aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-12-12 20:41:25 +0100
committerJustin M. Keyes <justinkz@gmail.com>2017-12-13 22:18:25 +0100
commited92ece815e1f32259b3f0397476ff6ac92726e3 (patch)
tree5fa2c1231f2afe287f17eef9894dbba96c6637f4
parent6b51c72e0cc99c6c03c521f77793028cf63afd45 (diff)
downloadrneovim-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
-rw-r--r--src/nvim/main.c3
-rw-r--r--src/nvim/tui/tui.c41
-rw-r--r--src/nvim/ui.c8
-rw-r--r--src/nvim/ui.h1
-rw-r--r--src/nvim/ui_bridge.c11
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;