summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-12-18 18:14:47 +0100
committerBram Moolenaar <Bram@vim.org>2017-12-18 18:14:47 +0100
commitc9e649ae816cdff0d1da8a97d40e695c6d3991bd (patch)
treeb9e52b1126c83609c9b5dae5305e535bc4002a10
parent606d45ccd8a2ad2956e2729f6135fd79fd2f6d72 (diff)
downloadvim-git-c9e649ae816cdff0d1da8a97d40e695c6d3991bd.tar.gz
patch 8.0.1405: duplicated code for getting a typed characterv8.0.1405
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)
-rw-r--r--src/gui.c64
-rw-r--r--src/main.c2
-rw-r--r--src/os_unix.c32
-rw-r--r--src/proto/gui.pro3
-rw-r--r--src/proto/ui.pro1
-rw-r--r--src/ui.c57
-rw-r--r--src/version.c2
7 files changed, 90 insertions, 71 deletions
diff --git a/src/gui.c b/src/gui.c
index 5aa8214f5..7026a11d0 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -2886,6 +2886,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];
@@ -3006,6 +2992,22 @@ gui_wait_for_chars(long wtime)
}
/*
+ * 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().
*/
static void
diff --git a/src/main.c b/src/main.c
index bfcc3e517..877adaf5b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
diff --git a/src/os_unix.c b/src/os_unix.c
index b61dc4827..ff0b0e88d 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -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
diff --git a/src/proto/gui.pro b/src/proto/gui.pro
index 26466ae02..baad47fe4 100644
--- a/src/proto/gui.pro
+++ b/src/proto/gui.pro
@@ -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);
diff --git a/src/proto/ui.pro b/src/proto/ui.pro
index 4cf87b44f..ac830f0fc 100644
--- a/src/proto/ui.pro
+++ b/src/proto/ui.pro
@@ -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);
diff --git a/src/ui.c b/src/ui.c
index 7d969fec8..e410f6829 100644
--- 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);
diff --git a/src/version.c b/src/version.c
index 283a92c46..3584f140e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1405,
+/**/
1404,
/**/
1403,