aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2023-11-24 02:15:50 +0100
committerGitHub <noreply@github.com>2023-11-24 09:15:50 +0800
commita8a93e517f9eb988ee86170d9a77382637dd24a3 (patch)
treead1a6c6b0529ea2ab336eea6e44a86fc8c138476
parent73c7a0d58e6358d35fe2d5a11b3e807a625a0001 (diff)
downloadrneovim-a8a93e517f9eb988ee86170d9a77382637dd24a3.tar.gz
rneovim-a8a93e517f9eb988ee86170d9a77382637dd24a3.tar.bz2
rneovim-a8a93e517f9eb988ee86170d9a77382637dd24a3.zip
fix(mouse): avoid dragging after click label popupmenu callback (#26187)
-rw-r--r--src/nvim/mouse.c26
-rw-r--r--src/nvim/popupmenu.c2
-rw-r--r--test/functional/ui/statuscolumn_spec.lua27
3 files changed, 45 insertions, 10 deletions
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 8a48a8928e..368153cad6 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -241,6 +241,14 @@ static int get_fpos_of_mouse(pos_T *mpos)
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.
/// 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.
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
bool is_click; // If false it's a drag or release 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.
if (is_click) {
- got_click = true;
+ mouse_got_click = true;
} else {
- if (!got_click) { // didn't get click, ignore
+ if (!mouse_got_click) { // didn't get click, ignore
return false;
}
if (!is_drag) { // release, reset got_click
- got_click = false;
+ mouse_got_click = false;
if (in_tab_line) {
in_tab_line = false;
return false;
@@ -364,7 +370,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
stuffnumReadbuff(count);
}
stuffcharReadbuff(Ctrl_T);
- got_click = false; // ignore drag&release now
+ mouse_got_click = false; // ignore drag&release now
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
}
show_popupmenu();
- got_click = false; // ignore release events
+ mouse_got_click = false; // ignore release events
return (jump_flags & CURSOR_MOVED) != 0;
}
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 (!is_drag && oap != NULL && oap->op_type != OP_NOP) {
- got_click = false;
+ mouse_got_click = false;
oap->motion_type = kMTCharWise;
}
@@ -838,7 +844,7 @@ popupexit:
} else { // location list window
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)
|| (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
@@ -847,7 +853,7 @@ popupexit:
stuffcharReadbuff(Ctrl_O);
}
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)) {
// Shift-Mouse click searches for the next occurrence of the word under
// the mouse pointer
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index a6eb32ecb1..e04d0c7acd 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -26,6 +26,7 @@
#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/message.h"
+#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/option.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
pum_select_mouse_pos();
if (pum_selected >= 0) {
+ reset_mouse_got_click();
pum_execute_menu(menu, mode);
break;
}
diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua
index dd11fa7c15..73039701cd 100644
--- a/test/functional/ui/statuscolumn_spec.lua
+++ b/test/functional/ui/statuscolumn_spec.lua
@@ -589,6 +589,33 @@ describe('statuscolumn', function()
meths.input_mouse('left', 'press', '', 0, 7, 7)
eq('0 1 l 11', eval("g:testvar"))
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