mirror of
https://github.com/vim/vim.git
synced 2025-08-27 20:13:38 -04:00
patch 8.2.4674: cannot force getting MouseMove events
Problem: Cannot force getting MouseMove events. Solution: Add the 'mousemoveevent' option with implementaiton for the GUI. (Ernie Rael, closes #10044)
This commit is contained in:
parent
8ef6997e2d
commit
c4cb544cd5
@ -261,6 +261,7 @@ Other options that are relevant:
|
|||||||
'mousefocus' window focus follows mouse pointer |gui-mouse-focus|
|
'mousefocus' window focus follows mouse pointer |gui-mouse-focus|
|
||||||
'mousemodel' what mouse button does which action
|
'mousemodel' what mouse button does which action
|
||||||
'mousehide' hide mouse pointer while typing text
|
'mousehide' hide mouse pointer while typing text
|
||||||
|
'mousemoveevent' enable mouse move events so that <MouseMove> can be mapped
|
||||||
'selectmode' whether to start Select mode or Visual mode
|
'selectmode' whether to start Select mode or Visual mode
|
||||||
|
|
||||||
A quick way to set these is with the ":behave" command.
|
A quick way to set these is with the ":behave" command.
|
||||||
@ -406,6 +407,9 @@ These mappings make selection work the way it probably should in a Motif
|
|||||||
application, with shift-left mouse allowing for extending the visual area
|
application, with shift-left mouse allowing for extending the visual area
|
||||||
rather than the right mouse button.
|
rather than the right mouse button.
|
||||||
|
|
||||||
|
<MouseMove> may be mapped, but 'mousemoveevent' must be enabled to use the
|
||||||
|
mapping.
|
||||||
|
|
||||||
Mouse mapping with modifiers does not work for modeless selection.
|
Mouse mapping with modifiers does not work for modeless selection.
|
||||||
|
|
||||||
|
|
||||||
|
@ -5517,6 +5517,18 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
|
|
||||||
The 'mousemodel' option is set by the |:behave| command.
|
The 'mousemodel' option is set by the |:behave| command.
|
||||||
|
|
||||||
|
*'mousemoveevent'* *'mousemev'*
|
||||||
|
'mousemoveevent' 'mousemev' boolean (default off)
|
||||||
|
global
|
||||||
|
{only works in the GUI}
|
||||||
|
When on, mouse move events are delivered to the input queue and are
|
||||||
|
available for mapping. The default, off, avoids the mouse movement
|
||||||
|
overhead except when needed. See |gui-mouse-mapping|.
|
||||||
|
Warning: Setting this option can make pending mappings to be aborted
|
||||||
|
when the mouse is moved.
|
||||||
|
Currently only works in the GUI, may be made to work in a terminal
|
||||||
|
later.
|
||||||
|
|
||||||
*'mouseshape'* *'mouses'* *E547*
|
*'mouseshape'* *'mouses'* *E547*
|
||||||
'mouseshape' 'mouses' string (default "i-r:beam,s:updown,sd:udsizing,
|
'mouseshape' 'mouses' string (default "i-r:beam,s:updown,sd:udsizing,
|
||||||
vs:leftright,vd:lrsizing,m:no,
|
vs:leftright,vd:lrsizing,m:no,
|
||||||
|
@ -131,8 +131,8 @@ test_gui_event({event}, {args})
|
|||||||
forward: set to 1 for forward search.
|
forward: set to 1 for forward search.
|
||||||
|
|
||||||
"mouse":
|
"mouse":
|
||||||
Inject a mouse button click event. The supported items in
|
Inject either a mouse button click, or a mouse move, event.
|
||||||
{args} are:
|
The supported items in {args} are:
|
||||||
button: mouse button. The supported values are:
|
button: mouse button. The supported values are:
|
||||||
0 right mouse button
|
0 right mouse button
|
||||||
1 middle mouse button
|
1 middle mouse button
|
||||||
@ -151,6 +151,28 @@ test_gui_event({event}, {args})
|
|||||||
4 shift is pressed
|
4 shift is pressed
|
||||||
8 alt is pressed
|
8 alt is pressed
|
||||||
16 ctrl is pressed
|
16 ctrl is pressed
|
||||||
|
move: Optional; if used and TRUE then a mouse move
|
||||||
|
event can be generated.
|
||||||
|
Only {args} row: and col: are used and
|
||||||
|
required; they are interpreted as pixels.
|
||||||
|
Only results in an event when 'mousemoveevent'
|
||||||
|
is set or a popup uses mouse move events.
|
||||||
|
|
||||||
|
"scrollbar":
|
||||||
|
Set or drag the left, right or horizontal scrollbar. Only
|
||||||
|
works when the scrollbar actually exists. The supported
|
||||||
|
items in {args} are:
|
||||||
|
which: scrollbar. The supported values are:
|
||||||
|
left Left scrollbar of the current window
|
||||||
|
right Right scrollbar of the current window
|
||||||
|
hor Horizontal scrollbar
|
||||||
|
value: amount to scroll. For the vertical scrollbars
|
||||||
|
the value can be 1 to the line-count of the
|
||||||
|
buffer. For the horizontal scrollbar the
|
||||||
|
value can be between 1 and the maximum line
|
||||||
|
length, assuming 'wrap' is not set.
|
||||||
|
dragging: 1 to drag the scrollbar and 0 to click in the
|
||||||
|
scrollbar.
|
||||||
|
|
||||||
"scrollbar":
|
"scrollbar":
|
||||||
Set or drag the left, right or horizontal scrollbar. Only
|
Set or drag the left, right or horizontal scrollbar. Only
|
||||||
|
25
src/gui.c
25
src/gui.c
@ -3142,13 +3142,26 @@ button_set:
|
|||||||
if (hold_gui_events)
|
if (hold_gui_events)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
row = gui_xy2colrow(x, y, &col);
|
||||||
|
// Don't report a mouse move unless moved to a
|
||||||
|
// different character position.
|
||||||
|
if (button == MOUSE_MOVE)
|
||||||
|
{
|
||||||
|
if (row == prev_row && col == prev_col)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev_row = row >= 0 ? row : 0;
|
||||||
|
prev_col = col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string[3] = CSI;
|
string[3] = CSI;
|
||||||
string[4] = KS_EXTRA;
|
string[4] = KS_EXTRA;
|
||||||
string[5] = (int)button_char;
|
string[5] = (int)button_char;
|
||||||
|
|
||||||
// Pass the pointer coordinates of the scroll event so that we
|
// Pass the pointer coordinates of the scroll event so that we
|
||||||
// know which window to scroll.
|
// know which window to scroll.
|
||||||
row = gui_xy2colrow(x, y, &col);
|
|
||||||
string[6] = (char_u)(col / 128 + ' ' + 1);
|
string[6] = (char_u)(col / 128 + ' ' + 1);
|
||||||
string[7] = (char_u)(col % 128 + ' ' + 1);
|
string[7] = (char_u)(col % 128 + ' ' + 1);
|
||||||
string[8] = (char_u)(row / 128 + ' ' + 1);
|
string[8] = (char_u)(row / 128 + ' ' + 1);
|
||||||
@ -4967,12 +4980,14 @@ gui_mouse_moved(int x, int y)
|
|||||||
// apply 'mousefocus' and pointer shape
|
// apply 'mousefocus' and pointer shape
|
||||||
gui_mouse_focus(x, y);
|
gui_mouse_focus(x, y);
|
||||||
|
|
||||||
|
if (p_mousemev
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
if (popup_uses_mouse_move)
|
|| popup_uses_mouse_move
|
||||||
// Generate a mouse-moved event, so that the popup can perhaps be
|
|
||||||
// closed, just like in the terminal.
|
|
||||||
gui_send_mouse_event(MOUSE_MOVE, x, y, FALSE, 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
)
|
||||||
|
// Generate a mouse-moved event. For a <MouseMove> mapping. Or so the
|
||||||
|
// popup can perhaps be closed, just like in the terminal.
|
||||||
|
gui_send_mouse_event(MOUSE_MOVE, x, y, FALSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -760,6 +760,9 @@ EXTERN int p_mousef; // 'mousefocus'
|
|||||||
EXTERN int p_mh; // 'mousehide'
|
EXTERN int p_mh; // 'mousehide'
|
||||||
#endif
|
#endif
|
||||||
EXTERN char_u *p_mousem; // 'mousemodel'
|
EXTERN char_u *p_mousem; // 'mousemodel'
|
||||||
|
#ifdef FEAT_GUI
|
||||||
|
EXTERN int p_mousemev; // 'mousemoveevent'
|
||||||
|
#endif
|
||||||
EXTERN long p_mouset; // 'mousetime'
|
EXTERN long p_mouset; // 'mousetime'
|
||||||
EXTERN int p_more; // 'more'
|
EXTERN int p_more; // 'more'
|
||||||
#ifdef FEAT_MZSCHEME
|
#ifdef FEAT_MZSCHEME
|
||||||
|
@ -1746,6 +1746,13 @@ static struct vimoption options[] =
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
(char_u *)0L} SCTX_INIT},
|
(char_u *)0L} SCTX_INIT},
|
||||||
|
{"mousemoveevent", "mousemev", P_BOOL|P_VI_DEF,
|
||||||
|
#ifdef FEAT_GUI
|
||||||
|
(char_u *)&p_mousemev, PV_NONE,
|
||||||
|
#else
|
||||||
|
(char_u *)NULL, PV_NONE,
|
||||||
|
#endif
|
||||||
|
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
|
||||||
{"mouseshape", "mouses", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
|
{"mouseshape", "mouses", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
|
||||||
#ifdef FEAT_MOUSESHAPE
|
#ifdef FEAT_MOUSESHAPE
|
||||||
(char_u *)&p_mouseshape, PV_NONE,
|
(char_u *)&p_mouseshape, PV_NONE,
|
||||||
|
@ -1194,6 +1194,78 @@ func Test_gui_mouse_event()
|
|||||||
set mousemodel&
|
set mousemodel&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_gui_mouse_move_event()
|
||||||
|
let args = #{move: 1, button: 0, multiclick: 0, modifiers: 0}
|
||||||
|
|
||||||
|
" default, do not generate mouse move events
|
||||||
|
set mousemev&
|
||||||
|
call assert_false(&mousemev)
|
||||||
|
|
||||||
|
let n_event = 0
|
||||||
|
nnoremap <special> <MouseMove> :let n_event += 1<CR>
|
||||||
|
|
||||||
|
" start at mouse pos (1,1), clear counter
|
||||||
|
call extend(args, #{row: 1, col:1})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
let n_event = 0
|
||||||
|
|
||||||
|
call extend(args, #{row: 30, col:300})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call extend(args, #{row: 100, col:300})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
" no events since mousemev off
|
||||||
|
call assert_equal(0, n_event)
|
||||||
|
|
||||||
|
" turn on mouse events and try the same thing
|
||||||
|
set mousemev
|
||||||
|
call extend(args, #{row: 1, col:1})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
let n_event = 0
|
||||||
|
|
||||||
|
call extend(args, #{row: 30, col:300})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call extend(args, #{row: 100, col:300})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call assert_equal(2, n_event)
|
||||||
|
|
||||||
|
" wiggle the mouse around, shouldn't get events
|
||||||
|
call extend(args, #{row: 1, col:1})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
let n_event = 0
|
||||||
|
|
||||||
|
call extend(args, #{row: 1, col:2})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call extend(args, #{row: 2, col:2})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call extend(args, #{row: 2, col:1})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call extend(args, #{row: 1, col:1})
|
||||||
|
call test_gui_event('mouse', args)
|
||||||
|
call feedkeys('', 'Lx!')
|
||||||
|
|
||||||
|
call assert_equal(0, n_event)
|
||||||
|
|
||||||
|
unmap <MouseMove>
|
||||||
|
set mousemev&
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Test for 'guitablabel' and 'guitabtooltip' options
|
" Test for 'guitablabel' and 'guitabtooltip' options
|
||||||
func TestGuiTabLabel()
|
func TestGuiTabLabel()
|
||||||
call add(g:TabLabels, v:lnum + 100)
|
call add(g:TabLabels, v:lnum + 100)
|
||||||
|
@ -1368,22 +1368,35 @@ test_gui_mouse_event(dict_T *args)
|
|||||||
int col;
|
int col;
|
||||||
int repeated_click;
|
int repeated_click;
|
||||||
int_u mods;
|
int_u mods;
|
||||||
|
int move;
|
||||||
|
|
||||||
if (dict_find(args, (char_u *)"button", -1) == NULL
|
if (dict_find(args, (char_u *)"row", -1) == NULL
|
||||||
|| dict_find(args, (char_u *)"row", -1) == NULL
|
|| dict_find(args, (char_u *)"col", -1) == NULL)
|
||||||
|| dict_find(args, (char_u *)"col", -1) == NULL
|
return FALSE;
|
||||||
|| dict_find(args, (char_u *)"multiclick", -1) == NULL
|
|
||||||
|| dict_find(args, (char_u *)"modifiers", -1) == NULL)
|
// Note: "move" is optional, requires fewer arguments
|
||||||
|
move = (int)dict_get_bool(args, (char_u *)"move", FALSE);
|
||||||
|
|
||||||
|
if (!move && (dict_find(args, (char_u *)"button", -1) == NULL
|
||||||
|
|| dict_find(args, (char_u *)"multiclick", -1) == NULL
|
||||||
|
|| dict_find(args, (char_u *)"modifiers", -1) == NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
button = (int)dict_get_number(args, (char_u *)"button");
|
|
||||||
row = (int)dict_get_number(args, (char_u *)"row");
|
row = (int)dict_get_number(args, (char_u *)"row");
|
||||||
col = (int)dict_get_number(args, (char_u *)"col");
|
col = (int)dict_get_number(args, (char_u *)"col");
|
||||||
|
|
||||||
|
if (move)
|
||||||
|
gui_mouse_moved(col, row);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button = (int)dict_get_number(args, (char_u *)"button");
|
||||||
repeated_click = (int)dict_get_number(args, (char_u *)"multiclick");
|
repeated_click = (int)dict_get_number(args, (char_u *)"multiclick");
|
||||||
mods = (int)dict_get_number(args, (char_u *)"modifiers");
|
mods = (int)dict_get_number(args, (char_u *)"modifiers");
|
||||||
|
|
||||||
gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
|
gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
|
||||||
repeated_click, mods);
|
repeated_click, mods);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4674,
|
||||||
/**/
|
/**/
|
||||||
4673,
|
4673,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user