summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-28 22:32:58 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-28 22:32:58 +0100
commit12dfc9eef14fe74c46145aa9e6cba9666f1bcd40 (patch)
tree3a3c98030644028f710d33d7c2b2558ac0f2db13
parentf58d81a18752cb9bf899b3f7328fc489cf6558e8 (diff)
downloadvim-git-8.1.0840.tar.gz
patch 8.1.0840: getchar(0) never returns a character in the terminalv8.1.0840
Problem: getchar(0) never returns a character in the terminal. Solution: Call wait_func() at least once.
-rw-r--r--src/gui_gtk_x11.c9
-rw-r--r--src/gui_photon.c5
-rw-r--r--src/gui_w32.c8
-rw-r--r--src/gui_x11.c7
-rw-r--r--src/testdir/test_timers.vim10
-rw-r--r--src/ui.c8
-rw-r--r--src/version.c2
7 files changed, 36 insertions, 13 deletions
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 688273369..e1de83a68 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -6317,10 +6317,11 @@ gui_mch_wait_for_chars(long wtime)
timed_out = FALSE;
- /* this timeout makes sure that we will return if no characters arrived in
- * time */
- if (wtime > 0)
- timer = timeout_add(wtime, input_timer_cb, &timed_out);
+ // This timeout makes sure that we will return if no characters arrived in
+ // time. If "wtime" is zero just use one.
+ if (wtime >= 0)
+ timer = timeout_add(wtime <= 0 ? 1L : wtime,
+ input_timer_cb, &timed_out);
else
timer = 0;
diff --git a/src/gui_photon.c b/src/gui_photon.c
index 234d25066..94012287e 100644
--- a/src/gui_photon.c
+++ b/src/gui_photon.c
@@ -1344,8 +1344,9 @@ gui_mch_wait_for_chars(int wtime)
{
is_timeout = FALSE;
- if (wtime > 0)
- PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, wtime, 0);
+ if (wtime >= 0)
+ PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL,
+ wtime == 0 ? 1 : wtime, 0);
while (1)
{
diff --git a/src/gui_w32.c b/src/gui_w32.c
index c5e58790d..ead617a79 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2097,12 +2097,14 @@ gui_mch_wait_for_chars(int wtime)
s_timed_out = FALSE;
- if (wtime > 0)
+ if (wtime >= 0)
{
- /* Don't do anything while processing a (scroll) message. */
+ // Don't do anything while processing a (scroll) message.
if (s_busy_processing)
return FAIL;
- s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)wtime,
+
+ // When called with "wtime" zero, just want one msec.
+ s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)(wtime == 0 ? 1 : wtime),
(TIMERPROC)_OnTimer);
}
diff --git a/src/gui_x11.c b/src/gui_x11.c
index c8a3b773a..ad91a2101 100644
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -2683,9 +2683,10 @@ gui_mch_wait_for_chars(long wtime)
timed_out = FALSE;
- if (wtime > 0)
- timer = XtAppAddTimeOut(app_context, (long_u)wtime, gui_x11_timer_cb,
- &timed_out);
+ if (wtime >= 0)
+ timer = XtAppAddTimeOut(app_context,
+ (long_u)(wtime == 0 ? 1L : wtime),
+ gui_x11_timer_cb, &timed_out);
#ifdef FEAT_JOB_CHANNEL
/* If there is a channel with the keep_open flag we need to poll for input
* on them. */
diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim
index bccd31b93..0b88d8af2 100644
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -250,6 +250,16 @@ func Test_peek_and_get_char()
call timer_stop(intr)
endfunc
+func Test_getchar_zero()
+ call timer_start(20, {id -> feedkeys('x', 'L')})
+ let c = 0
+ while c == 0
+ let c = getchar(0)
+ sleep 10m
+ endwhile
+ call assert_equal('x', nr2char(c))
+endfunc
+
func Test_ex_mode()
" Function with an empty line.
func Foo(...)
diff --git a/src/ui.c b/src/ui.c
index d4278a39f..0823d2dd2 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -272,6 +272,7 @@ inchar_loop(
{
int len;
int interrupted = FALSE;
+ int did_call_wait_func = FALSE;
int did_start_blocking = FALSE;
long wait_time;
long elapsed_time = 0;
@@ -313,7 +314,11 @@ inchar_loop(
elapsed_time = ELAPSED_FUNC(start_tv);
#endif
wait_time -= elapsed_time;
- if (wait_time <= 0)
+
+ // If the waiting time is now zero or less, we timed out. However,
+ // loop at least once to check for characters and events. Matters
+ // when "wtime" is zero.
+ if (wait_time <= 0 && did_call_wait_func)
{
if (wtime >= 0)
// no character available within "wtime"
@@ -374,6 +379,7 @@ inchar_loop(
// Wait for a character to be typed or another event, such as the winch
// signal or an event on the monitored file descriptors.
+ did_call_wait_func = TRUE;
if (wait_func(wait_time, &interrupted, FALSE))
{
// If input was put directly in typeahead buffer bail out here.
diff --git a/src/version.c b/src/version.c
index b69344ce1..ae28d083d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 840,
+/**/
839,
/**/
838,