patch 8.2.1966: popup becomes current window after closing a terminal window

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)
diff --git a/src/autocmd.c b/src/autocmd.c
index be35845c..a82659f 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -1433,9 +1433,9 @@
 	// window.  Expect a few side effects...
 	win = curwin;
 
-    aco->save_curwin = curwin;
+    aco->save_curwin_id = curwin->w_id;
     aco->save_curbuf = curbuf;
-    aco->save_prevwin = prevwin;
+    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,7 +1481,7 @@
 	curwin = aucmd_win;
     }
     curbuf = buf;
-    aco->new_curwin = curwin;
+    aco->new_curwin_id = curwin->w_id;
     set_bufref(&aco->new_curbuf, curbuf);
 }
 
@@ -1493,7 +1493,8 @@
 aucmd_restbuf(
     aco_save_T	*aco)		// structure holding saved values
 {
-    int dummy;
+    int	    dummy;
+    win_T   *save_curwin;
 
     if (aco->use_aucmd_win)
     {
@@ -1533,8 +1534,9 @@
 	(void)win_comp_pos();   // recompute window positions
 	unblock_autocmds();
 
-	if (win_valid(aco->save_curwin))
-	    curwin = aco->save_curwin;
+	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,9 +1545,7 @@
 	// May need to restore insert mode for a prompt buffer.
 	entering_window(curwin);
 #endif
-
-	if (win_valid(aco->save_prevwin))
-	    prevwin = aco->save_prevwin;
+	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,13 +1571,15 @@
     }
     else
     {
-	// restore curwin
-	if (win_valid(aco->save_curwin))
+	// 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 == aco->new_curwin
+	    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,10 +1594,9 @@
 		++curbuf->b_nwindows;
 	    }
 
-	    curwin = aco->save_curwin;
+	    curwin = save_curwin;
 	    curbuf = curwin->w_buffer;
-	    if (win_valid(aco->save_prevwin))
-		prevwin = aco->save_prevwin;
+	    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();
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 24ab0ec..c10b61d 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -5,6 +5,7 @@
 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);
diff --git a/src/structs.h b/src/structs.h
index 330bb53..90e7620 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3889,13 +3889,13 @@
  */
 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
+    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;
 
 /*
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 43dbeb5..fdfa305 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -3737,5 +3737,26 @@
   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
diff --git a/src/version.c b/src/version.c
index 786e05e..1fbae19 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1966,
+/**/
     1965,
 /**/
     1964,
diff --git a/src/window.c b/src/window.c
index 2cd0663..501ea84 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1461,6 +1461,21 @@
 }
 
 /*
+ * 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