3838 * in tl_scrollback are no longer used.
3939 *
4040 * TODO:
41- * - if the job in the terminal does not support the mouse, we can use the
42- * mouse in the Terminal window for copy/paste and scrolling.
4341 * - When using 'termguicolors' still use the 16 ANSI colors as-is. Helps for
4442 * - In the GUI use a terminal emulator for :!cmd. Make the height the same as
4543 * the window and position it higher up when it gets filled, so it looks like
@@ -900,6 +898,105 @@ term_send_mouse(VTerm *vterm, int button, int pressed)
900898 return TRUE;
901899}
902900
901+ static int enter_mouse_col = -1 ;
902+ static int enter_mouse_row = -1 ;
903+
904+ /*
905+ * Handle a mouse click, drag or release.
906+ * Return TRUE when a mouse event is sent to the terminal.
907+ */
908+ static int
909+ term_mouse_click (VTerm * vterm , int key )
910+ {
911+ #if defined(FEAT_CLIPBOARD )
912+ /* For modeless selection mouse drag and release events are ignored, unless
913+ * they are preceded with a mouse down event */
914+ static int ignore_drag_release = TRUE;
915+ VTermMouseState mouse_state ;
916+
917+ vterm_state_get_mousestate (vterm_obtain_state (vterm ), & mouse_state );
918+ if (mouse_state .flags == 0 )
919+ {
920+ /* Terminal is not using the mouse, use modeless selection. */
921+ switch (key )
922+ {
923+ case K_LEFTDRAG :
924+ case K_LEFTRELEASE :
925+ case K_RIGHTDRAG :
926+ case K_RIGHTRELEASE :
927+ /* Ignore drag and release events when the button-down wasn't
928+ * seen before. */
929+ if (ignore_drag_release )
930+ {
931+ int save_mouse_col , save_mouse_row ;
932+
933+ if (enter_mouse_col < 0 )
934+ break ;
935+
936+ /* mouse click in the window gave us focus, handle that
937+ * click now */
938+ save_mouse_col = mouse_col ;
939+ save_mouse_row = mouse_row ;
940+ mouse_col = enter_mouse_col ;
941+ mouse_row = enter_mouse_row ;
942+ clip_modeless (MOUSE_LEFT , TRUE, FALSE);
943+ mouse_col = save_mouse_col ;
944+ mouse_row = save_mouse_row ;
945+ }
946+ /* FALLTHROUGH */
947+ case K_LEFTMOUSE :
948+ case K_RIGHTMOUSE :
949+ if (key == K_LEFTRELEASE || key == K_RIGHTRELEASE )
950+ ignore_drag_release = TRUE;
951+ else
952+ ignore_drag_release = FALSE;
953+ /* Should we call mouse_has() here? */
954+ if (clip_star .available )
955+ {
956+ int button , is_click , is_drag ;
957+
958+ button = get_mouse_button (KEY2TERMCAP1 (key ),
959+ & is_click , & is_drag );
960+ if (mouse_model_popup () && button == MOUSE_LEFT
961+ && (mod_mask & MOD_MASK_SHIFT ))
962+ {
963+ /* Translate shift-left to right button. */
964+ button = MOUSE_RIGHT ;
965+ mod_mask &= ~MOD_MASK_SHIFT ;
966+ }
967+ clip_modeless (button , is_click , is_drag );
968+ }
969+ break ;
970+
971+ case K_MIDDLEMOUSE :
972+ if (clip_star .available )
973+ insert_reg ('*' , TRUE);
974+ break ;
975+ }
976+ enter_mouse_col = -1 ;
977+ return FALSE;
978+ }
979+ #endif
980+ enter_mouse_col = -1 ;
981+
982+ switch (key )
983+ {
984+ case K_LEFTMOUSE :
985+ case K_LEFTMOUSE_NM : term_send_mouse (vterm , 1 , 1 ); break ;
986+ case K_LEFTDRAG : term_send_mouse (vterm , 1 , 1 ); break ;
987+ case K_LEFTRELEASE :
988+ case K_LEFTRELEASE_NM : term_send_mouse (vterm , 1 , 0 ); break ;
989+ case K_MOUSEMOVE : term_send_mouse (vterm , 0 , 0 ); break ;
990+ case K_MIDDLEMOUSE : term_send_mouse (vterm , 2 , 1 ); break ;
991+ case K_MIDDLEDRAG : term_send_mouse (vterm , 2 , 1 ); break ;
992+ case K_MIDDLERELEASE : term_send_mouse (vterm , 2 , 0 ); break ;
993+ case K_RIGHTMOUSE : term_send_mouse (vterm , 3 , 1 ); break ;
994+ case K_RIGHTDRAG : term_send_mouse (vterm , 3 , 1 ); break ;
995+ case K_RIGHTRELEASE : term_send_mouse (vterm , 3 , 0 ); break ;
996+ }
997+ return TRUE;
998+ }
999+
9031000/*
9041001 * Convert typed key "c" into bytes to send to the job.
9051002 * Return the number of bytes in "buf".
@@ -995,17 +1092,21 @@ term_convert_key(term_T *term, int c, char *buf)
9951092 case K_MOUSERIGHT : /* TODO */ return 0 ;
9961093
9971094 case K_LEFTMOUSE :
998- case K_LEFTMOUSE_NM : other = term_send_mouse ( vterm , 1 , 1 ); break ;
999- case K_LEFTDRAG : other = term_send_mouse ( vterm , 1 , 1 ); break ;
1095+ case K_LEFTMOUSE_NM :
1096+ case K_LEFTDRAG :
10001097 case K_LEFTRELEASE :
1001- case K_LEFTRELEASE_NM : other = term_send_mouse (vterm , 1 , 0 ); break ;
1002- case K_MOUSEMOVE : other = term_send_mouse (vterm , 0 , 0 ); break ;
1003- case K_MIDDLEMOUSE : other = term_send_mouse (vterm , 2 , 1 ); break ;
1004- case K_MIDDLEDRAG : other = term_send_mouse (vterm , 2 , 1 ); break ;
1005- case K_MIDDLERELEASE : other = term_send_mouse (vterm , 2 , 0 ); break ;
1006- case K_RIGHTMOUSE : other = term_send_mouse (vterm , 3 , 1 ); break ;
1007- case K_RIGHTDRAG : other = term_send_mouse (vterm , 3 , 1 ); break ;
1008- case K_RIGHTRELEASE : other = term_send_mouse (vterm , 3 , 0 ); break ;
1098+ case K_LEFTRELEASE_NM :
1099+ case K_MOUSEMOVE :
1100+ case K_MIDDLEMOUSE :
1101+ case K_MIDDLEDRAG :
1102+ case K_MIDDLERELEASE :
1103+ case K_RIGHTMOUSE :
1104+ case K_RIGHTDRAG :
1105+ case K_RIGHTRELEASE : if (!term_mouse_click (vterm , c ))
1106+ return 0 ;
1107+ other = TRUE;
1108+ break ;
1109+
10091110 case K_X1MOUSE : /* TODO */ return 0 ;
10101111 case K_X1DRAG : /* TODO */ return 0 ;
10111112 case K_X1RELEASE : /* TODO */ return 0 ;
@@ -1473,6 +1574,8 @@ term_vgetc()
14731574 return c ;
14741575}
14751576
1577+ static int mouse_was_outside = FALSE;
1578+
14761579/*
14771580 * Send keys to terminal.
14781581 * Return FAIL when the key needs to be handled in Normal mode.
@@ -1483,7 +1586,6 @@ send_keys_to_term(term_T *term, int c, int typed)
14831586{
14841587 char msg [KEY_BUF_LEN ];
14851588 size_t len ;
1486- static int mouse_was_outside = FALSE;
14871589 int dragging_outside = FALSE;
14881590
14891591 /* Catch keys that need to be handled as in Normal mode. */
@@ -1731,6 +1833,29 @@ prepare_restore_cursor_props(void)
17311833 may_output_cursor_props ();
17321834}
17331835
1836+ /*
1837+ * Called when entering a window with the mouse. If this is a terminal window
1838+ * we may want to change state.
1839+ */
1840+ void
1841+ term_win_entered ()
1842+ {
1843+ term_T * term = curbuf -> b_term ;
1844+
1845+ if (term != NULL )
1846+ {
1847+ if (term_use_loop ())
1848+ {
1849+ reset_VIsual_and_resel ();
1850+ if (State & INSERT )
1851+ stop_insert_mode = TRUE;
1852+ }
1853+ mouse_was_outside = FALSE;
1854+ enter_mouse_col = mouse_col ;
1855+ enter_mouse_row = mouse_row ;
1856+ }
1857+ }
1858+
17341859/*
17351860 * Returns TRUE if the current window contains a terminal and we are sending
17361861 * keys to the job.
0 commit comments