}
}
+#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.
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;
// 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
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);