tui.c: request focus-reporting (fix regression) #7670

ref #7649
ref #7664

27f9b1c7b0 caused a regression: it uses loop_schedule_deferred() to
defer emitting the "enable focus reporting" termcode. tui_main() never
processes `tui_loop.events` (which loop_schedule_deferred() depends on),
so the event was never actually processed.

But fixing that (by processing `tui_loop.events`) would bring back the
problem 27f9b1c7b0 tried to fix: it still emits the event too soon.

Instead, do a little dance: schedule the event on `main_loop` and then
forward it to `tui_loop`.

NOTE: after this commit, in tmux 2.3 with `focus-events` enabled,
FocusGained is fired on startup and when resuming from suspend.

Using `script` to record the terminal session (and `vterm-dump` to
post-process the result):

BEFORE:
    {DECSM 1049}{DECSM 1}{ESC =}
    {CUP *}{ED *}{DECSM 2004}{DECSM 1004}{CSI 1,43 r}
    {CUP 1,1}
    {CUP *}{ED *}{SM 34}{DECSM 25}
    {DECRM 25}{CSI 2   q}{CSI 2   q}
    {CUP *}{ED *}{LF}
    {SGR *}{LS1}{SGR 94}~
    ...

AFTER:
    {CUP *}{ED *}{CSI 1,43 r}
    {CUP 1,1}
    {CUP *}{ED *}{SM 34}{DECSM 25}
    {DECRM 25}{CSI 2   q}{CSI 2   q}
    {CUP *}{ED *}{DECSM 2004}{DECSM 1004}{LF}
    {SGR *}{LS1}{SGR 94}~
    ...
This commit is contained in:
Justin M. Keyes 2017-12-02 03:53:23 +01:00
parent 27f9b1c7b0
commit 4b83f37912
2 changed files with 15 additions and 9 deletions

View File

@ -19,12 +19,11 @@ typedef struct loop {
MultiQueue *events;
MultiQueue *thread_events;
// Immediate events:
// "Events that should be processed after exiting uv_run() (to avoid
// recursion), but before returning from loop_poll_events()."
// 502aee690c980fcb3cfcb3f211dcfad06103db46
// Practical consequence: these events are processed by
// "Processed after exiting uv_run() (to avoid recursion), but before
// returning from loop_poll_events()." 502aee690c98
// Practical consequence (for main_loop): these events are processed by
// state_enter()..os_inchar()
// whereas "regular" (main_loop.events) events are processed by
// whereas "regular" events (main_loop.events) are processed by
// state_enter()..VimState.execute()
// But state_enter()..os_inchar() can be "too early" if you want the event
// to trigger UI updates and other user-activity-related side-effects.

View File

@ -169,10 +169,16 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
/// Emits some termcodes after Nvim startup, which were observed to slowdown
/// rendering during startup in tmux 2.3 (+focus-events). #7649
static void terminfo_start_event(void **argv)
static void terminfo_after_startup_event(void **argv)
{
UI *ui = argv[0];
bool defer = argv[1] != NULL; // clever(?) boolean without malloc() dance.
TUIData *data = ui->data;
if (defer) { // We're on the main-loop. Now forward to the TUI loop.
loop_schedule(data->loop,
event_create(terminfo_after_startup_event, 2, ui, NULL));
return;
}
// Enable bracketed paste
unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
// Enable focus reporting
@ -268,6 +274,9 @@ static void terminfo_start(UI *ui)
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
}
loop_schedule(&main_loop,
event_create(terminfo_after_startup_event, 2, ui, ui));
}
static void terminfo_stop(UI *ui)
@ -304,8 +313,6 @@ static void tui_terminal_start(UI *ui)
update_size(ui);
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
term_input_start(&data->input);
loop_schedule_deferred(data->loop,
event_create(terminfo_start_event, 1, ui));
}
static void tui_terminal_stop(UI *ui)
@ -352,7 +359,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
CONTINUE(bridge);
while (!data->stop) {
loop_poll_events(&tui_loop, -1);
loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed
}
ui_bridge_stopped(bridge);