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:
1 parent
ea183ce4e5
commit
bf3547849f
4 files changed
+55
-3
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -758,6 +758,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
850,
|
||||
/**/
|
||||
849,
|
||||
/**/
|
||||
|
||||
Reference in new issue
Block a user