From: Hirohito Higashi Date: Fri, 24 Jul 2026 20:20:54 +0000 (+0000) Subject: patch 9.2.0850: MS-Windows: commands from a client can be lost X-Git-Tag: v9.2.0850^0 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=bf3547849ff1d554dcd58d0f8ec7a3debb6b8427;p=thirdparty%2Fvim.git 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) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/src/gui_w32.c b/src/gui_w32.c index 077ca9c1f7..d9dbe65aca 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -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; diff --git a/src/os_mswin.c b/src/os_mswin.c index 6831171cf7..ac26dbc1be 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -2053,10 +2053,15 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) // Remember who sent this, for 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 diff --git a/src/proto/gui_w32.pro b/src/proto/gui_w32.pro index e6319e90cf..0a1628df30 100644 --- a/src/proto/gui_w32.pro +++ b/src/proto/gui_w32.pro @@ -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); diff --git a/src/version.c b/src/version.c index 296346f33f..028ab88800 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 850, /**/ 849, /**/