fix(float): re-sort layers when grid zindex changed #30259

Problem: when zindex is changed in vim.schedule the zindex sort in
layers not changed.

Solution: resort layers when zindex changed.
This commit is contained in:
glepnir 2024-12-12 18:45:57 +08:00 committed by GitHub
parent de794f2d24
commit 17383870dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 140 additions and 0 deletions

View File

@ -101,6 +101,35 @@ bool ui_comp_should_draw(void)
return composed_uis != 0 && valid_screen;
}
/// Raises or lowers the layer, syncing comp_index with zindex.
///
/// This function adjusts the position of a layer in the layers array
/// based on its zindex, either raising or lowering it.
///
/// @param[in] layer_idx Index of the layer to be raised or lowered.
/// @param[in] raise Raise the layer if true, else lower it.
void ui_comp_layers_adjust(size_t layer_idx, bool raise)
{
size_t size = layers.size;
ScreenGrid *layer = layers.items[layer_idx];
if (raise) {
while (layer_idx < size - 1 && layer->zindex > layers.items[layer_idx + 1]->zindex) {
layers.items[layer_idx] = layers.items[layer_idx + 1];
layers.items[layer_idx]->comp_index = layer_idx;
layer_idx++;
}
} else {
while (layer_idx > 0 && layer->zindex < layers.items[layer_idx - 1]->zindex) {
layers.items[layer_idx] = layers.items[layer_idx - 1];
layers.items[layer_idx]->comp_index = layer_idx;
layer_idx--;
}
}
layers.items[layer_idx] = layer;
layer->comp_index = layer_idx;
}
/// Places `grid` at (col,row) position with (width * height) size.
/// Adds `grid` as the top layer if it is a new layer.
///

View File

@ -852,7 +852,13 @@ void ui_ext_win_position(win_T *wp, bool validate)
}
}
bool resort = wp->w_grid_alloc.comp_index != 0
&& wp->w_grid_alloc.zindex != wp->w_config.zindex;
bool raise = resort && wp->w_grid_alloc.zindex < wp->w_config.zindex;
wp->w_grid_alloc.zindex = wp->w_config.zindex;
if (resort) {
ui_comp_layers_adjust(wp->w_grid_alloc.comp_index, raise);
}
if (ui_has(kUIMultigrid)) {
String anchor = cstr_as_string(float_anchor_str[c.anchor]);
if (!c.hide) {

View File

@ -8542,6 +8542,111 @@ describe('float window', function()
|
]]}
end
--
-- Check that floats are positioned correctly after changing the zindexes.
--
command('fclose')
exec_lua([[
local win1, win3 = ...
vim.api.nvim_win_set_config(win1, { zindex = 400, title = 'win_400', title_pos = 'center', border = 'double' })
vim.api.nvim_win_set_config(win3, { zindex = 300, title = 'win_300', title_pos = 'center', border = 'single' })
]], win1, win3)
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
^ |
{0:~ }|*5
## grid 3
|
## grid 4
{5:}{11:win_400}{5:}|
{5:}{7: }{5:}|
{5:}{7:~ }{5:}|*2
{5:}|
## grid 6
{5:}{11:win_300}{5:}|
{5:}{8: }{5:}|
{5:}{8:~ }{5:}|*2
{5:}|
]], float_pos={
[4] = {1001, "NW", 1, 1, 5, true, 400};
[6] = {1003, "NW", 1, 3, 7, true, 300};
}, win_viewport={
[2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
[4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
[6] = {win = 1003, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
}, win_viewport_margins={
[2] = { bottom = 0, left = 0, right = 0, top = 0, win = 1000 },
[4] = { bottom = 1, left = 1, right = 1, top = 1, win = 1001 },
[6] = { bottom = 1, left = 1, right = 1, top = 1, win = 1003 }
}})
else
screen:expect({
grid = [[
^ |
{0:~ }{5:}{11:win_400}{5:}{0: }|
{0:~ }{5:}{7: }{5:}{0: }|
{0:~ }{5:}{7:~ }{5:}{8: }{5:}{0: }|*2
{0:~ }{5:}{8: }{5:}{0: }|
{5:} |
]]
})
end
exec_lua([[
local win1, win3 = ...
vim.api.nvim_win_set_config(win1, { zindex = 100, title='win_100' })
vim.api.nvim_win_set_config(win3, { zindex = 150, title='win_150' })
]], win1, win3)
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
^ |
{0:~ }|*5
## grid 3
|
## grid 4
{5:}{11:win_100}{5:}|
{5:}{7: }{5:}|
{5:}{7:~ }{5:}|*2
{5:}|
## grid 6
{5:}{11:win_150}{5:}|
{5:}{8: }{5:}|
{5:}{8:~ }{5:}|*2
{5:}|
]], float_pos={
[4] = {1001, "NW", 1, 1, 5, true, 100};
[6] = {1003, "NW", 1, 3, 7, true, 150};
}, win_viewport={
[2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
[4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
[6] = {win = 1003, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
}, win_viewport_margins={
[2] = { bottom = 0, left = 0, right = 0, top = 0, win = 1000 },
[4] = { bottom = 1, left = 1, right = 1, top = 1, win = 1001 },
[6] = { bottom = 1, left = 1, right = 1, top = 1, win = 1003 }
}})
else
screen:expect({
grid = [[
^ |
{0:~ }{5:}{11:w}{5:}{11:win_150}{5:}{0: }|
{0:~ }{5:}{7: }{5:}{8: }{5:}{0: }|
{0:~ }{5:}{7:~}{5:}{8:~ }{5:}{0: }|*2
{0:~ }{5:}{0: }|
|
]]
})
end
end)
it('can use winbar', function()