Skip to content

Commit

Permalink
patch 8.0.0854: no redraw after terminal was closed
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
brammool committed Aug 3, 2017
1 parent b4a6721 commit e9c21ae
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 28 deletions.
12 changes: 12 additions & 0 deletions src/os_mswin.c
Expand Up @@ -809,6 +809,18 @@ mch_char_avail(void)
/* never used */ /* never used */
return TRUE; 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 #endif




Expand Down
38 changes: 26 additions & 12 deletions src/os_unix.c
Expand Up @@ -175,8 +175,8 @@ typedef int waitstatus;
#endif #endif
static pid_t wait4pid(pid_t, waitstatus *); static pid_t wait4pid(pid_t, waitstatus *);


static int WaitForChar(long msec, int *interrupted); static int WaitForChar(long msec, int *interrupted, int ignore_input);
static int WaitForCharOrMouse(long msec, int *interrupted); static int WaitForCharOrMouse(long msec, int *interrupted, int ignore_input);
#if defined(__BEOS__) || defined(VMS) #if defined(__BEOS__) || defined(VMS)
int RealWaitForChar(int, long, int *, int *interrupted); int RealWaitForChar(int, long, int *, int *interrupted);
#else #else
Expand Down Expand Up @@ -481,7 +481,7 @@ mch_inchar(
* We want to be interrupted by the winch signal * We want to be interrupted by the winch signal
* or by an event on the monitored file descriptors. * 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 input was put directly in typeahead buffer bail out here. */
if (typebuf_changed(tb_change_cnt)) if (typebuf_changed(tb_change_cnt))
Expand Down Expand Up @@ -536,9 +536,20 @@ handle_resize(void)
int int
mch_char_avail(void) 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) #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
# ifdef HAVE_SYS_RESOURCE_H # ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h> # include <sys/resource.h>
Expand Down Expand Up @@ -718,7 +729,7 @@ mch_delay(long msec, int ignoreinput)
in_mch_delay = FALSE; in_mch_delay = FALSE;
} }
else else
WaitForChar(msec, NULL); WaitForChar(msec, NULL, FALSE);
} }


