mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(tui): detach/attach on suspend/resume (#22040)
Problem: When a TUI client is suspended it still receives UI events from the server, and has to process these accumulated events when it is resumed. With mulitple TUI clients this is a bigger problem, considering the following steps: 1. A TUI client is attached. 2. CTRL-Z is pressed and the first client is suspended. 3. Another TUI client is attached. 4. CTRL-Z is pressed and a "suspend" event is sent to both clients. The second client is suspended, while the first client isn't able to process the event because it has already been suspended. 5. The first client is resumed. It processes the accumulated "suspend" event and suspends immediately. Solution: Make a TUI client detach on suspend and re-attach on resume.
This commit is contained in:
parent
cbf9199d65
commit
d3355ad01c
@ -1347,6 +1347,7 @@ static void show_verbose_terminfo(TUIData *tui)
|
||||
static void suspend_event(void **argv)
|
||||
{
|
||||
TUIData *tui = argv[0];
|
||||
ui_client_detach();
|
||||
bool enable_mouse = tui->mouse_enabled;
|
||||
tui_terminal_stop(tui);
|
||||
stream_set_blocking(tui->input.in_fd, true); // normalize stream (#2598)
|
||||
@ -1359,6 +1360,7 @@ static void suspend_event(void **argv)
|
||||
tui_mouse_on(tui);
|
||||
}
|
||||
stream_set_blocking(tui->input.in_fd, false); // libuv expects this
|
||||
ui_client_attach(tui->width, tui->height, tui->term);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nvim/ui_client.h"
|
||||
|
||||
static TUIData *tui = NULL;
|
||||
static bool ui_client_is_remote = false;
|
||||
|
||||
// uncrustify:off
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
@ -66,13 +67,8 @@ uint64_t ui_client_start_server(int argc, char **argv)
|
||||
return channel->id;
|
||||
}
|
||||
|
||||
void ui_client_run(bool remote_ui)
|
||||
FUNC_ATTR_NORETURN
|
||||
void ui_client_attach(int width, int height, char *term)
|
||||
{
|
||||
int width, height;
|
||||
char *term;
|
||||
tui = tui_start(&width, &height, &term);
|
||||
|
||||
MAXSIZE_TEMP_ARRAY(args, 3);
|
||||
ADD_C(args, INTEGER_OBJ(width));
|
||||
ADD_C(args, INTEGER_OBJ(height));
|
||||
@ -82,14 +78,14 @@ void ui_client_run(bool remote_ui)
|
||||
PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true));
|
||||
PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true));
|
||||
if (term) {
|
||||
PUT(opts, "term_name", STRING_OBJ(cstr_to_string(term)));
|
||||
PUT_C(opts, "term_name", STRING_OBJ(cstr_as_string(term)));
|
||||
}
|
||||
if (ui_client_bg_response != kNone) {
|
||||
bool is_dark = (ui_client_bg_response == kTrue);
|
||||
PUT_C(opts, "term_background", STRING_OBJ(cstr_as_string(is_dark ? "dark" : "light")));
|
||||
}
|
||||
PUT_C(opts, "term_colors", INTEGER_OBJ(t_colors));
|
||||
if (!remote_ui) {
|
||||
if (!ui_client_is_remote) {
|
||||
PUT_C(opts, "stdin_tty", BOOLEAN_OBJ(stdin_isatty));
|
||||
PUT_C(opts, "stdout_tty", BOOLEAN_OBJ(stdout_isatty));
|
||||
if (ui_client_forward_stdin) {
|
||||
@ -100,6 +96,23 @@ void ui_client_run(bool remote_ui)
|
||||
|
||||
rpc_send_event(ui_client_channel_id, "nvim_ui_attach", args);
|
||||
ui_client_attached = true;
|
||||
}
|
||||
|
||||
void ui_client_detach(void)
|
||||
{
|
||||
rpc_send_event(ui_client_channel_id, "nvim_ui_detach", (Array)ARRAY_DICT_INIT);
|
||||
ui_client_attached = false;
|
||||
}
|
||||
|
||||
void ui_client_run(bool remote_ui)
|
||||
FUNC_ATTR_NORETURN
|
||||
{
|
||||
ui_client_is_remote = remote_ui;
|
||||
int width, height;
|
||||
char *term;
|
||||
tui = tui_start(&width, &height, &term);
|
||||
|
||||
ui_client_attach(width, height, term);
|
||||
|
||||
// os_exit() will be invoked when the client channel detaches
|
||||
while (true) {
|
||||
|
Loading…
Reference in New Issue
Block a user