# HG changeset patch # User Bram Moolenaar # Date 1667384332 -3600 # Node ID 013f8436b0d50b2ac19b554d700e7596ccce76ce # Parent 4d6024463de73415c0257d41411264b766a25d5c patch 9.0.0822: crash when dragging the statusline with a mapping Commit: https://github.com/vim/vim/commit/8ab9ca93eea32b318235384720200771863ecaee Author: Bram Moolenaar Date: Mon Oct 31 13:06:26 2022 +0000 patch 9.0.0822: crash when dragging the statusline with a mapping Problem: Crash when dragging the statusline with a mapping. Solution: Check for valid window pointer. (issue https://github.com/vim/vim/issues/11427) diff --git a/src/mouse.c b/src/mouse.c --- 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 --- 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 --- 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 "\" + endfunc + func DragExpr() + call test_setmouse(&lines - 2, 1) + return "\" + endfunc + nnoremap ClickExpr() + nnoremap DragExpr() + + " this was causing a crash in win_drag_status_line() + call feedkeys("\:tabnew\\", 'tx') +endfunc + " Test for mapping in Insert mode func Test_mouse_drag_insert_map() set mouse=a diff --git a/src/version.c b/src/version.c --- 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 --- 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)