]> granicus.if.org Git - vim/commitdiff
patch 8.1.0840: getchar(0) never returns a character in the terminal v8.1.0840
authorBram Moolenaar <Bram@vim.org>
Mon, 28 Jan 2019 21:32:58 +0000 (22:32 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 28 Jan 2019 21:32:58 +0000 (22:32 +0100)
Problem:    getchar(0) never returns a character in the terminal.
Solution:   Call wait_func() at least once.

src/gui_gtk_x11.c
src/gui_photon.c
src/gui_w32.c
src/gui_x11.c
src/testdir/test_timers.vim
src/ui.c
src/version.c

index 6882733696990efcabaae1fb2dcfb86d1614836a..e1de83a68b54ea762ab885fa7ae86f1a5dcd80e0 100644 (file)
@@ -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;
 
index 234d25066947832b6e8682802fc345d1c4801cfa..94012287e799c5199d73bcf339e5bee38f48c9b4 100644 (file)
@@ -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)
     {
index c5e58790d263aea65c7a01b1bf5912a24046805e..ead617a79f9e86623ec302080b71caeabc968e19 100644 (file)
@@ -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);
     }
 
index c8a3b773ab9e359dfbed80f5499c52008a65ff67..ad91a21013fd3c71d0a8449e82279dbc6ba2706e 100644 (file)
@@ -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. */
index bccd31b93daa00da24f2130458504052aa5b08e6..0b88d8af23ff084f59bbf4debfba2e4bb2a19c67 100644 (file)
@@ -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(...)
index d4278a39f8b56cd5441145a3f121f31fead6841e..0823d2dd2382c42e778a438ad07705731e720ba4 100644 (file)
--- 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.
index b69344ce18ff79d91121809af30b10ca8ae8d1ba..ae28d083d5b9cc740b59a5d0a2742db652050770 100644 (file)
@@ -783,6 +783,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    840,
 /**/
     839,
 /**/