diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2017-12-12 20:41:25 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2017-12-13 22:18:25 +0100 |
commit | ed92ece815e1f32259b3f0397476ff6ac92726e3 (patch) | |
tree | 5fa2c1231f2afe287f17eef9894dbba96c6637f4 /src | |
parent | 6b51c72e0cc99c6c03c521f77793028cf63afd45 (diff) | |
download | rneovim-ed92ece815e1f32259b3f0397476ff6ac92726e3.tar.gz rneovim-ed92ece815e1f32259b3f0397476ff6ac92726e3.tar.bz2 rneovim-ed92ece815e1f32259b3f0397476ff6ac92726e3.zip |
tui: defer termcodes using a timer
With this implementation there is no "jank" during startup.
Using the main_loop in any fashion is janky. Using only the TUI loop
emits the termcodes too soon, or requires bad hacks like counting
tui_flush invocations (9 seems to work).
ref #7664
ref #7649
ref #7664
ref 27f9b1c7b029d8
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/main.c | 3 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 41 | ||||
-rw-r--r-- | src/nvim/ui.c | 8 | ||||
-rw-r--r-- | src/nvim/ui.h | 1 | ||||
-rw-r--r-- | src/nvim/ui_bridge.c | 11 |
5 files changed, 21 insertions, 43 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index 5d826d9524..0346414697 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -563,9 +563,6 @@ int main(int argc, char **argv) (void)eval_has_provider("clipboard"); } - if (!headless_mode) { - ui_builtin_after_startup(); - } TIME_MSG("before starting main loop"); ILOG("starting main loop"); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 0d3a241793..b8f43e9d13 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -70,6 +70,7 @@ typedef struct { UIBridgeData *bridge; Loop *loop; bool stop; + uv_timer_t after_startup_timer; unibi_var_t params[9]; char buf[OUTBUF_SIZE]; size_t bufpos; @@ -126,7 +127,6 @@ UI *tui_start(void) { UI *ui = xcalloc(1, sizeof(UI)); ui->stop = tui_stop; - ui->after_startup = tui_after_startup; ui->rgb = p_tgc; ui->resize = tui_resize; ui->clear = tui_clear; @@ -170,18 +170,6 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, return unibi_run(str, data->params, buf, len); } -/// Emits some termcodes after Nvim startup, which were observed to slowdown -/// rendering during startup in tmux 2.3 (+focus-events). #7649 -static void terminfo_after_startup_event(void **argv) -{ - UI *ui = argv[0]; - TUIData *data = ui->data; - // Enable bracketed paste - unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste); - // Enable focus reporting - unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting); -} - static void termname_set_event(void **argv) { char *termname = argv[0]; @@ -261,6 +249,9 @@ static void terminfo_start(UI *ui) unibi_out(ui, unibi_enter_ca_mode); unibi_out(ui, unibi_keypad_xmit); unibi_out(ui, unibi_clear_screen); + // Enable bracketed paste + unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste); + uv_loop_init(&data->write_loop); if (data->out_isatty) { uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0); @@ -275,13 +266,6 @@ static void terminfo_start(UI *ui) } } -static void tui_after_startup(UI *ui) -{ - TUIData *data = ui->data; - loop_schedule(data->loop, - event_create(terminfo_after_startup_event, 1, ui)); -} - static void terminfo_stop(UI *ui) { TUIData *data = ui->data; @@ -307,6 +291,18 @@ static void terminfo_stop(UI *ui) unibi_destroy(data->ut); } +static void after_startup_timer_cb(uv_timer_t *handle) + FUNC_ATTR_NONNULL_ALL +{ + UI *ui = handle->data; + TUIData *data = ui->data; + uv_timer_stop(&data->after_startup_timer); + + // Emit this after Nvim startup, not during. This works around a tmux + // 2.3 bug(?) which caused slow drawing during startup. #7649 + unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting); +} + static void tui_terminal_start(UI *ui) { TUIData *data = ui->data; @@ -316,6 +312,8 @@ static void tui_terminal_start(UI *ui) update_size(ui); signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH); term_input_start(&data->input); + + uv_timer_start(&data->after_startup_timer, after_startup_timer_cb, 500, 0); } static void tui_terminal_stop(UI *ui) @@ -349,6 +347,8 @@ static void tui_main(UIBridgeData *bridge, UI *ui) #ifdef UNIX signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT); #endif + uv_timer_init(&data->loop->uv, &data->after_startup_timer); + data->after_startup_timer.data = ui; #if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18 data->input.tk_ti_hook_fn = tui_tk_ti_getstr; @@ -367,6 +367,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui) loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed } + uv_close((uv_handle_t *)&data->after_startup_timer, NULL); ui_bridge_stopped(bridge); term_input_destroy(&data->input); signal_watcher_stop(&data->cont_handle); diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 5c8e9380db..81da88c54a 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -138,14 +138,6 @@ void ui_builtin_start(void) #endif } -/// Immediately after VimEnter event. -void ui_builtin_after_startup(void) -{ -#ifdef FEAT_TUI - UI_CALL(after_startup); -#endif -} - void ui_builtin_stop(void) { UI_CALL(stop); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 84d17e9ec2..0e40a1a215 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -36,7 +36,6 @@ struct ui_t { #endif void (*event)(UI *ui, char *name, Array args, bool *args_consumed); void (*stop)(UI *ui); - void (*after_startup)(UI *ui); }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 324d821df5..0a69cf0ecb 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -42,7 +42,6 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->ui = ui; rv->bridge.rgb = ui->rgb; rv->bridge.stop = ui_bridge_stop; - rv->bridge.after_startup = ui_bridge_after_startup; rv->bridge.resize = ui_bridge_resize; rv->bridge.clear = ui_bridge_clear; rv->bridge.eol_clear = ui_bridge_eol_clear; @@ -107,16 +106,6 @@ static void ui_thread_run(void *data) bridge->ui_main(bridge, bridge->ui); } -static void ui_bridge_after_startup(UI *b) -{ - UI_BRIDGE_CALL(b, after_startup, 1, b); -} -static void ui_bridge_after_startup_event(void **argv) -{ - UI *ui = UI(argv[0]); - ui->after_startup(ui); -} - static void ui_bridge_stop(UI *b) { UIBridgeData *bridge = (UIBridgeData *)b; |