diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-08-03 20:44:48 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-08-03 20:44:48 +0200 |
commit | e9c21aed6233185e7fbe1b462a0571c0e460a5a9 (patch) | |
tree | b18f24877ce95b0c81a2a0d2fe0af691d9cd6c9f | |
parent | b4a6721a288438c96fbeb051b09ef90735ac70d6 (diff) | |
download | vim-git-e9c21aed6233185e7fbe1b462a0571c0e460a5a9.tar.gz |
patch 8.0.0854: no redraw after terminal was closedv8.0.0854
Problem: No redraw after terminal was closed.
Solution: Set typebuf_was_filled. (Yasuhiro Matsumoto, closes #1925, closes
#1924) Add function to check for messages even when input is
available.
-rw-r--r-- | src/os_mswin.c | 12 | ||||
-rw-r--r-- | src/os_unix.c | 38 | ||||
-rw-r--r-- | src/os_win32.c | 32 | ||||
-rw-r--r-- | src/proto/os_unix.pro | 1 | ||||
-rw-r--r-- | src/proto/os_win32.pro | 1 | ||||
-rw-r--r-- | src/terminal.c | 18 | ||||
-rw-r--r-- | src/version.c | 2 |
7 files changed, 76 insertions, 28 deletions
diff --git a/src/os_mswin.c b/src/os_mswin.c index 696847e50..dd4201222 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -809,6 +809,18 @@ mch_char_avail(void) /* never used */ return TRUE; } + +# if defined(FEAT_TERMINAL) || defined(PROTO) +/* + * Check for any pending input or messages. + */ + int +mch_check_messages(void) +{ + /* TODO: check for messages */ + return TRUE; +} +# endif #endif diff --git a/src/os_unix.c b/src/os_unix.c index c90ab34f6..ade8d8818 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -175,8 +175,8 @@ typedef int waitstatus; #endif static pid_t wait4pid(pid_t, waitstatus *); -static int WaitForChar(long msec, int *interrupted); -static int WaitForCharOrMouse(long msec, int *interrupted); +static int WaitForChar(long msec, int *interrupted, int ignore_input); +static int WaitForCharOrMouse(long msec, int *interrupted, int ignore_input); #if defined(__BEOS__) || defined(VMS) int RealWaitForChar(int, long, int *, int *interrupted); #else @@ -481,7 +481,7 @@ mch_inchar( * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. */ - if (WaitForChar(wait_time, &interrupted)) + if (WaitForChar(wait_time, &interrupted, FALSE)) { /* If input was put directly in typeahead buffer bail out here. */ if (typebuf_changed(tb_change_cnt)) @@ -536,9 +536,20 @@ handle_resize(void) int mch_char_avail(void) { - return WaitForChar(0L, NULL); + return WaitForChar(0L, NULL, FALSE); } +#if defined(FEAT_TERMINAL) || defined(PROTO) +/* + * Check for any pending input or messages. + */ + int +mch_check_messages(void) +{ + return WaitForChar(0L, NULL, TRUE); +} +#endif + #if defined(HAVE_TOTAL_MEM) || defined(PROTO) # ifdef HAVE_SYS_RESOURCE_H # include <sys/resource.h> @@ -718,7 +729,7 @@ mch_delay(long msec, int ignoreinput) in_mch_delay = FALSE; } else - WaitForChar(msec, NULL); + WaitForChar(msec, NULL, FALSE); } #if defined(HAVE_STACK_LIMIT) \ @@ -5616,13 +5627,15 @@ mch_breakcheck(int force) * from inbuf[]. * "msec" == -1 will block forever. * Invokes timer callbacks when needed. + * When "ignore_input" is TRUE even check for pending input when input is + * already available. * "interrupted" (if not NULL) is set to TRUE when no character is available * but something else needs to be done. * Returns TRUE when a character is available. * When a GUI is being used, this will never get called -- webb */ static int -WaitForChar(long msec, int *interrupted) +WaitForChar(long msec, int *interrupted, int ignore_input) { #ifdef FEAT_TIMERS long due_time; @@ -5631,7 +5644,7 @@ WaitForChar(long msec, int *interrupted) /* When waiting very briefly don't trigger timers. */ if (msec >= 0 && msec < 10L) - return WaitForCharOrMouse(msec, NULL); + return WaitForCharOrMouse(msec, NULL, ignore_input); while (msec < 0 || remaining > 0) { @@ -5645,7 +5658,7 @@ WaitForChar(long msec, int *interrupted) } if (due_time <= 0 || (msec > 0 && due_time > remaining)) due_time = remaining; - if (WaitForCharOrMouse(due_time, interrupted)) + if (WaitForCharOrMouse(due_time, interrupted, ignore_input)) return TRUE; if (interrupted != NULL && *interrupted) /* Nothing available, but need to return so that side effects get @@ -5656,7 +5669,7 @@ WaitForChar(long msec, int *interrupted) } return FALSE; #else - return WaitForCharOrMouse(msec, interrupted); + return WaitForCharOrMouse(msec, interrupted, ignore_input); #endif } @@ -5664,12 +5677,13 @@ WaitForChar(long msec, int *interrupted) * Wait "msec" msec until a character is available from the mouse or keyboard * or from inbuf[]. * "msec" == -1 will block forever. + * for "ignore_input" see WaitForCharOr(). * "interrupted" (if not NULL) is set to TRUE when no character is available * but something else needs to be done. * When a GUI is being used, this will never get called -- webb */ static int -WaitForCharOrMouse(long msec, int *interrupted) +WaitForCharOrMouse(long msec, int *interrupted, int ignore_input) { #ifdef FEAT_MOUSE_GPM int gpm_process_wanted; @@ -5679,7 +5693,7 @@ WaitForCharOrMouse(long msec, int *interrupted) #endif int avail; - if (input_available()) /* something in inbuf[] */ + if (!ignore_input && input_available()) /* something in inbuf[] */ return 1; #if defined(FEAT_MOUSE_DEC) @@ -5722,7 +5736,7 @@ WaitForCharOrMouse(long msec, int *interrupted) # endif if (!avail) { - if (input_available()) + if (!ignore_input && input_available()) return 1; # ifdef FEAT_XCLIPBOARD if (rest == 0 || !do_xterm_trace()) diff --git a/src/os_win32.c b/src/os_win32.c index d3cab0223..f75040c11 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -1400,10 +1400,11 @@ handle_focus_event(INPUT_RECORD ir) /* * Wait until console input from keyboard or mouse is available, * or the time is up. + * When "ignore_input" is TRUE even wait when input is available. * Return TRUE if something is available FALSE if not. */ static int -WaitForChar(long msec) +WaitForChar(long msec, int ignore_input) { DWORD dwNow = 0, dwEndTime = 0; INPUT_RECORD ir; @@ -1440,7 +1441,7 @@ WaitForChar(long msec) || g_nMouseClick != -1 #endif #ifdef FEAT_CLIENTSERVER - || input_available() + || (!ignore_input && input_available()) #endif ) return TRUE; @@ -1583,8 +1584,19 @@ WaitForChar(long msec) int mch_char_avail(void) { - return WaitForChar(0L); + return WaitForChar(0L, FALSE); } + +# if defined(FEAT_TERMINAL) || defined(PROTO) +/* + * Check for any pending input or messages. + */ + int +mch_check_messages(void) +{ + return WaitForChar(0L, TRUE); +} +# endif #endif /* @@ -1614,7 +1626,7 @@ tgetch(int *pmodifiers, WCHAR *pch2) DWORD cRecords = 0; #ifdef FEAT_CLIENTSERVER - (void)WaitForChar(-1L); + (void)WaitForChar(-1L, FALSE); if (input_available()) return 0; # ifdef FEAT_MOUSE @@ -1681,7 +1693,7 @@ mch_inchar( if (time >= 0) { - if (!WaitForChar(time)) /* no character available */ + if (!WaitForChar(time, FALSE)) /* no character available */ return 0; } else /* time == -1, wait forever */ @@ -1693,7 +1705,7 @@ mch_inchar( * write the autoscript file to disk. Or cause the CursorHold event * to be triggered. */ - if (!WaitForChar(p_ut)) + if (!WaitForChar(p_ut, FALSE)) { #ifdef FEAT_AUTOCMD if (trigger_cursorhold() && maxlen >= 3) @@ -1723,7 +1735,7 @@ mch_inchar( /* Keep looping until there is something in the typeahead buffer and more * to get and still room in the buffer (up to two bytes for a char and * three bytes for a modifier). */ - while ((typeaheadlen == 0 || WaitForChar(0L)) + while ((typeaheadlen == 0 || WaitForChar(0L, FALSE)) && typeaheadlen + 5 <= TYPEAHEADLEN) { if (typebuf_changed(tb_change_cnt)) @@ -5721,7 +5733,7 @@ cursor_visible(BOOL fVisible) /* - * write `cbToWrite' bytes in `pchBuf' to the screen + * Write "cbToWrite" bytes in `pchBuf' to the screen. * Returns the number of bytes actually written (at least one). */ static DWORD @@ -5828,7 +5840,7 @@ mch_write( if (p_wd) { - WaitForChar(p_wd); + WaitForChar(p_wd, FALSE); if (prefix != 0) prefix = 1; } @@ -6120,7 +6132,7 @@ mch_delay( # endif Sleep((int)msec); else - WaitForChar(msec); + WaitForChar(msec, FALSE); #endif } diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index 46230dc15..8e955aa7b 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -3,6 +3,7 @@ int mch_chdir(char *path); void mch_write(char_u *s, int len); int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt); int mch_char_avail(void); +int mch_check_messages(void); long_u mch_total_mem(int special); void mch_delay(long msec, int ignoreinput); int mch_stackcheck(char *p); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro index 4e0629867..bc16a193a 100644 --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -8,6 +8,7 @@ void PlatformId(void); void mch_setmouse(int on); void mch_update_cursor(void); int mch_char_avail(void); +int mch_check_messages(void); int mch_inchar(char_u *buf, int maxlen, long time, int tb_change_cnt); void mch_init(void); void mch_exit(int r); diff --git a/src/terminal.c b/src/terminal.c index b06feffc2..9c165337b 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1305,6 +1305,7 @@ term_channel_closed(channel_T *ch) /* Need to break out of vgetc(). */ ins_char_typebuf(K_IGNORE); + typebuf_was_filled = TRUE; term = curbuf->b_term; if (term != NULL) @@ -2140,31 +2141,36 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED) ch_log(NULL, "term_wait(): invalid argument"); return; } + if (buf->b_term->tl_job == NULL) + { + ch_log(NULL, "term_wait(): no job to wait for"); + return; + } /* Get the job status, this will detect a job that finished. */ - if (buf->b_term->tl_job == NULL - || STRCMP(job_status(buf->b_term->tl_job), "dead") == 0) + if (STRCMP(job_status(buf->b_term->tl_job), "dead") == 0) { /* The job is dead, keep reading channel I/O until the channel is * closed. */ + ch_log(NULL, "term_wait(): waiting for channel to close"); while (buf->b_term != NULL && !buf->b_term->tl_channel_closed) { - mch_char_avail(); + mch_check_messages(); parse_queued_messages(); ui_delay(10L, FALSE); } - mch_char_avail(); + mch_check_messages(); parse_queued_messages(); } else { - mch_char_avail(); + mch_check_messages(); parse_queued_messages(); /* Wait for 10 msec for any channel I/O. */ /* TODO: use delay from optional argument */ ui_delay(10L, TRUE); - mch_char_avail(); + mch_check_messages(); /* Flushing messages on channels is hopefully sufficient. * TODO: is there a better way? */ diff --git a/src/version.c b/src/version.c index 617042584..25750b5c6 100644 --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 854, +/**/ 853, /**/ 852, |