diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/tui/input.c | 39 | ||||
-rw-r--r-- | src/nvim/tui/input.h | 1 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 35 | ||||
-rw-r--r-- | src/nvim/tui/tui_defs.h | 1 |
4 files changed, 68 insertions, 8 deletions
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 98dd7b4b45..744d306c06 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -160,12 +160,16 @@ void tinput_init(TermInput *input, Loop *loop) // initialize a timer handle for handling ESC with libtermkey uv_timer_init(&loop->uv, &input->timer_handle); input->timer_handle.data = input; + + uv_timer_init(&loop->uv, &input->bg_query_timer); + input->bg_query_timer.data = input; } void tinput_destroy(TermInput *input) { map_destroy(int, &kitty_key_map); uv_close((uv_handle_t *)&input->timer_handle, NULL); + uv_close((uv_handle_t *)&input->bg_query_timer, NULL); rstream_may_close(&input->read_stream); termkey_destroy(input->tk); } @@ -179,6 +183,7 @@ void tinput_stop(TermInput *input) { rstream_stop(&input->read_stream); uv_timer_stop(&input->timer_handle); + uv_timer_stop(&input->bg_query_timer); } static void tinput_done_event(void **argv) @@ -474,6 +479,13 @@ static void tinput_timer_cb(uv_timer_t *handle) tinput_flush(input); } +static void bg_query_timer_cb(uv_timer_t *handle) + FUNC_ATTR_NONNULL_ALL +{ + TermInput *input = handle->data; + tui_query_bg_color(input->tui_data); +} + /// Handle focus events. /// /// If the upcoming sequence of bytes in the input stream matches the termcode @@ -660,6 +672,33 @@ static void handle_unknown_csi(TermInput *input, const TermKeyKey *key) } } break; + case 'n': + // Device Status Report (DSR) + if (nparams == 2) { + int args[2]; + for (size_t i = 0; i < ARRAY_SIZE(args); i++) { + if (termkey_interpret_csi_param(params[i], &args[i], NULL, NULL) != TERMKEY_RES_KEY) { + return; + } + } + + if (args[0] == 997) { + // Theme update notification + // https://github.com/contour-terminal/contour/blob/master/docs/vt-extensions/color-palette-update-notifications.md + // The second argument tells us whether the OS theme is set to light + // mode or dark mode, but all we care about is the background color of + // the terminal emulator. We query for that with OSC 11 and the response + // is handled by the autocommand created in _defaults.lua. The terminal + // may send us multiple notifications all at once so we use a timer to + // coalesce the queries. + if (uv_timer_get_due_in(&input->bg_query_timer) > 0) { + return; + } + + uv_timer_start(&input->bg_query_timer, bg_query_timer_cb, 100, 0); + } + } + break; default: break; } diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index 4c2baf908e..f6aaff30de 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -32,6 +32,7 @@ typedef struct { TermKey *tk; TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook uv_timer_t timer_handle; + uv_timer_t bg_query_timer; ///< timer used to batch background color queries Loop *loop; RStream read_stream; TUIData *tui_data; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 6e0012096b..603db5b891 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -241,16 +241,19 @@ void tui_handle_term_mode(TUIData *tui, TermMode mode, TermModeState state) tui->unibi_ext.sync = (int)unibi_add_ext_str(tui->ut, "Sync", "\x1b[?2026%?%p1%{1}%-%tl%eh%;"); break; - case kTermModeResizeEvents: - signal_watcher_stop(&tui->winch_handle); - tui_set_term_mode(tui, mode, true); - break; case kTermModeGraphemeClusters: if (!is_set) { tui_set_term_mode(tui, mode, true); tui->did_set_grapheme_cluster_mode = true; } break; + case kTermModeThemeUpdates: + tui_set_term_mode(tui, mode, true); + break; + case kTermModeResizeEvents: + signal_watcher_stop(&tui->winch_handle); + tui_set_term_mode(tui, mode, true); + break; } } } @@ -320,6 +323,18 @@ static void tui_reset_key_encoding(TUIData *tui) } } +/// Write the OSC 11 sequence to the terminal emulator to query the current +/// background color. +/// +/// The response will be handled by the TermResponse autocommand created in +/// _defaults.lua. +void tui_query_bg_color(TUIData *tui) + FUNC_ATTR_NONNULL_ALL +{ + out(tui, S_LEN("\x1b]11;?\x07")); + flush_buf(tui); +} + /// Enable the alternate screen and emit other control sequences to start the TUI. /// /// This is also called when the TUI is resumed after being suspended. We reinitialize all state @@ -438,14 +453,13 @@ static void terminfo_start(TUIData *tui) // Enable bracketed paste unibi_out_ext(tui, tui->unibi_ext.enable_bracketed_paste); - // Query support for mode 2026 (Synchronized Output). Some terminals also - // support an older DCS sequence for synchronized output, but we will only use - // mode 2026. + // Query support for private DEC modes that Nvim can take advantage of. // Some terminals (such as Terminal.app) do not support DECRQM, so skip the query. if (!nsterm) { tui_request_term_mode(tui, kTermModeSynchronizedOutput); - tui_request_term_mode(tui, kTermModeResizeEvents); tui_request_term_mode(tui, kTermModeGraphemeClusters); + tui_request_term_mode(tui, kTermModeThemeUpdates); + tui_request_term_mode(tui, kTermModeResizeEvents); } // Don't use DECRQSS in screen or tmux, as they behave strangely when receiving it. @@ -493,6 +507,10 @@ static void terminfo_start(TUIData *tui) /// Disable the alternate screen and prepare for the TUI to close. static void terminfo_stop(TUIData *tui) { + // Disable theme update notifications. We do this first to avoid getting any + // more notifications after we reset the cursor and any color palette changes. + tui_set_term_mode(tui, kTermModeThemeUpdates, false); + // Destroy output stuff tui_mode_change(tui, NULL_STRING, SHAPE_IDX_N); tui_mouse_off(tui); @@ -509,6 +527,7 @@ static void terminfo_stop(TUIData *tui) if (tui->did_set_grapheme_cluster_mode) { tui_set_term_mode(tui, kTermModeGraphemeClusters, false); } + // May restore old title before exiting alternate screen. tui_set_title(tui, NULL_STRING); if (ui_client_exit_status == 0) { diff --git a/src/nvim/tui/tui_defs.h b/src/nvim/tui/tui_defs.h index bd99d6b0ad..5d6f027bf7 100644 --- a/src/nvim/tui/tui_defs.h +++ b/src/nvim/tui/tui_defs.h @@ -5,6 +5,7 @@ typedef struct TUIData TUIData; typedef enum { kTermModeSynchronizedOutput = 2026, kTermModeGraphemeClusters = 2027, + kTermModeThemeUpdates = 2031, kTermModeResizeEvents = 2048, } TermMode; |