patch 9.2.0850: MS-Windows: commands from a client can be lost

Problem:  On MS-Windows commands sent by a client in quick succession,
          e.g. repeated "--remote-tab", can be lost: the files are not
          all opened (eight)
Solution: In the GUI the client message is handled re-entrantly, e.g.
          while a command line is being read during a redraw. Inserting
          the received keys into the typeahead buffer then corrupts it.
          Postpone inserting the keys until a safe point where the
          typeahead buffer is empty (Hirohito Higashi).

fixes:  #20810
closes: #20816

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Hirohito HigashiandClaude Opus 4.8 authored and Christian Brabandt committed 2026-07-24 20:20:54 +00:00
1 parent ea183ce4e5
commit bf3547849f
4 files changed
+55 -3

No files matched your search

+44
View File
@@ -2597,6 +2597,46 @@ remove_any_timer(void)
}
}
#ifdef FEAT_CLIENTSERVER
// A client message may be handled re-entrantly, e.g. during a redraw while a
// command line is being read; inserting the keys into the typeahead buffer
// then corrupts it. Store them here until a safe point.
static garray_T server_pending_ga = {0, 0, 0, 0, NULL};
/*
* Store keys received from a client, to be inserted into the typeahead buffer
* later by server_flush_input().
*/
void
server_add_input(char_u *str)
{
if (server_pending_ga.ga_data == NULL)
ga_init2(&server_pending_ga, 1, 200);
ga_concat(&server_pending_ga, str);
}
/*
* Insert postponed keys received from a client, but only when the typeahead
* buffer is empty, so that they are not mixed into a command that is currently
* being read.
*/
static void
server_flush_input(void)
{
char_u *str;
if (server_pending_ga.ga_len == 0 || typebuf.tb_len != 0)
return;
str = vim_strnsave(server_pending_ga.ga_data, server_pending_ga.ga_len);
server_pending_ga.ga_len = 0;
if (str != NULL)
{
server_to_input_buf(str);
vim_free(str);
}
}
#endif
/*
* GUI input routine called by gui_wait_for_chars(). Waits for a character
* from the keyboard.
@@ -2655,6 +2695,10 @@ gui_mch_wait_for_chars(int wtime)
MSG msg;
parse_queued_messages();
# ifdef FEAT_CLIENTSERVER
// Insert keys from a client that were postponed to this safe point.
server_flush_input();
# endif
# ifdef FEAT_TIMERS
if (did_add_timer)
break;
+8 -3
View File
@@ -2053,10 +2053,15 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
// Remember who sent this, for <client>
clientWindow = sender;
// Add the received keys to the input buffer. The loop waiting
// for the user to do something should check the input buffer.
// Add the received keys to the input buffer.
str = serverConvert(client_enc, (char_u *)data->lpData, &tofree);
server_to_input_buf(str);
# ifdef FEAT_GUI
if (gui.in_use)
// The GUI may get here re-entrantly, so insert the keys later.
server_add_input(str);
else
# endif
server_to_input_buf(str);
vim_free(tofree);
# ifdef FEAT_GUI
+1
View File
@@ -30,6 +30,7 @@ void gui_mch_iconify(void);
void gui_mch_draw_hollow_cursor(guicolor_T color);
void gui_mch_draw_part_cursor(int w, int h, guicolor_T color);
void gui_mch_update(void);
void server_add_input(char_u *str);
int gui_mch_wait_for_chars(int wtime);
void gui_mch_clear_block(int row1, int col1, int row2, int col2);
void gui_mch_free_popup_image(win_T *wp);
+2
View File
@@ -758,6 +758,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
850,
/**/
849,
/**/