Skip to content

Commit c9e649a

Browse files
committed
patch 8.0.1405: duplicated code for getting a typed character
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)
1 parent 606d45c commit c9e649a

7 files changed

Lines changed: 90 additions & 71 deletions

File tree

src/gui.c

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,6 +2885,18 @@ gui_insert_lines(int row, int count)
28852885
}
28862886
}
28872887

2888+
/*
2889+
* Passed to ui_wait_for_chars_or_timer(), ignoring extra arguments.
2890+
*/
2891+
static int
2892+
gui_wait_for_chars_3(
2893+
long wtime,
2894+
int *interrupted UNUSED,
2895+
int ignore_input UNUSED)
2896+
{
2897+
return gui_mch_wait_for_chars(wtime);
2898+
}
2899+
28882900
/*
28892901
* Returns OK if a character was found to be available within the given time,
28902902
* or FAIL otherwise.
@@ -2893,32 +2905,7 @@ gui_insert_lines(int row, int count)
28932905
gui_wait_for_chars_or_timer(long wtime)
28942906
{
28952907
#ifdef FEAT_TIMERS
2896-
int due_time;
2897-
long remaining = wtime;
2898-
int tb_change_cnt = typebuf.tb_change_cnt;
2899-
2900-
/* When waiting very briefly don't trigger timers. */
2901-
if (wtime >= 0 && wtime < 10L)
2902-
return gui_mch_wait_for_chars(wtime);
2903-
2904-
while (wtime < 0 || remaining > 0)
2905-
{
2906-
/* Trigger timers and then get the time in wtime until the next one is
2907-
* due. Wait up to that time. */
2908-
due_time = check_due_timer();
2909-
if (typebuf.tb_change_cnt != tb_change_cnt)
2910-
{
2911-
/* timer may have used feedkeys() */
2912-
return FAIL;
2913-
}
2914-
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
2915-
due_time = remaining;
2916-
if (gui_mch_wait_for_chars(due_time))
2917-
return OK;
2918-
if (wtime > 0)
2919-
remaining -= due_time;
2920-
}
2921-
return FAIL;
2908+
return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0);
29222909
#else
29232910
return gui_mch_wait_for_chars(wtime);
29242911
#endif
@@ -2933,10 +2920,9 @@ gui_wait_for_chars_or_timer(long wtime)
29332920
* or FAIL otherwise.
29342921
*/
29352922
int
2936-
gui_wait_for_chars(long wtime)
2923+
gui_wait_for_chars(long wtime, int tb_change_cnt)
29372924
{
29382925
int retval;
2939-
int tb_change_cnt = typebuf.tb_change_cnt;
29402926

29412927
#ifdef FEAT_MENU
29422928
/*
@@ -2974,13 +2960,13 @@ gui_wait_for_chars(long wtime)
29742960
retval = FAIL;
29752961
/*
29762962
* We may want to trigger the CursorHold event. First wait for
2977-
* 'updatetime' and if nothing is typed within that time put the
2978-
* K_CURSORHOLD key in the input buffer.
2963+
* 'updatetime' and if nothing is typed within that time, and feedkeys()
2964+
* wasn't used, put the K_CURSORHOLD key in the input buffer.
29792965
*/
29802966
if (gui_wait_for_chars_or_timer(p_ut) == OK)
29812967
retval = OK;
29822968
#ifdef FEAT_AUTOCMD
2983-
else if (trigger_cursorhold())
2969+
else if (trigger_cursorhold() && typebuf.tb_change_cnt == tb_change_cnt)
29842970
{
29852971
char_u buf[3];
29862972

@@ -3005,6 +2991,22 @@ gui_wait_for_chars(long wtime)
30052991
return retval;
30062992
}
30072993

2994+
/*
2995+
* Equivalent of mch_inchar() for the GUI.
2996+
*/
2997+
int
2998+
gui_inchar(
2999+
char_u *buf,
3000+
int maxlen,
3001+
long wtime, /* milli seconds */
3002+
int tb_change_cnt)
3003+
{
3004+
if (gui_wait_for_chars(wtime, tb_change_cnt)
3005+
&& !typebuf_changed(tb_change_cnt))
3006+
return read_from_input_buf(buf, (long)maxlen);
3007+
return 0;
3008+
}
3009+
30083010
/*
30093011
* Fill p[4] with mouse coordinates encoded for check_termcode().
30103012
*/

src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ vim_main2(void)
619619
# ifdef FEAT_SUN_WORKSHOP
620620
if (!usingSunWorkShop)
621621
# endif
622-
gui_wait_for_chars(50L);
622+
gui_wait_for_chars(50L, typebuf.tb_change_cnt);
623623
TIME_MSG("GUI delay");
624624
}
625625
#endif

