Patch 8.2.1966
Problem: Popup becomes current window after closing a terminal window.
Solution: When restoring the window after executing autocommands, check that
the window ID is still the same. (Naruhiko Nishino,
closes #7272)
Files: src/autocmd.c, src/window.c, src/proto/window.pro, src/structs.h,
src/testdir/test_popupwin.vim
*** ../vim-8.2.1965/src/autocmd.c 2020-10-21 12:19:50.080854732 +0200
--- src/autocmd.c 2020-11-07 16:45:35.814707017 +0100
***************
*** 1433,1441 ****
// window. Expect a few side effects...
win = curwin;
! aco->save_curwin = curwin;
aco->save_curbuf = curbuf;
! aco->save_prevwin = prevwin;
if (win != NULL)
{
// There is a window for "buf" in the current tab page, make it the
--- 1433,1441 ----
// window. Expect a few side effects...
win = curwin;
! aco->save_curwin_id = curwin->w_id;
aco->save_curbuf = curbuf;
! aco->save_prevwin_id = prevwin == NULL ? 0 : prevwin->w_id;
if (win != NULL)
{
// There is a window for "buf" in the current tab page, make it the
***************
*** 1481,1487 ****
curwin = aucmd_win;
}
curbuf = buf;
! aco->new_curwin = curwin;
set_bufref(&aco->new_curbuf, curbuf);
}
--- 1481,1487 ----
curwin = aucmd_win;
}
curbuf = buf;
! aco->new_curwin_id = curwin->w_id;
set_bufref(&aco->new_curbuf, curbuf);
}
***************
*** 1493,1499 ****
aucmd_restbuf(
aco_save_T *aco) // structure holding saved values
{
! int dummy;
if (aco->use_aucmd_win)
{
--- 1493,1500 ----
aucmd_restbuf(
aco_save_T *aco) // structure holding saved values
{
! int dummy;
! win_T *save_curwin;
if (aco->use_aucmd_win)
{
***************
*** 1533,1540 ****
(void)win_comp_pos(); // recompute window positions
unblock_autocmds();
! if (win_valid(aco->save_curwin))
! curwin = aco->save_curwin;
else
// Hmm, original window disappeared. Just use the first one.
curwin = firstwin;
--- 1534,1542 ----
(void)win_comp_pos(); // recompute window positions
unblock_autocmds();
! save_curwin = win_find_by_id(aco->save_curwin_id);
! if (save_curwin != NULL)
! curwin = save_curwin;
else
// Hmm, original window disappeared. Just use the first one.
curwin = firstwin;
***************
*** 1543,1551 ****
// May need to restore insert mode for a prompt buffer.
entering_window(curwin);
#endif
!
! if (win_valid(aco->save_prevwin))
! prevwin = aco->save_prevwin;
#ifdef FEAT_EVAL
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
--- 1545,1551 ----
// May need to restore insert mode for a prompt buffer.
entering_window(curwin);
#endif
! prevwin = win_find_by_id(aco->save_prevwin_id);
#ifdef FEAT_EVAL
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
***************
*** 1571,1583 ****
}
else
{
! // restore curwin
! if (win_valid(aco->save_curwin))
{
// Restore the buffer which was previously edited by curwin, if
// it was changed, we are still the same window and the buffer is
// valid.
! if (curwin == aco->new_curwin
&& curbuf != aco->new_curbuf.br_buf
&& bufref_valid(&aco->new_curbuf)
&& aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL)
--- 1571,1585 ----
}
else
{
! // Restore curwin. Use the window ID, a window may have been closed
! // and the memory re-used for another one.
! save_curwin = win_find_by_id(aco->save_curwin_id);
! if (save_curwin != NULL)
{
// Restore the buffer which was previously edited by curwin, if
// it was changed, we are still the same window and the buffer is
// valid.
! if (curwin->w_id == aco->new_curwin_id
&& curbuf != aco->new_curbuf.br_buf
&& bufref_valid(&aco->new_curbuf)
&& aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL)
***************
*** 1592,1601 ****
++curbuf->b_nwindows;
}
! curwin = aco->save_curwin;
curbuf = curwin->w_buffer;
! if (win_valid(aco->save_prevwin))
! prevwin = aco->save_prevwin;
// In case the autocommand moves the cursor to a position that
// does not exist in curbuf.
check_cursor();
--- 1594,1602 ----
++curbuf->b_nwindows;
}
! curwin = save_curwin;
curbuf = curwin->w_buffer;
! prevwin = win_find_by_id(aco->save_prevwin_id);
// In case the autocommand moves the cursor to a position that
// does not exist in curbuf.
check_cursor();
*** ../vim-8.2.1965/src/window.c 2020-11-04 11:03:08.372891857 +0100
--- src/window.c 2020-11-07 16:55:40.479270357 +0100
***************
*** 1461,1466 ****
--- 1461,1481 ----
}
/*
+ * Find window "id" in the current tab page.
+ * Return NULL if not found.
+ */
+ win_T *
+ win_find_by_id(int id)
+ {
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ if (wp->w_id == id)
+ return wp;
+ return NULL;
+ }
+
+ /*
* Check if "win" is a pointer to an existing window in any tab page.
*/
int
*** ../vim-8.2.1965/src/proto/window.pro 2020-10-01 22:37:36.403376674
+0200
--- src/proto/window.pro 2020-11-07 16:36:12.130134001 +0100
***************
*** 5,10 ****
--- 5,11 ----
int win_split_ins(int size, int flags, win_T *new_wp, int dir);
int win_valid_popup(win_T *win);
int win_valid(win_T *win);
+ win_T *win_find_by_id(int id);
int win_valid_any_tab(win_T *win);
int win_count(void);
int make_windows(int count, int vertical);
*** ../vim-8.2.1965/src/structs.h 2020-11-05 20:50:45.331984998 +0100
--- src/structs.h 2020-11-07 16:36:45.270027261 +0100
***************
*** 3889,3901 ****
*/
typedef struct
{
! buf_T *save_curbuf; // saved curbuf
! int use_aucmd_win; // using aucmd_win
! win_T *save_curwin; // saved curwin
! win_T *new_curwin; // new curwin
! win_T *save_prevwin; // saved prevwin
! bufref_T new_curbuf; // new curbuf
! char_u *globaldir; // saved value of globaldir
} aco_save_T;
/*
--- 3889,3901 ----
*/
typedef struct
{
! buf_T *save_curbuf; // saved curbuf
! int use_aucmd_win; // using aucmd_win
! int save_curwin_id; // ID of saved curwin
! int new_curwin_id; // ID of new curwin
! int save_prevwin_id; // ID of saved prevwin
! bufref_T new_curbuf; // new curbuf
! char_u *globaldir; // saved value of globaldir
} aco_save_T;
/*
*** ../vim-8.2.1965/src/testdir/test_popupwin.vim 2020-11-06
17:58:31.727138982 +0100
--- src/testdir/test_popupwin.vim 2020-11-07 16:55:29.183325154 +0100
***************
*** 3737,3741 ****
--- 3737,3762 ----
bwipe
endfunc
+ func Test_popupwin_exiting_terminal()
+ CheckFeature terminal
+
+ " Tests that when creating a popup right after closing a terminal window
does
+ " not make the popup the current window.
+ let winid = win_getid()
+ try
+ augroup Test_popupwin_exiting_terminal
+ autocmd!
+ autocmd WinEnter * :call popup_create('test', {})
+ augroup END
+ let bnr = term_start(&shell, #{term_finish: 'close'})
+ call term_sendkeys(bnr, "exit\r\n")
+ call WaitForAssert({-> assert_equal(winid, win_getid())})
+ finally
+ call popup_clear(1)
+ augroup Test_popupwin_exiting_terminal
+ autocmd!
+ augroup END
+ endtry
+ endfunc
" vim: shiftwidth=2 sts=2
*** ../vim-8.2.1965/src/version.c 2020-11-07 13:09:09.209143607 +0100
--- src/version.c 2020-11-07 16:58:47.566392798 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 1966,
/**/
--
hundred-and-one symptoms of being an internet addict:
213. Your kids start referring to you as "that guy in front of the monitor."
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202011071559.0A7FxP2a726381%40masaka.moolenaar.net.