]> granicus.if.org Git - vim/commitdiff
patch 8.0.1405: duplicated code for getting a typed character v8.0.1405
authorBram Moolenaar <Bram@vim.org>
Mon, 18 Dec 2017 17:14:47 +0000 (18:14 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 18 Dec 2017 17:14:47 +0000 (18:14 +0100)
Problem:    Duplicated code for getting a typed character. CursorHold is
            called too often in the GUI. (lilydjwg)
Solution:   Refactor code to move code up from mch_inchar().  Don't fire
            CursorHold if feedkeys() was used. (closes #2451)

src/gui.c
src/main.c
src/os_unix.c
src/proto/gui.pro
src/proto/ui.pro
src/ui.c
src/version.c

index 5aa8214f5f32d05ca80bd541c0172813f046ca01..7026a11d0c967b33b069a441c01b89c04dac3adf 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -2885,6 +2885,18 @@ gui_insert_lines(int row, int count)
     }
 }
 
+/*
+ * Passed to ui_wait_for_chars_or_timer(), ignoring extra arguments.
+ */
+    static int
+gui_wait_for_chars_3(
+    long wtime,
+    int *interrupted UNUSED,
+    int ignore_input UNUSED)
+{
+    return gui_mch_wait_for_chars(wtime);
+}
+
 /*
  * Returns OK if a character was found to be available within the given time,
  * or FAIL otherwise.
@@ -2893,32 +2905,7 @@ gui_insert_lines(int row, int count)
 gui_wait_for_chars_or_timer(long wtime)
 {
 #ifdef FEAT_TIMERS
-    int            due_time;
-    long    remaining = wtime;
-    int            tb_change_cnt = typebuf.tb_change_cnt;
-
-    /* When waiting very briefly don't trigger timers. */
-    if (wtime >= 0 && wtime < 10L)
-       return gui_mch_wait_for_chars(wtime);
-
-    while (wtime < 0 || remaining > 0)
-    {
-       /* Trigger timers and then get the time in wtime until the next one is
-        * due.  Wait up to that time. */
-       due_time = check_due_timer();
-       if (typebuf.tb_change_cnt != tb_change_cnt)
-       {
-           /* timer may have used feedkeys() */
-           return FAIL;
-       }
-       if (due_time <= 0 || (wtime > 0 && due_time > remaining))
-           due_time = remaining;
-       if (gui_mch_wait_for_chars(due_time))
-           return OK;
-       if (wtime > 0)
-           remaining -= due_time;
-    }
-    return FAIL;
+    return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0);
 #else
     return gui_mch_wait_for_chars(wtime);
 #endif
@@ -2933,10 +2920,9 @@ gui_wait_for_chars_or_timer(long wtime)
  * or FAIL otherwise.
  */
     int
-gui_wait_for_chars(long wtime)
+gui_wait_for_chars(long wtime, int tb_change_cnt)
 {
     int            retval;
-    int            tb_change_cnt = typebuf.tb_change_cnt;
 
 #ifdef FEAT_MENU
     /*
@@ -2974,13 +2960,13 @@ gui_wait_for_chars(long wtime)
     retval = FAIL;
     /*
      * We may want to trigger the CursorHold event.  First wait for
-     * 'updatetime' and if nothing is typed within that time put the
-     * K_CURSORHOLD key in the input buffer.
+     * 'updatetime' and if nothing is typed within that time, and feedkeys()
+     * wasn't used, put the K_CURSORHOLD key in the input buffer.
      */
     if (gui_wait_for_chars_or_timer(p_ut) == OK)
        retval = OK;
 #ifdef FEAT_AUTOCMD
-    else if (trigger_cursorhold())
+    else if (trigger_cursorhold() && typebuf.tb_change_cnt == tb_change_cnt)
     {
        char_u  buf[3];
 
@@ -3005,6 +2991,22 @@ gui_wait_for_chars(long wtime)
     return retval;
 }
 
+/*
+ * Equivalent of mch_inchar() for the GUI.
+ */
+    int
+gui_inchar(
+    char_u  *buf,
+    int            maxlen,
+    long    wtime,             /* milli seconds */
+    int            tb_change_cnt)
+{
+    if (gui_wait_for_chars(wtime, tb_change_cnt)
+           && !typebuf_changed(tb_change_cnt))
+       return read_from_input_buf(buf, (long)maxlen);
+    return 0;
+}
+
 /*
  * Fill p[4] with mouse coordinates encoded for check_termcode().
  */
index bfcc3e517b08ba8228bd4a3dca8b999f28b660c3..877adaf5ba268a2a9fe74b2216ea13074925b895 100644 (file)
@@ -619,7 +619,7 @@ vim_main2(void)
 # ifdef FEAT_SUN_WORKSHOP
        if (!usingSunWorkShop)
 # endif
-           gui_wait_for_chars(50L);
+           gui_wait_for_chars(50L, typebuf.tb_change_cnt);
        TIME_MSG("GUI delay");
     }
 #endif
