]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0850: MS-Windows: commands from a client can be lost v9.2.0850
authorHirohito Higashi <h.east.727@gmail.com>
Fri, 24 Jul 2026 20:20:54 +0000 (20:20 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 24 Jul 2026 20:20:54 +0000 (20:20 +0000)
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>
src/gui_w32.c
src/os_mswin.c
src/proto/gui_w32.pro
src/version.c

index 077ca9c1f7882bd0e5c0f844e1827071e503c036..d9dbe65acada7392682e58651b8f0cf755f9afbc 100644 (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;
index 6831171cf7d580cb7949324d31f86d8adf5770df..ac26dbc1be503bc557a44c6cc6109eda58f5fe52 100644 (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
index e6319e90cf267a4bf2cdf1abdfa63610ef0c95b6..0a1628df30e16ea2d4b9f41764245b90dbcda619 100644 (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);
index 296346f33f260d83b4f4847256e7a8a09f15ea0e..028ab88800dd3ab0fa89ef14b79c8af3af14f27c 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    850,
 /**/
     849,
 /**/