mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(mouse): avoid dragging after click label popupmenu callback (#26187)
This commit is contained in:
@ -241,6 +241,14 @@ static int get_fpos_of_mouse(pos_T *mpos)
|
|||||||
return IN_BUFFER;
|
return IN_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mouse_got_click = false; ///< got a click some time back
|
||||||
|
|
||||||
|
/// Reset the flag that a mouse click was seen.
|
||||||
|
void reset_mouse_got_click(void)
|
||||||
|
{
|
||||||
|
mouse_got_click = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Do the appropriate action for the current mouse click in the current mode.
|
/// Do the appropriate action for the current mouse click in the current mode.
|
||||||
/// Not used for Command-line mode.
|
/// Not used for Command-line mode.
|
||||||
///
|
///
|
||||||
@ -282,8 +290,6 @@ static int get_fpos_of_mouse(pos_T *mpos)
|
|||||||
/// @return true if start_arrow() should be called for edit mode.
|
/// @return true if start_arrow() should be called for edit mode.
|
||||||
bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
||||||
{
|
{
|
||||||
static bool got_click = false; // got a click some time back
|
|
||||||
|
|
||||||
int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
|
int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
|
||||||
bool is_click; // If false it's a drag or release event
|
bool is_click; // If false it's a drag or release event
|
||||||
bool is_drag; // If true it's a drag event
|
bool is_drag; // If true it's a drag event
|
||||||
@ -341,13 +347,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
|||||||
|
|
||||||
// Ignore drag and release events if we didn't get a click.
|
// Ignore drag and release events if we didn't get a click.
|
||||||
if (is_click) {
|
if (is_click) {
|
||||||
got_click = true;
|
mouse_got_click = true;
|
||||||
} else {
|
} else {
|
||||||
if (!got_click) { // didn't get click, ignore
|
if (!mouse_got_click) { // didn't get click, ignore
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!is_drag) { // release, reset got_click
|
if (!is_drag) { // release, reset got_click
|
||||||
got_click = false;
|
mouse_got_click = false;
|
||||||
if (in_tab_line) {
|
if (in_tab_line) {
|
||||||
in_tab_line = false;
|
in_tab_line = false;
|
||||||
return false;
|
return false;
|
||||||
@ -364,7 +370,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
|||||||
stuffnumReadbuff(count);
|
stuffnumReadbuff(count);
|
||||||
}
|
}
|
||||||
stuffcharReadbuff(Ctrl_T);
|
stuffcharReadbuff(Ctrl_T);
|
||||||
got_click = false; // ignore drag&release now
|
mouse_got_click = false; // ignore drag&release now
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +594,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
|||||||
ui_flush(); // Update before showing popup menu
|
ui_flush(); // Update before showing popup menu
|
||||||
}
|
}
|
||||||
show_popupmenu();
|
show_popupmenu();
|
||||||
got_click = false; // ignore release events
|
mouse_got_click = false; // ignore release events
|
||||||
return (jump_flags & CURSOR_MOVED) != 0;
|
return (jump_flags & CURSOR_MOVED) != 0;
|
||||||
}
|
}
|
||||||
if (which_button == MOUSE_LEFT
|
if (which_button == MOUSE_LEFT
|
||||||
@ -628,7 +634,7 @@ popupexit:
|
|||||||
|
|
||||||
// If an operator is pending, ignore all drags and releases until the next mouse click.
|
// If an operator is pending, ignore all drags and releases until the next mouse click.
|
||||||
if (!is_drag && oap != NULL && oap->op_type != OP_NOP) {
|
if (!is_drag && oap != NULL && oap->op_type != OP_NOP) {
|
||||||
got_click = false;
|
mouse_got_click = false;
|
||||||
oap->motion_type = kMTCharWise;
|
oap->motion_type = kMTCharWise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -838,7 +844,7 @@ popupexit:
|
|||||||
} else { // location list window
|
} else { // location list window
|
||||||
do_cmdline_cmd(".ll");
|
do_cmdline_cmd(".ll");
|
||||||
}
|
}
|
||||||
got_click = false; // ignore drag&release now
|
mouse_got_click = false; // ignore drag&release now
|
||||||
} else if ((mod_mask & MOD_MASK_CTRL)
|
} else if ((mod_mask & MOD_MASK_CTRL)
|
||||||
|| (curbuf->b_help && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) {
|
|| (curbuf->b_help && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) {
|
||||||
// Ctrl-Mouse click (or double click in a help window) jumps to the tag
|
// Ctrl-Mouse click (or double click in a help window) jumps to the tag
|
||||||
@ -847,7 +853,7 @@ popupexit:
|
|||||||
stuffcharReadbuff(Ctrl_O);
|
stuffcharReadbuff(Ctrl_O);
|
||||||
}
|
}
|
||||||
stuffcharReadbuff(Ctrl_RSB);
|
stuffcharReadbuff(Ctrl_RSB);
|
||||||
got_click = false; // ignore drag&release now
|
mouse_got_click = false; // ignore drag&release now
|
||||||
} else if ((mod_mask & MOD_MASK_SHIFT)) {
|
} else if ((mod_mask & MOD_MASK_SHIFT)) {
|
||||||
// Shift-Mouse click searches for the next occurrence of the word under
|
// Shift-Mouse click searches for the next occurrence of the word under
|
||||||
// the mouse pointer
|
// the mouse pointer
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/menu.h"
|
#include "nvim/menu.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
|
#include "nvim/mouse.h"
|
||||||
#include "nvim/move.h"
|
#include "nvim/move.h"
|
||||||
#include "nvim/option.h"
|
#include "nvim/option.h"
|
||||||
#include "nvim/option_vars.h"
|
#include "nvim/option_vars.h"
|
||||||
@ -1147,6 +1148,7 @@ void pum_show_popupmenu(vimmenu_T *menu)
|
|||||||
// right mouse release: select clicked item, close if any
|
// right mouse release: select clicked item, close if any
|
||||||
pum_select_mouse_pos();
|
pum_select_mouse_pos();
|
||||||
if (pum_selected >= 0) {
|
if (pum_selected >= 0) {
|
||||||
|
reset_mouse_got_click();
|
||||||
pum_execute_menu(menu, mode);
|
pum_execute_menu(menu, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -589,6 +589,33 @@ describe('statuscolumn', function()
|
|||||||
meths.input_mouse('left', 'press', '', 0, 7, 7)
|
meths.input_mouse('left', 'press', '', 0, 7, 7)
|
||||||
eq('0 1 l 11', eval("g:testvar"))
|
eq('0 1 l 11', eval("g:testvar"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('selecting popupmenu does not drag mouse', function()
|
||||||
|
screen:try_resize(screen._width, 2)
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[0] = {foreground = Screen.colors.Brown},
|
||||||
|
[1] = {background = Screen.colors.Plum1},
|
||||||
|
})
|
||||||
|
meths.set_option_value('statuscolumn', '%0@MyClickFunc@%l%T', {})
|
||||||
|
exec([[
|
||||||
|
function! MyClickFunc(minwid, clicks, button, mods)
|
||||||
|
let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
|
||||||
|
menu PopupStc.Echo <cmd>echo g:testvar<CR>
|
||||||
|
popup PopupStc
|
||||||
|
endfunction
|
||||||
|
]])
|
||||||
|
meths.input_mouse('left', 'press', '', 0, 0, 0)
|
||||||
|
screen:expect([[
|
||||||
|
{0:8 }^aaaaa |
|
||||||
|
{1: Echo } |
|
||||||
|
]])
|
||||||
|
meths.input_mouse('left', 'press', '', 0, 1, 5)
|
||||||
|
meths.input_mouse('left', 'release', '', 0, 1, 5)
|
||||||
|
screen:expect([[
|
||||||
|
{0:8 }^aaaaa |
|
||||||
|
0 1 l 8 |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user