index b61dc48274eb89d6fe8c042fbc6ffe57565a5a78..ff0b0e88d61940fdb670b439ece8c8197082ed0f 100644 (file)
@@ -5790,36 +5790,8 @@ mch_breakcheck(int force)
 WaitForChar(long msec, int *interrupted, int ignore_input)
 {
 #ifdef FEAT_TIMERS
-    long    due_time;
-    long    remaining = msec;
-    int            tb_change_cnt = typebuf.tb_change_cnt;
-
-    /* When waiting very briefly don't trigger timers. */
-    if (msec >= 0 && msec < 10L)
-       return WaitForCharOrMouse(msec, NULL, ignore_input);
-
-    while (msec < 0 || remaining > 0)
-    {
-       /* Trigger timers and then get the time in msec until the next one is
-        * due.  Wait up to that time. */
-       due_time = check_due_timer();
-       if (typebuf.tb_change_cnt != tb_change_cnt)
-       {
-           /* timer may have used feedkeys() */
-           return FALSE;
-       }
-       if (due_time <= 0 || (msec > 0 && due_time > remaining))
-           due_time = remaining;
-       if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
-           return TRUE;
-       if (interrupted != NULL && *interrupted)
-           /* Nothing available, but need to return so that side effects get
-            * handled, such as handling a message on a channel. */
-           return FALSE;
-       if (msec > 0)
-           remaining -= due_time;
-    }
-    return FALSE;
+    return ui_wait_for_chars_or_timer(
+                   msec, WaitForCharOrMouse, interrupted, ignore_input) == OK;
 #else
     return WaitForCharOrMouse(msec, interrupted, ignore_input);
 #endif
index 26466ae0252257ec32faabd8d7c91d5707bf4d0a..baad47fe40c7ce9b9bde5b22feb437f01d9c3af0 100644 (file)
@@ -29,7 +29,8 @@ int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T b
 void gui_undraw_cursor(void);
 void gui_redraw(int x, int y, int w, int h);
 int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
-int gui_wait_for_chars(long wtime);
+int gui_wait_for_chars(long wtime, int tb_change_cnt);
+int gui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
 void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u modifiers);
 int gui_xy2colrow(int x, int y, int *colp);
 void gui_menu_cb(vimmenu_T *menu);
index 4cf87b44f7577bf7a4a9c5a639fc65a5459ba564..ac830f0fcb68176274f08a2590db5c7844092a45 100644 (file)
@@ -2,6 +2,7 @@
 void ui_write(char_u *s, int len);
 void ui_inchar_undo(char_u *s, int len);
 int ui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
+int ui_wait_for_chars_or_timer(long wtime, int (*wait_func)(long wtime, int *interrupted, int ignore_input), int *interrupted, int ignore_input);
 int ui_char_avail(void);
 void ui_delay(long msec, int ignoreinput);
 void ui_suspend(void);
index 7d969fec861ca50e2b8e7728e199e0ab663eeccd..e410f6829920fcae88afa7137afe52e8d21d6733 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -32,7 +32,7 @@ ui_write(char_u *s, int len)
     {
        gui_write(s, len);
        if (p_wd)
-           gui_wait_for_chars(p_wd);
+           gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
        return;
     }
 #endif
@@ -182,18 +182,13 @@ ui_inchar(
 
 #ifdef FEAT_GUI
     if (gui.in_use)
-    {
-       if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
-           retval = read_from_input_buf(buf, (long)maxlen);
-    }
+       retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
 #endif
 #ifndef NO_CONSOLE
 # ifdef FEAT_GUI
     else
 # endif
-    {
        retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
-    }
 #endif
 
     if (wtime == -1 || wtime > 100L)
@@ -212,6 +207,52 @@ theend:
     return retval;
 }
 
+#if defined(FEAT_TIMERS) || defined(PROT)
+/*
+ * Wait for a timer to fire or "wait_func" to return non-zero.
+ * Returns OK when something was read.
+ * Returns FAIL when it timed out or was interrupted.
+ */
+    int
+ui_wait_for_chars_or_timer(
+    long    wtime,
+    int            (*wait_func)(long wtime, int *interrupted, int ignore_input),
+    int            *interrupted,
+    int            ignore_input)
+{
+    int            due_time;
+    long    remaining = wtime;
+    int            tb_change_cnt = typebuf.tb_change_cnt;
+
+    /* When waiting very briefly don't trigger timers. */
+    if (wtime >= 0 && wtime < 10L)
+       return wait_func(wtime, NULL, ignore_input);
+
+    while (wtime < 0 || remaining > 0)
+    {
+       /* Trigger timers and then get the time in wtime until the next one is
+        * due.  Wait up to that time. */
+       due_time = check_due_timer();
+       if (typebuf.tb_change_cnt != tb_change_cnt)
+       {
+           /* timer may have used feedkeys() */
+           return FAIL;
+       }
+       if (due_time <= 0 || (wtime > 0 && due_time > remaining))
+           due_time = remaining;
+       if (wait_func(due_time, interrupted, ignore_input))
+           return OK;
+       if (interrupted != NULL && *interrupted)
+           /* Nothing available, but need to return so that side effects get
+            * handled, such as handling a message on a channel. */
+           return FALSE;
+       if (wtime > 0)
+           remaining -= due_time;
+    }
+    return FAIL;
+}
+#endif
+
 /*
  * return non-zero if a character is available
  */
@@ -245,7 +286,7 @@ ui_delay(long msec, int ignoreinput)
 {
 #ifdef FEAT_GUI
     if (gui.in_use && !ignoreinput)
-       gui_wait_for_chars(msec);
+       gui_wait_for_chars(msec, typebuf.tb_change_cnt);
     else
 #endif
        mch_delay(msec, ignoreinput);
index 283a92c466b6358c0f87274068a4130e0971e6e3..3584f140eece499ffadefdb252dfbe5258e350ea 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1405,
 /**/
     1404,
 /**/