0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

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 #11427)
This commit is contained in:
Bram Moolenaar
2022-10-31 13:06:26 +00:00
parent 86e6717ace
commit 8ab9ca93ee
5 changed files with 44 additions and 10 deletions

View File

@@ -179,6 +179,18 @@ get_fpos_of_mouse(pos_T *mpos)
} }
#endif #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. * 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.
@@ -224,7 +236,6 @@ do_mouse(
int fixindent) // PUT_FIXINDENT if fixing indent necessary int fixindent) // PUT_FIXINDENT if fixing indent necessary
{ {
static int do_always = FALSE; // ignore 'mouse' setting next time 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 which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
int is_click = FALSE; // If FALSE it's a drag or release event 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. // 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 mouse_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;
@@ -360,7 +371,7 @@ do_mouse(
if (count > 1) if (count > 1)
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;
} }
@@ -641,7 +652,7 @@ do_mouse(
} }
# ifdef FEAT_MENU # ifdef FEAT_MENU
show_popupmenu(); show_popupmenu();
got_click = FALSE; // ignore release events mouse_got_click = FALSE; // ignore release events
# endif # endif
return (jump_flags & CURSOR_MOVED) != 0; return (jump_flags & CURSOR_MOVED) != 0;
#else #else
@@ -698,7 +709,7 @@ do_mouse(
// next mouse click. // 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 = MCHAR; oap->motion_type = MCHAR;
} }
@@ -897,7 +908,7 @@ do_mouse(
do_cmdline_cmd((char_u *)".cc"); do_cmdline_cmd((char_u *)".cc");
else // location list window else // location list window
do_cmdline_cmd((char_u *)".ll"); do_cmdline_cmd((char_u *)".ll");
got_click = FALSE; // ignore drag&release now mouse_got_click = FALSE; // ignore drag&release now
} }
#endif #endif
@@ -909,7 +920,7 @@ do_mouse(
if (State & MODE_INSERT) if (State & MODE_INSERT)
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
} }
// Shift-Mouse click searches for the next occurrence of the word under // Shift-Mouse click searches for the next occurrence of the word under

View File

@@ -1,6 +1,7 @@
/* mouse.c */ /* mouse.c */
void mouse_set_vert_scroll_step(long step); void mouse_set_vert_scroll_step(long step);
void mouse_set_hor_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); int do_mouse(oparg_T *oap, int c, int dir, long count, int fixindent);
void ins_mouse(int c); void ins_mouse(int c);
void ins_mousescroll(int dir); void ins_mousescroll(int dir);

View File

@@ -1648,6 +1648,24 @@ func Test_mouse_drag_mapped_start_select()
set mouse& set mouse&
endfunc 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 " Test for mapping <LeftDrag> in Insert mode
func Test_mouse_drag_insert_map() func Test_mouse_drag_insert_map()
set mouse=a set mouse=a

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
822,
/**/ /**/
821, 821,
/**/ /**/

View File

@@ -4249,6 +4249,7 @@ leave_tabpage(
{ {
tabpage_T *tp = curtab; tabpage_T *tp = curtab;
reset_mouse_got_click();
#ifdef FEAT_JOB_CHANNEL #ifdef FEAT_JOB_CHANNEL
leaving_window(curwin); leaving_window(curwin);
#endif #endif
@@ -4464,6 +4465,7 @@ goto_tabpage_tp(
// Don't repeat a message in another tab page. // Don't repeat a message in another tab page.
set_keep_msg(NULL, 0); set_keep_msg(NULL, 0);
reset_mouse_got_click();
skip_win_fix_scroll = TRUE; skip_win_fix_scroll = TRUE;
if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer, if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer,
trigger_leave_autocmds) == OK) trigger_leave_autocmds) == OK)