patch 8.2.0196: blocking commands for a finished job in a popup window

Problem:    Blocking commands for a finished job in a popup window.
Solution:   Do not block commands if the job has finished.  Adjust test.
diff --git a/src/popupwin.c b/src/popupwin.c
index d4f6026..714f457 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2863,10 +2863,15 @@
 }
 
 # if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Return TRUE if the current window is running a terminal in a popup window.
+ * Return FALSE when the job has ended.
+ */
     int
 error_if_term_popup_window()
 {
-    if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL)
+    if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL
+					   && term_job_running(curbuf->b_term))
     {
 	emsg(_("E899: Not allowed for a terminal in a popup window"));
 	return TRUE;
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index 8d37db8..e8760d1 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -19,6 +19,7 @@
 int term_use_loop(void);
 void term_win_entered(void);
 int terminal_loop(int blocking);
+int may_close_term_popup(void);
 void term_channel_closed(channel_T *ch);
 void term_check_channel_closed_recently(void);
 int term_do_update_window(win_T *wp);
diff --git a/src/terminal.c b/src/terminal.c
index 7f92ab1..cbf8fe0 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3260,6 +3260,29 @@
     return FALSE;
 }
 
+#if defined(FEAT_PROP_POPUP) || defined(PROTO)
+/*
+ * If the current window is a terminal in a popup window and the job has
+ * finished, close the popup window and to back to the previous window.
+ * Otherwise return FAIL.
+ */
+    int
+may_close_term_popup(void)
+{
+    if (popup_is_popup(curwin) && curbuf->b_term != NULL
+					  && !term_job_running(curbuf->b_term))
+    {
+	win_T *pwin = curwin;
+
+	if (win_valid(prevwin))
+	    win_enter(prevwin, FALSE);
+	popup_close_with_retval(pwin, 0);
+	return OK;
+    }
+    return FAIL;
+}
+#endif
+
 /*
  * Called when a channel has been closed.
  * If this was a channel for a terminal window then finish it up.
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 75247b5..f8f501a 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2396,10 +2396,20 @@
 
 func Test_popupwin_terminal_buffer()
   CheckFeature terminal
+  CheckUnix
 
+  let origwin = win_getid()
   let ptybuf = term_start(&shell, #{hidden: 1})
-  call assert_fails('let winnr = popup_create(ptybuf, #{})', 'E278:')
-  exe 'bwipe! ' .. ptybuf
+  let winnr = popup_create(ptybuf, #{minwidth: 40, minheight: 10})
+  " Wait for shell to start
+  sleep 200m
+  " Cannot quit while job is running
+  call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
+  call feedkeys("exit\<CR>", 'xt')
+  " Wait for shell to exit
+  sleep 100m
+  call feedkeys(":quit\<CR>", 'xt')
+  call assert_equal(origwin, win_getid())
 endfunc
 
 func Test_popupwin_with_buffer_and_filter()
diff --git a/src/version.c b/src/version.c
index 65d961d..8c5cb53 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    196,
+/**/
     195,
 /**/
     194,
diff --git a/src/window.c b/src/window.c
index aeafb26..23037fe 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2441,6 +2441,11 @@
     int		had_diffmode = win->w_p_diff;
 #endif
 
+#if defined(FEAT_TERMINAL) && defined(FEAT_PROP_POPUP)
+    // Can close a popup window with a terminal if the job has finished.
+    if (may_close_term_popup() == OK)
+	return OK;
+#endif
     if (ERROR_IF_ANY_POPUP_WINDOW)
 	return FAIL;
 
@@ -6439,6 +6444,12 @@
     int		count = 0;
     win_T	*wp;
 
+#if defined(FEAT_PROP_POPUP)
+    // If the current window is a popup then there always is another window.
+    if (popup_is_popup(curwin))
+	return FALSE;
+#endif
+
     // If there is another tab page there always is another window.
     if (first_tabpage->tp_next != NULL)
 	return FALSE;