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.

Raspunde prin e-mail lui