#if defined(HAVE_STACK_LIMIT) \ #if defined(HAVE_STACK_LIMIT) \
Expand Down Expand Up @@ -5616,13 +5627,15 @@ mch_breakcheck(int force)
* from inbuf[]. * from inbuf[].
* "msec" == -1 will block forever. * "msec" == -1 will block forever.
* Invokes timer callbacks when needed. * 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 * "interrupted" (if not NULL) is set to TRUE when no character is available
* but something else needs to be done. * but something else needs to be done.
* Returns TRUE when a character is available. * Returns TRUE when a character is available.
* When a GUI is being used, this will never get called -- webb * When a GUI is being used, this will never get called -- webb
*/ */
static int static int
WaitForChar(long msec, int *interrupted) WaitForChar(long msec, int *interrupted, int ignore_input)
{ {
#ifdef FEAT_TIMERS #ifdef FEAT_TIMERS
long due_time; long due_time;
Expand All @@ -5631,7 +5644,7 @@ WaitForChar(long msec, int *interrupted)


/* When waiting very briefly don't trigger timers. */ /* When waiting very briefly don't trigger timers. */
if (msec >= 0 && msec < 10L) if (msec >= 0 && msec < 10L)
return WaitForCharOrMouse(msec, NULL); return WaitForCharOrMouse(msec, NULL, ignore_input);


while (msec < 0 || remaining > 0) while (msec < 0 || remaining > 0)
{ {
Expand All @@ -5645,7 +5658,7 @@ WaitForChar(long msec, int *interrupted)
} }
if (due_time <= 0 || (msec > 0 && due_time > remaining)) if (due_time <= 0 || (msec > 0 && due_time > remaining))
due_time = remaining; due_time = remaining;
if (WaitForCharOrMouse(due_time, interrupted)) if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
return TRUE; return TRUE;
if (interrupted != NULL && *interrupted) if (interrupted != NULL && *interrupted)
/* Nothing available, but need to return so that side effects get /* Nothing available, but need to return so that side effects get
Expand All @@ -5656,20 +5669,21 @@ WaitForChar(long msec, int *interrupted)
} }
return FALSE; return FALSE;
#else #else
return WaitForCharOrMouse(msec, interrupted); return WaitForCharOrMouse(msec, interrupted, ignore_input);
#endif #endif
} }


/* /*
* Wait "msec" msec until a character is available from the mouse or keyboard * Wait "msec" msec until a character is available from the mouse or keyboard
* or from inbuf[]. * or from inbuf[].
* "msec" == -1 will block forever. * "msec" == -1 will block forever.
* for "ignore_input" see WaitForCharOr().
* "interrupted" (if not NULL) is set to TRUE when no character is available * "interrupted" (if not NULL) is set to TRUE when no character is available
* but something else needs to be done. * but something else needs to be done.
* When a GUI is being used, this will never get called -- webb * When a GUI is being used, this will never get called -- webb
*/ */
static int static int
WaitForCharOrMouse(long msec, int *interrupted) WaitForCharOrMouse(long msec, int *interrupted, int ignore_input)
{ {
#ifdef FEAT_MOUSE_GPM #ifdef FEAT_MOUSE_GPM
int gpm_process_wanted; int gpm_process_wanted;
Expand All @@ -5679,7 +5693,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
#endif #endif
int avail; int avail;


if (input_available()) /* something in inbuf[] */ if (!ignore_input && input_available()) /* something in inbuf[] */
return 1; return 1;


#if defined(FEAT_MOUSE_DEC) #if defined(FEAT_MOUSE_DEC)
Expand Down Expand Up @@ -5722,7 +5736,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
# endif # endif
if (!avail) if (!avail)
{ {
if (input_available()) if (!ignore_input && input_available())
return 1; return 1;
# ifdef FEAT_XCLIPBOARD # ifdef FEAT_XCLIPBOARD
if (rest == 0 || !do_xterm_trace()) if (rest == 0 || !do_xterm_trace())
Expand Down
32 changes: 22 additions & 10 deletions src/os_win32.c
Expand Up @@ -1400,10 +1400,11 @@ handle_focus_event(INPUT_RECORD ir)
/* /*
* Wait until console input from keyboard or mouse is available, * Wait until console input from keyboard or mouse is available,
* or the time is up. * 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. * Return TRUE if something is available FALSE if not.
*/ */
static int static int
WaitForChar(long msec) WaitForChar(long msec, int ignore_input)
{ {
DWORD dwNow = 0, dwEndTime = 0; DWORD dwNow = 0, dwEndTime = 0;
INPUT_RECORD ir; INPUT_RECORD ir;
Expand Down Expand Up @@ -1440,7 +1441,7 @@ WaitForChar(long msec)
|| g_nMouseClick != -1 || g_nMouseClick != -1
#endif #endif
#ifdef FEAT_CLIENTSERVER #ifdef FEAT_CLIENTSERVER
|| input_available() || (!ignore_input && input_available())
#endif #endif
) )
return TRUE; return TRUE;
Expand Down Expand Up @@ -1583,8 +1584,19 @@ WaitForChar(long msec)
int int
mch_char_avail(void) 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 #endif


/* /*
Expand Down Expand Up @@ -1614,7 +1626,7 @@ tgetch(int *pmodifiers, WCHAR *pch2)
DWORD cRecords = 0; DWORD cRecords = 0;


#ifdef FEAT_CLIENTSERVER #ifdef FEAT_CLIENTSERVER
(void)WaitForChar(-1L); (void)WaitForChar(-1L, FALSE);
if (input_available()) if (input_available())
return 0; return 0;
# ifdef FEAT_MOUSE # ifdef FEAT_MOUSE
Expand Down Expand Up @@ -1681,7 +1693,7 @@ mch_inchar(


if (time >= 0) if (time >= 0)
{ {
if (!WaitForChar(time)) /* no character available */ if (!WaitForChar(time, FALSE)) /* no character available */
return 0; return 0;
} }
else /* time == -1, wait forever */ else /* time == -1, wait forever */
Expand All @@ -1693,7 +1705,7 @@ mch_inchar(
* write the autoscript file to disk. Or cause the CursorHold event * write the autoscript file to disk. Or cause the CursorHold event
* to be triggered. * to be triggered.
*/ */
if (!WaitForChar(p_ut)) if (!WaitForChar(p_ut, FALSE))
{ {
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
if (trigger_cursorhold() && maxlen >= 3) if (trigger_cursorhold() && maxlen >= 3)
Expand Down Expand Up @@ -1723,7 +1735,7 @@ mch_inchar(
/* Keep looping until there is something in the typeahead buffer and more /* 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 * to get and still room in the buffer (up to two bytes for a char and
* three bytes for a modifier). */ * three bytes for a modifier). */
while ((typeaheadlen == 0 || WaitForChar(0L)) while ((typeaheadlen == 0 || WaitForChar(0L, FALSE))
&& typeaheadlen + 5 <= TYPEAHEADLEN) && typeaheadlen + 5 <= TYPEAHEADLEN)
{ {
if (typebuf_changed(tb_change_cnt)) if (typebuf_changed(tb_change_cnt))
Expand Down Expand Up @@ -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). * Returns the number of bytes actually written (at least one).
*/ */
static DWORD static DWORD
Expand Down Expand Up @@ -5828,7 +5840,7 @@ mch_write(


if (p_wd) if (p_wd)
{ {
WaitForChar(p_wd); WaitForChar(p_wd, FALSE);
if (prefix != 0) if (prefix != 0)
prefix = 1; prefix = 1;
} }
Expand Down Expand Up @@ -6120,7 +6132,7 @@ mch_delay(
# endif # endif
Sleep((int)msec); Sleep((int)msec);
else else
WaitForChar(msec); WaitForChar(msec, FALSE);
#endif #endif
} }


Expand Down
1 change: 1 addition & 0 deletions src/proto/os_unix.pro
Expand Up @@ -3,6 +3,7 @@ int mch_chdir(char *path);
void mch_write(char_u *s, int len); void mch_write(char_u *s, int len);
int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt); int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
int mch_char_avail(void); int mch_char_avail(void);
int mch_check_messages(void);
long_u mch_total_mem(int special); long_u mch_total_mem(int special);
void mch_delay(long msec, int ignoreinput); void mch_delay(long msec, int ignoreinput);
int mch_stackcheck(char *p); int mch_stackcheck(char *p);
Expand Down
1 change: 1 addition & 0 deletions src/proto/os_win32.pro
Expand Up @@ -8,6 +8,7 @@ void PlatformId(void);
void mch_setmouse(int on); void mch_setmouse(int on);
void mch_update_cursor(void); void mch_update_cursor(void);
int mch_char_avail(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); int mch_inchar(char_u *buf, int maxlen, long time, int tb_change_cnt);
void mch_init(void); void mch_init(void);
void mch_exit(int r); void mch_exit(int r);
Expand Down
18 changes: 12 additions & 6 deletions src/terminal.c
Expand Up @@ -1305,6 +1305,7 @@ term_channel_closed(channel_T *ch)


/* Need to break out of vgetc(). */ /* Need to break out of vgetc(). */
ins_char_typebuf(K_IGNORE); ins_char_typebuf(K_IGNORE);
typebuf_was_filled = TRUE;


term = curbuf->b_term; term = curbuf->b_term;
if (term != NULL) if (term != NULL)
Expand Down Expand Up @@ -2140,31 +2141,36 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
ch_log(NULL, "term_wait(): invalid argument"); ch_log(NULL, "term_wait(): invalid argument");
return; 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. */ /* Get the job status, this will detect a job that finished. */
if (buf->b_term->tl_job == NULL if (STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
|| STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
{ {
/* The job is dead, keep reading channel I/O until the channel is /* The job is dead, keep reading channel I/O until the channel is
* closed. */ * closed. */
ch_log(NULL, "term_wait(): waiting for channel to close");
while (buf->b_term != NULL && !buf->b_term->tl_channel_closed) while (buf->b_term != NULL && !buf->b_term->tl_channel_closed)
{ {
mch_char_avail(); mch_check_messages();
parse_queued_messages(); parse_queued_messages();
ui_delay(10L, FALSE); ui_delay(10L, FALSE);
} }
mch_char_avail(); mch_check_messages();
parse_queued_messages(); parse_queued_messages();
} }
else else
{ {
mch_char_avail(); mch_check_messages();
parse_queued_messages(); parse_queued_messages();


/* Wait for 10 msec for any channel I/O. */ /* Wait for 10 msec for any channel I/O. */
/* TODO: use delay from optional argument */ /* TODO: use delay from optional argument */
ui_delay(10L, TRUE); ui_delay(10L, TRUE);
mch_char_avail(); mch_check_messages();


/* Flushing messages on channels is hopefully sufficient. /* Flushing messages on channels is hopefully sufficient.
* TODO: is there a better way? */ * TODO: is there a better way? */
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -769,6 +769,8 @@ static char *(features[]) =


static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
854,
/**/ /**/
853, 853,
/**/ /**/
Expand Down

0 comments on commit e9c21ae

Please sign in to comment.