mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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 vim/vim#11427)
8ab9ca93ee
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
parent
41f308feab
commit
a600e73007
@ -227,6 +227,15 @@ 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. 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.
|
||||
///
|
||||
@ -268,8 +277,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, long 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
|
||||
@ -328,13 +335,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, long 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;
|
||||
if (!is_drag) { // release, reset mouse_got_click
|
||||
mouse_got_click = false;
|
||||
if (in_tab_line) {
|
||||
in_tab_line = false;
|
||||
return false;
|
||||
@ -351,7 +358,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long 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;
|
||||
}
|
||||
|
||||
@ -574,7 +581,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long 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
|
||||
@ -613,7 +620,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -815,7 +822,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
} 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
|
||||
@ -824,7 +831,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
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
|
||||
|
@ -1050,6 +1050,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 Ntest_setmouse(&lines - 1, 1)
|
||||
return "\<LeftMouse>"
|
||||
endfunc
|
||||
func DragExpr()
|
||||
call Ntest_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
|
||||
|
@ -4195,6 +4195,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds)
|
||||
{
|
||||
tabpage_T *tp = curtab;
|
||||
|
||||
reset_mouse_got_click();
|
||||
leaving_window(curwin);
|
||||
reset_VIsual_and_resel(); // stop Visual mode
|
||||
if (trigger_leave_autocmds) {
|
||||
@ -4392,6 +4393,7 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le
|
||||
// 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user