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

Christian Brabandt <[email protected]>
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0850: MS-Windows: commands from a client can be lost

Commit: https://github.com/vim/vim/commit/bf3547849ff1d554dcd58d0f8ec7a3debb6b8427
Author: Hirohito Higashi <[email protected]>
Date:   Fri Jul 24 20:20:54 2026 +0000

    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) <[email protected]>
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/gui_w32.c b/src/gui_w32.c
index 077ca9c1f..d9dbe65ac 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 6831171cf..ac26dbc1b 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 <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
diff --git a/src/proto/gui_w32.pro b/src/proto/gui_w32.pro
index e6319e90c..0a1628df3 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 296346f33..028ab8880 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,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wnMX0-00C78j-UW%40256bit.org.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.