summaryrefslogtreecommitdiffstats
path: root/src/gui.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-27 16:55:47 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-27 16:55:47 +0100
commite40b9d47bf8f8f716d3ef5a95c8ecbbdc0a501f9 (patch)
tree7891a85cc4c4d8f9c173309dfdf7e870777a8046 /src/gui.c
parentd93090f41f70c521cfad5b25efcb0024b9480082 (diff)
patch 8.1.0834: GUI may wait too long before dealing with messagesv8.1.0834
Problem: GUI may wait too long before dealing with messages. Returning early may cause a mapping to time out. Solution: Use the waiting loop from Unix also for the GUI. (closes #3817, closes #3824)
Diffstat (limited to 'src/gui.c')
-rw-r--r--src/gui.c125
1 files changed, 52 insertions, 73 deletions
diff --git a/src/gui.c b/src/gui.c
index c22f47716b..39968954a8 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -2896,10 +2896,14 @@ gui_wait_for_chars_3(
* or FAIL otherwise.
*/
static int
-gui_wait_for_chars_or_timer(long wtime)
+gui_wait_for_chars_or_timer(
+ long wtime,
+ int *interrupted UNUSED,
+ int ignore_input UNUSED)
{
#ifdef FEAT_TIMERS
- return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0);
+ return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3,
+ interrupted, ignore_input);
#else
return gui_mch_wait_for_chars(wtime);
#endif
@@ -2907,94 +2911,72 @@ gui_wait_for_chars_or_timer(long wtime)
/*
* The main GUI input routine. Waits for a character from the keyboard.
- * wtime == -1 Wait forever.
- * wtime == 0 Don't wait.
- * wtime > 0 Wait wtime milliseconds for a character.
- * Returns OK if a character was found to be available within the given time,
- * or FAIL otherwise.
+ * "wtime" == -1 Wait forever.
+ * "wtime" == 0 Don't wait.
+ * "wtime" > 0 Wait wtime milliseconds for a character.
+ *
+ * Returns the number of characters read or zero when timed out or interrupted.
+ * "buf" may be NULL, in which case a non-zero number is returned if characters
+ * are available.
*/
- int
-gui_wait_for_chars(long wtime, int tb_change_cnt)
+ static int
+gui_wait_for_chars_buf(
+ char_u *buf,
+ int maxlen,
+ long wtime, // don't use "time", MIPS cannot handle it
+ int tb_change_cnt)
{
- int retval;
-#if defined(ELAPSED_FUNC)
- elapsed_T start_tv;
-#endif
+ int retval;
#ifdef FEAT_MENU
- /*
- * If we're going to wait a bit, update the menus and mouse shape for the
- * current State.
- */
+ // If we're going to wait a bit, update the menus and mouse shape for the
+ // current State.
if (wtime != 0)
gui_update_menus(0);
#endif
gui_mch_update();
- if (input_available()) /* Got char, return immediately */
- return OK;
- if (wtime == 0) /* Don't wait for char */
- return FAIL;
-
- /* Before waiting, flush any output to the screen. */
- gui_mch_flush();
-
- if (wtime > 0)
+ if (input_available()) // Got char, return immediately
{
- /* Blink when waiting for a character. Probably only does something
- * for showmatch() */
- gui_mch_start_blink();
- retval = gui_wait_for_chars_or_timer(wtime);
- gui_mch_stop_blink(TRUE);
- return retval;
+ if (buf != NULL && !typebuf_changed(tb_change_cnt))
+ return read_from_input_buf(buf, (long)maxlen);
+ return 0;
}
+ if (wtime == 0) // Don't wait for char
+ return FAIL;
-#if defined(ELAPSED_FUNC)
- ELAPSED_INIT(start_tv);
-#endif
+ // Before waiting, flush any output to the screen.
+ gui_mch_flush();
- /*
- * While we are waiting indefinitely for a character, blink the cursor.
- */
+ // Blink while waiting for a character.
gui_mch_start_blink();
- retval = FAIL;
- /*
- * We may want to trigger the CursorHold event. First wait for
- * '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;
- else if (trigger_cursorhold()
-#if defined(ELAPSED_FUNC)
- && ELAPSED_FUNC(start_tv) >= p_ut
-#endif
- && typebuf.tb_change_cnt == tb_change_cnt)
- {
- char_u buf[3];
-
- /* Put K_CURSORHOLD in the input buffer. */
- buf[0] = CSI;
- buf[1] = KS_EXTRA;
- buf[2] = (int)KE_CURSORHOLD;
- add_to_input_buf(buf, 3);
-
- retval = OK;
- }
-
- if (retval == FAIL && typebuf.tb_change_cnt == tb_change_cnt)
- {
- /* Blocking wait. */
- before_blocking();
- retval = gui_wait_for_chars_or_timer(-1L);
- }
+ // Common function to loop until "wtime" is met, while handling timers and
+ // other callbacks.
+ retval = inchar_loop(buf, maxlen, wtime, tb_change_cnt,
+ gui_wait_for_chars_or_timer, NULL);
gui_mch_stop_blink(TRUE);
+
return retval;
}
/*
+ * Wait for a character from the keyboard without actually reading it.
+ * Also deals with timers.
+ * wtime == -1 Wait forever.
+ * wtime == 0 Don't wait.
+ * wtime > 0 Wait wtime milliseconds for a character.
+ * Returns OK if a character was found to be available within the given time,
+ * or FAIL otherwise.
+ */
+ int
+gui_wait_for_chars(long wtime, int tb_change_cnt)
+{
+ return gui_wait_for_chars_buf(NULL, 0, wtime, tb_change_cnt);
+}
+
+/*
* Equivalent of mch_inchar() for the GUI.
*/
int
@@ -3004,10 +2986,7 @@ gui_inchar(
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;
+ return gui_wait_for_chars_buf(buf, maxlen, wtime, tb_change_cnt);
}
/*