]> granicus.if.org Git - vim/commitdiff
patch 9.0.0822: crash when dragging the statusline with a mapping v9.0.0822
authorBram Moolenaar <Bram@vim.org>
Mon, 31 Oct 2022 13:06:26 +0000 (13:06 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 31 Oct 2022 13:06:26 +0000 (13:06 +0000)
Problem:    Crash when dragging the statusline with a mapping.
Solution:   Check for valid window pointer. (issue #11427)

src/mouse.c
src/proto/mouse.pro
src/testdir/test_mapping.vim
src/version.c
src/window.c

index 9efd148ecb536b7ddf74c6acf8fa5e55732c592f..40c2159c04ff5780e60a414b9886ead9e6369f73 100644 (file)
@@ -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
index 249e7f2408cd1b86f69bd0b09c1e777306d1a933..65976892a52fd201087485302d1cf7a8482a94b4 100644 (file)
@@ -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);
index 4212731f35460b1f4ffde79b01dc4a8fca1bc1d7..ce9f932d65a0a96e0d170b0d9196347d2ed52083 100644 (file)
@@ -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
index 58f17e1e2625f5318a62e1d6c6918b6a4c9b8f90..387c81104931d25eaae9159380c6b3232fe4a57c 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    822,
 /**/
     821,
 /**/
index 8d61defab2b48d421ef577e1577bb9cb4d41eacc..5a9440a4c1f59c4124bc88ba0196e928be972efe 100644 (file)
@@ -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)