summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-02-02 15:25:16 +0100
committerBram Moolenaar <Bram@vim.org>2020-02-02 15:25:16 +0100
commitd98c0b63abd7b0e61a383669474abe96044615af (patch)
tree81409a98d3a6d7712373b57242a40171ab64d8de
parent3180fe6c6dc0728d21c6318b957022b029c234f0 (diff)
downloadvim-git-d98c0b63abd7b0e61a383669474abe96044615af.tar.gz
patch 8.2.0196: blocking commands for a finished job in a popup windowv8.2.0196
Problem: Blocking commands for a finished job in a popup window. Solution: Do not block commands if the job has finished. Adjust test.
-rw-r--r--src/popupwin.c7
-rw-r--r--src/proto/terminal.pro1
-rw-r--r--src/terminal.c23
-rw-r--r--src/testdir/test_popupwin.vim14
-rw-r--r--src/version.c2
-rw-r--r--src/window.c11
6 files changed, 55 insertions, 3 deletions
diff --git a/src/popupwin.c b/src/popupwin.c
index d4f6026f9..714f457fe 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2863,10 +2863,15 @@ error_if_popup_window(int also_with_term UNUSED)
}
# 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 8d37db8e3..e8760d14a 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -19,6 +19,7 @@ cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
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 7f92ab1a4..cbf8fe079 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3260,6 +3260,29 @@ term_after_channel_closed(term_T *term)
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 75247b533..f8f501afa 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2396,10 +2396,20 @@ endfunc
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 65d961d02..8c5cb53dc 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
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 aeafb267c..23037fe75 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2441,6 +2441,11 @@ win_close(win_T *win, int free_buf)
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 @@ only_one_window(void)
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;