fix(startup): wait for bg detection before user config #37075

Problem:
Automatic background detection sets the background option too late,
which loads colorschemes twice and causes problems when the user's
terminal background doesn't match the default (#32109, #36211, #36416).

Solution:
Use a DA1 query to determine whether the TTY supports OSC 11. Wait for
background detection and setting to complete before processing user
config.

Note: To preserve the existing behavior as much as possible, this triggers
OptionSet manually on VimEnter (since it won't trigger automatically if
we set bg during startup). However, I'm unsure if this behavior is
truly desired given that the documentation says OptionSet is triggered
"After setting an option (except during |startup|)."

Also fixes flickering issue #28667. To check for flickering:

    nvim --clean --cmd "set termguicolors" --cmd "echo \"foo\"" --cmd "sleep 10"

On master, this gives me a black screen for 10 seconds, but on this
branch, the background is dark or light depending on the terminal
background (since the option is now set during startup rather than after
VimEnter).
This commit is contained in:
Kyle
2026-02-27 03:52:52 -06:00
committed by GitHub
parent f45c550f4e
commit 5cbb9d613b
4 changed files with 88 additions and 16 deletions

View File

@@ -726,7 +726,31 @@ static void handle_unknown_csi(TermInput *input, const TermKeyKey *key)
break;
case 'n':
// Device Status Report (DSR)
if (nparams == 2) {
if (nparams == 1) {
// ECMA-48 DSR
// https://ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf
int arg;
if (termkey_interpret_csi_param(params[0], &arg, NULL, NULL) != TERMKEY_RES_KEY) {
return;
}
MAXSIZE_TEMP_ARRAY(args, 2);
ADD_C(args, STATIC_CSTR_AS_OBJ("termresponse"));
StringBuilder response = KV_INITIAL_VALUE;
kv_printf(response, "\x1b[%dn", arg);
ADD_C(args, STRING_OBJ(cbuf_as_string(response.items, response.size)));
rpc_send_event(ui_client_channel_id, "nvim_ui_term_event", args);
kv_destroy(response);
} else if (nparams == 2) {
// Hard to find comprehensive docs on these responses. Some can be found at https://www.xfree86.org/current/ctlseqs.html
// under "Device Status Report (DSR, DEC-specific)"
// - Report Printer status
// - Report User Defined Key status
// - Report Locator status
// When the first parameter is 997, it's a theme update response based on
// contour terminal VT extensions, as described below.
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) {

View File

@@ -337,13 +337,14 @@ static void tui_reset_key_encoding(TUIData *tui)
}
}
/// Write the OSC 11 sequence to the terminal emulator to query the current background color.
/// Write the OSC 11 + DSR sequence to the terminal emulator to query the current
/// background color.
///
/// Response will be handled by the TermResponse handler in _core/defaults.lua.
void tui_query_bg_color(TUIData *tui)
FUNC_ATTR_NONNULL_ALL
{
out(tui, S_LEN("\x1b]11;?\x07"));
out(tui, S_LEN("\x1b]11;?\x07\x1b[5n"));
flush_buf(tui);
}