fix(tui): reset clear_region attributes during startup #28713

Problem:  Fix added in #28676 worked accidentally(used variables were
          themselves uninitialized at this point during startup) and
          does not always work.
Solution: Reset attributes when clearing regions during startup.
This commit is contained in:
luukvbaal 2024-05-26 19:54:08 +02:00 committed by GitHub
parent eb37241d38
commit bc63ffcf39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 41 deletions

View File

@ -115,6 +115,7 @@ struct TUIData {
kvec_t(HlAttrs) attrs; kvec_t(HlAttrs) attrs;
int print_attr_id; int print_attr_id;
bool default_attr; bool default_attr;
bool set_default_colors;
bool can_clear_attr; bool can_clear_attr;
ModeShape showing_mode; ModeShape showing_mode;
Integer verbose; Integer verbose;
@ -166,14 +167,6 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb)
tui->seen_error_exit = 0; tui->seen_error_exit = 0;
tui->loop = &main_loop; tui->loop = &main_loop;
tui->url = -1; tui->url = -1;
// Because setting the default colors is delayed until after startup to avoid
// flickering with the default colorscheme background, any flush that happens
// during startup in turn would result in clearing invalidated regions with
// uninitialized attrs(black). Instead initialize clear_attrs with current
// terminal background so that it is at least not perceived as flickering, even
// though it may be different from the colorscheme that is set during startup.
tui->clear_attrs.rgb_bg_color = normal_bg;
tui->clear_attrs.cterm_bg_color = (int16_t)cterm_normal_bg_color;
kv_init(tui->invalid_regions); kv_init(tui->invalid_regions);
kv_init(tui->urlbuf); kv_init(tui->urlbuf);
@ -1016,7 +1009,16 @@ static void clear_region(TUIData *tui, int top, int bot, int left, int right, in
{ {
UGrid *grid = &tui->grid; UGrid *grid = &tui->grid;
update_attrs(tui, attr_id); // Setting the default colors is delayed until after startup to avoid flickering
// with the default colorscheme background. Consequently, any flush that happens
// during startup would result in clearing invalidated regions with zeroed
// clear_attrs, perceived as a black flicker. Reset attributes to clear with
// current terminal background instead(#28667, #28668).
if (tui->set_default_colors) {
update_attrs(tui, attr_id);
} else {
unibi_out(tui, unibi_exit_attribute_mode);
}
// Background is set to the default color and the right edge matches the // Background is set to the default color and the right edge matches the
// screen end, try to use terminal codes for clearing the requested area. // screen end, try to use terminal codes for clearing the requested area.
@ -1419,6 +1421,7 @@ void tui_default_colors_set(TUIData *tui, Integer rgb_fg, Integer rgb_bg, Intege
tui->clear_attrs.cterm_bg_color = (int16_t)cterm_bg; tui->clear_attrs.cterm_bg_color = (int16_t)cterm_bg;
tui->print_attr_id = -1; tui->print_attr_id = -1;
tui->set_default_colors = true;
invalidate(tui, 0, tui->grid.height, 0, tui->grid.width); invalidate(tui, 0, tui->grid.height, 0, tui->grid.width);
} }

View File

@ -2003,38 +2003,39 @@ describe('TUI', function()
]]) ]])
end) end)
it('invalidated regions are cleared with terminal background attr', function() -- #28667, #28668
local screen = Screen.new(50, 10) for _, guicolors in ipairs({ 'notermguicolors', 'termguicolors' }) do
screen:set_default_attr_ids({ [1] = { foreground = Screen.colors.Black } }) it('has no black flicker when clearing regions during startup with ' .. guicolors, function()
screen:attach() local screen = Screen.new(50, 10)
fn.termopen({ screen:attach()
nvim_prog, fn.termopen({
'--clean', nvim_prog,
'--cmd', '--clean',
'set termguicolors', '--cmd',
'--cmd', 'set ' .. guicolors,
'sleep 10', '--cmd',
}, { 'sleep 10',
env = { }, {
VIMRUNTIME = os.getenv('VIMRUNTIME'), env = {
}, VIMRUNTIME = os.getenv('VIMRUNTIME'),
}) },
screen:expect({ })
grid = [[ screen:expect({
{1:^ }| grid = [[
{1: }|*8 ^ |
| |*9
]], ]],
}) intermediate = true,
screen:try_resize(51, 11) })
screen:expect({ screen:try_resize(51, 11)
grid = [[ screen:expect({
{1:^ }| grid = [[
{1: }|*9 ^ |
| |*10
]], ]],
}) })
end) end)
end
it('argv[0] can be overridden #23953', function() it('argv[0] can be overridden #23953', function()
if not exec_lua('return pcall(require, "ffi")') then if not exec_lua('return pcall(require, "ffi")') then