summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-10-31 13:06:26 +0000
committerBram Moolenaar <Bram@vim.org>2022-10-31 13:06:26 +0000
commit8ab9ca93eea32b318235384720200771863ecaee (patch)
tree78a5fbdd321361af03a3e2c819e7bd9aeec73159 /src
parent86e6717ace4f5e00eaeb84b59e3fc92bca548155 (diff)
downloadvim-git-8ab9ca93eea32b318235384720200771863ecaee.tar.gz
patch 9.0.0822: crash when dragging the statusline with a mappingv9.0.0822
Problem: Crash when dragging the statusline with a mapping. Solution: Check for valid window pointer. (issue #11427)
Diffstat (limited to 'src')
-rw-r--r--src/mouse.c31
-rw-r--r--src/proto/mouse.pro1
-rw-r--r--src/testdir/test_mapping.vim18
-rw-r--r--src/version.c2
-rw-r--r--src/window.c2
5 files changed, 44 insertions, 10 deletions
diff --git a/src/mouse.c b/src/mouse.c
index 9efd148ec..40c2159c0 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -179,6 +179,18 @@ get_fpos_of_mouse(pos_T *mpos)
}
#endif
+static int mouse_got_click = FALSE; // got a click some time back
+
+/*
+ * Reset the flag that a mouse click was seen. To be called when switching tab
+ * page.
+ */
+ 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.
@@ -224,7 +236,6 @@ do_mouse(
int fixindent) // PUT_FIXINDENT if fixing indent necessary
{
static int do_always = FALSE; // ignore 'mouse' setting next time
- static int got_click = FALSE; // got a click some time back
int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
int is_click = FALSE; // If FALSE it's a drag or release event
@@ -336,14 +347,14 @@ do_mouse(
// 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
+ if (!is_drag) // release, reset mouse_got_click
{
- got_click = FALSE;
+ mouse_got_click = FALSE;
if (in_tab_line)
{
in_tab_line = FALSE;
@@ -360,7 +371,7 @@ do_mouse(
if (count > 1)
stuffnumReadbuff(count);
stuffcharReadbuff(Ctrl_T);
- got_click = FALSE; // ignore drag&release now
+ mouse_got_click = FALSE; // ignore drag&release now
return FALSE;
}
@@ -641,7 +652,7 @@ do_mouse(
}
# ifdef FEAT_MENU
show_popupmenu();
- got_click = FALSE; // ignore release events
+ mouse_got_click = FALSE; // ignore release events
# endif
return (jump_flags & CURSOR_MOVED) != 0;
#else
@@ -698,7 +709,7 @@ do_mouse(
// next mouse click.
if (!is_drag && oap != NULL && oap->op_type != OP_NOP)
{
- got_click = FALSE;
+ mouse_got_click = FALSE;
oap->motion_type = MCHAR;
}
@@ -897,7 +908,7 @@ do_mouse(
do_cmdline_cmd((char_u *)".cc");
else // location list window
do_cmdline_cmd((char_u *)".ll");
- got_click = FALSE; // ignore drag&release now
+ mouse_got_click = FALSE; // ignore drag&release now
}
#endif
@@ -909,7 +920,7 @@ do_mouse(
if (State & MODE_INSERT)
stuffcharReadbuff(Ctrl_O);
stuffcharReadbuff(Ctrl_RSB);
- got_click = FALSE; // ignore drag&release now
+ mouse_got_click = FALSE; // ignore drag&release now
}
// Shift-Mouse click searches for the next occurrence of the word under
diff --git a/src/proto/mouse.pro b/src/proto/mouse.pro
index 249e7f240..65976892a 100644
--- a/src/proto/mouse.pro
+++ b/src/proto/mouse.pro
@@ -1,6 +1,7 @@
/* mouse.c */
void mouse_set_vert_scroll_step(long step);
void mouse_set_hor_scroll_step(long step);
+void reset_mouse_got_click(void);
int do_mouse(oparg_T *oap, int c, int dir, long count, int fixindent);
void ins_mouse(int c);
void ins_mousescroll(int dir);
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index 4212731f3..ce9f932d6 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -1648,6 +1648,24 @@ func Test_mouse_drag_mapped_start_select()
set mouse&
endfunc
+func Test_mouse_drag_statusline()
+ set laststatus=2
+ set mouse=a
+ func ClickExpr()
+ call test_setmouse(&lines - 1, 1)
+ return "\<LeftMouse>"
+ endfunc
+ func DragExpr()
+ call test_setmouse(&lines - 2, 1)
+ return "\<LeftDrag>"
+ endfunc
+ nnoremap <expr> <F2> ClickExpr()
+ nnoremap <expr> <F3> DragExpr()
+
+ " this was causing a crash in win_drag_status_line()
+ call feedkeys("\<F2>:tabnew\<CR>\<F3>", 'tx')
+endfunc
+
" Test for mapping <LeftDrag> in Insert mode
func Test_mouse_drag_insert_map()
set mouse=a
diff --git a/src/version.c b/src/version.c
index 58f17e1e2..387c81104 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 822,
+/**/
821,
/**/
820,
diff --git a/src/window.c b/src/window.c
index 8d61defab..5a9440a4c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4249,6 +4249,7 @@ leave_tabpage(
{
tabpage_T *tp = curtab;
+ reset_mouse_got_click();
#ifdef FEAT_JOB_CHANNEL
leaving_window(curwin);
#endif
@@ -4464,6 +4465,7 @@ goto_tabpage_tp(
// Don't repeat a message in another tab page.
set_keep_msg(NULL, 0);
+ reset_mouse_got_click();
skip_win_fix_scroll = TRUE;
if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer,
trigger_leave_autocmds) == OK)