vim-patch:8.0.0948: crash if timer closes window while dragging status line

Problem:    Crash if timer closes window while dragging status line.
Solution:   Check if the window still exists. (Yasuhiro Matsumoto, closes
            vim/vim#1979)
989a70c590
This commit is contained in:
Jan Edmund Lazo 2018-08-05 17:22:14 -04:00
parent fe6e4b3244
commit e7e2115de5
4 changed files with 25 additions and 3 deletions

View File

@ -7884,7 +7884,11 @@ static void ins_mousescroll(int dir)
col = mouse_col; col = mouse_col;
/* find the window at the pointer coordinates */ /* find the window at the pointer coordinates */
curwin = mouse_find_win(&row, &col); win_T *const wp = mouse_find_win(&row, &col);
if (wp == NULL) {
return;
}
curwin = wp;
curbuf = curwin->w_buffer; curbuf = curwin->w_buffer;
} }
if (curwin == old_curwin) if (curwin == old_curwin)

View File

@ -9493,6 +9493,9 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/* Find the window at the mouse coordinates and compute the /* Find the window at the mouse coordinates and compute the
* text position. */ * text position. */
win = mouse_find_win(&row, &col); win = mouse_find_win(&row, &col);
if (win == NULL) {
return;
}
(void)mouse_comp_pos(win, &row, &col, &lnum); (void)mouse_comp_pos(win, &row, &col, &lnum);
for (wp = firstwin; wp != win; wp = wp->w_next) for (wp = firstwin; wp != win; wp = wp->w_next)
++winnr; ++winnr;

View File

@ -125,6 +125,9 @@ retnomove:
// find the window where the row is in // find the window where the row is in
wp = mouse_find_win(&row, &col); wp = mouse_find_win(&row, &col);
if (wp == NULL) {
return IN_UNKNOWN;
}
dragwin = NULL; dragwin = NULL;
// winpos and height may change in win_enter()! // winpos and height may change in win_enter()!
if (row >= wp->w_height) { // In (or below) status line if (row >= wp->w_height) { // In (or below) status line
@ -427,6 +430,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
// Find the window at screen position "*rowp" and "*colp". The positions are // Find the window at screen position "*rowp" and "*colp". The positions are
// updated to become relative to the top-left of the window. // updated to become relative to the top-left of the window.
// Returns NULL when something is wrong.
win_T *mouse_find_win(int *rowp, int *colp) win_T *mouse_find_win(int *rowp, int *colp)
{ {
frame_T *fp; frame_T *fp;
@ -450,7 +454,14 @@ win_T *mouse_find_win(int *rowp, int *colp)
} }
} }
} }
return fp->fr_win; // When using a timer that closes a window the window might not actually
// exist.
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp == fp->fr_win) {
return wp;
}
}
return NULL;
} }
/* /*

View File

@ -3995,7 +3995,11 @@ static void nv_mousescroll(cmdarg_T *cap)
col = mouse_col; col = mouse_col;
/* find the window at the pointer coordinates */ /* find the window at the pointer coordinates */
curwin = mouse_find_win(&row, &col); win_T *const wp = mouse_find_win(&row, &col);
if (wp == NULL) {
return;
}
curwin = wp;
curbuf = curwin->w_buffer; curbuf = curwin->w_buffer;
} }