src/os_unix.c

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5790,36 +5790,8 @@ mch_breakcheck(int force)
57905790
WaitForChar(long msec, int *interrupted, int ignore_input)
57915791
{
57925792
#ifdef FEAT_TIMERS
5793-
long due_time;
5794-
long remaining = msec;
5795-
int tb_change_cnt = typebuf.tb_change_cnt;
5796-
5797-
/* When waiting very briefly don't trigger timers. */
5798-
if (msec >= 0 && msec < 10L)
5799-
return WaitForCharOrMouse(msec, NULL, ignore_input);
5800-
5801-
while (msec < 0 || remaining > 0)
5802-
{
5803-
/* Trigger timers and then get the time in msec until the next one is
5804-
* due. Wait up to that time. */
5805-
due_time = check_due_timer();
5806-
if (typebuf.tb_change_cnt != tb_change_cnt)
5807-
{
5808-
/* timer may have used feedkeys() */
5809-
return FALSE;
5810-
}
5811-
if (due_time <= 0 || (msec > 0 && due_time > remaining))
5812-
due_time = remaining;
5813-
if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
5814-
return TRUE;
5815-
if (interrupted != NULL && *interrupted)
5816-
/* Nothing available, but need to return so that side effects get
5817-
* handled, such as handling a message on a channel. */
5818-
return FALSE;
5819-
if (msec > 0)
5820-
remaining -= due_time;
5821-
}
5822-
return FALSE;
5793+
return ui_wait_for_chars_or_timer(
5794+
msec, WaitForCharOrMouse, interrupted, ignore_input) == OK;
58235795
#else
58245796
return WaitForCharOrMouse(msec, interrupted, ignore_input);
58255797
#endif

src/proto/gui.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T b
2929
void gui_undraw_cursor(void);
3030
void gui_redraw(int x, int y, int w, int h);
3131
int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
32-
int gui_wait_for_chars(long wtime);
32+
int gui_wait_for_chars(long wtime, int tb_change_cnt);
33+
int gui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
3334
void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u modifiers);
3435
int gui_xy2colrow(int x, int y, int *colp);
3536
void gui_menu_cb(vimmenu_T *menu);

src/proto/ui.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
void ui_write(char_u *s, int len);
33
void ui_inchar_undo(char_u *s, int len);
44
int ui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
5+
int ui_wait_for_chars_or_timer(long wtime, int (*wait_func)(long wtime, int *interrupted, int ignore_input), int *interrupted, int ignore_input);
56
int ui_char_avail(void);
67
void ui_delay(long msec, int ignoreinput);
78
void ui_suspend(void);

src/ui.c

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ ui_write(char_u *s, int len)
3232
{
3333
gui_write(s, len);
3434
if (p_wd)
35-
gui_wait_for_chars(p_wd);
35+
gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
3636
return;
3737
}
3838
#endif
@@ -182,18 +182,13 @@ ui_inchar(
182182

183183
#ifdef FEAT_GUI
184184
if (gui.in_use)
185-
{
186-
if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
187-
retval = read_from_input_buf(buf, (long)maxlen);
188-
}
185+
retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
189186
#endif
190187
#ifndef NO_CONSOLE
191188
# ifdef FEAT_GUI
192189
else
193190
# endif
194-
{
195191
retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
196-
}
197192
#endif
198193

199194
if (wtime == -1 || wtime > 100L)
@@ -212,6 +207,52 @@ ui_inchar(
212207
return retval;
213208
}
214209

210+
#if defined(FEAT_TIMERS) || defined(PROT)
211+
/*
212+
* Wait for a timer to fire or "wait_func" to return non-zero.
213+
* Returns OK when something was read.
214+
* Returns FAIL when it timed out or was interrupted.
215+
*/
216+
int
217+
ui_wait_for_chars_or_timer(
218+
long wtime,
219+
int (*wait_func)(long wtime, int *interrupted, int ignore_input),
220+
int *interrupted,
221+
int ignore_input)
222+
{
223+
int due_time;
224+
long remaining = wtime;
225+
int tb_change_cnt = typebuf.tb_change_cnt;
226+
227+
/* When waiting very briefly don't trigger timers. */
228+
if (wtime >= 0 && wtime < 10L)
229+
return wait_func(wtime, NULL, ignore_input);
230+
231+
while (wtime < 0 || remaining > 0)
232+
{
233+
/* Trigger timers and then get the time in wtime until the next one is
234+
* due. Wait up to that time. */
235+
due_time = check_due_timer();
236+
if (typebuf.tb_change_cnt != tb_change_cnt)
237+
{
238+
/* timer may have used feedkeys() */
239+
return FAIL;
240+
}
241+
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
242+
due_time = remaining;
243+
if (wait_func(due_time, interrupted, ignore_input))
244+
return OK;
245+
if (interrupted != NULL && *interrupted)
246+
/* Nothing available, but need to return so that side effects get
247+
* handled, such as handling a message on a channel. */
248+
return FALSE;
249+
if (wtime > 0)
250+
remaining -= due_time;
251+
}
252+
return FAIL;
253+
}
254+
#endif
255+
215256
/*
216257
* return non-zero if a character is available
217258
*/
@@ -245,7 +286,7 @@ ui_delay(long msec, int ignoreinput)
245286
{
246287
#ifdef FEAT_GUI
247288
if (gui.in_use && !ignoreinput)
248-
gui_wait_for_chars(msec);
289+
gui_wait_for_chars(msec, typebuf.tb_change_cnt);
249290
else
250291
#endif
251292
mch_delay(msec, ignoreinput);

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ static char *(features[]) =
771771

772772
static int included_patches[] =
773773
{ /* Add new patch number below this line */
774+
/**/
775+
1405,
774776
/**/
775777
1404,
776778
/**/

0 commit comments

Comments
 (0)