fix(compositor): clear old position with last known dimensions #38229

Problem:  When reconfiguring a float reallocates the grid before the old
          area is cleared, artifacts are left on the screen.
Solution: Use the last known compositor dimensions of a grid when
          clearing the area covered by the old position.

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
luukvbaal
2026-03-11 12:38:18 +01:00
committed by GitHub
parent 63594ffa04
commit e1b3ca6629
2 changed files with 34 additions and 9 deletions

View File

@@ -143,8 +143,6 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
bool moved; bool moved;
grid->pending_comp_index_update = true; grid->pending_comp_index_update = true;
grid->comp_height = height;
grid->comp_width = width;
if (grid->comp_index != 0) { if (grid->comp_index != 0) {
moved = (row != grid->comp_row) || (col != grid->comp_col); moved = (row != grid->comp_row) || (col != grid->comp_col);
if (ui_comp_should_draw()) { if (ui_comp_should_draw()) {
@@ -153,19 +151,19 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
// use it. // use it.
grid->comp_disabled = true; grid->comp_disabled = true;
compose_area(grid->comp_row, row, compose_area(grid->comp_row, row,
grid->comp_col, grid->comp_col + grid->cols); grid->comp_col, grid->comp_col + grid->comp_width);
if (grid->comp_col < col) { if (grid->comp_col < col) {
compose_area(MAX(row, grid->comp_row), compose_area(MAX(row, grid->comp_row),
MIN(row + height, grid->comp_row + grid->rows), MIN(row + height, grid->comp_row + grid->comp_height),
grid->comp_col, col); grid->comp_col, col);
} }
if (col + width < grid->comp_col + grid->cols) { if (col + width < grid->comp_col + grid->comp_width) {
compose_area(MAX(row, grid->comp_row), compose_area(MAX(row, grid->comp_row),
MIN(row + height, grid->comp_row + grid->rows), MIN(row + height, grid->comp_row + grid->comp_height),
col + width, grid->comp_col + grid->cols); col + width, grid->comp_col + grid->comp_width);
} }
compose_area(row + height, grid->comp_row + grid->rows, compose_area(row + height, grid->comp_row + grid->comp_height,
grid->comp_col, grid->comp_col + grid->cols); grid->comp_col, grid->comp_col + grid->comp_width);
grid->comp_disabled = false; grid->comp_disabled = false;
} }
grid->comp_row = row; grid->comp_row = row;
@@ -204,6 +202,9 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
grid->comp_index = insert_at; grid->comp_index = insert_at;
grid->pending_comp_index_update = true; grid->pending_comp_index_update = true;
} }
grid->comp_height = height;
grid->comp_width = width;
if (moved && valid && ui_comp_should_draw()) { if (moved && valid && ui_comp_should_draw()) {
compose_area(grid->comp_row, grid->comp_row + grid->rows, compose_area(grid->comp_row, grid->comp_row + grid->rows,
grid->comp_col, grid->comp_col + grid->cols); grid->comp_col, grid->comp_col + grid->cols);

View File

@@ -1126,6 +1126,30 @@ describe('float window', function()
neq(tp1, api.nvim_win_get_tabpage(w6)) neq(tp1, api.nvim_win_get_tabpage(w6))
end) end)
it('compositor clears old position when configuring reallocates grid #38143', function()
local screen = Screen.new()
local w1 = api.nvim_open_win(0, true, { relative = 'editor', border = 'single', row = 0, col = 0, width = 5, height = 5 })
screen:expect([[
{2:┌─────┐} |
{2:│}{4:^ }{2:│}{1: }|
{2:│}{11:~ }{2:│}{1: }|*4
{2:└─────┘}{1: }|
{1:~ }|*6
|
]])
api.nvim_win_set_config(w1, { relative = 'cursor', row = 1, col = 1, height = 4, width = 4 })
screen:expect([[
|
{1:~ }|
{1:~ }{2:┌────┐}{1: }|
{1:~ }{2:│}{4:^ }{2:│}{1: }|
{1:~ }{2:│}{11:~ }{2:│}{1: }|*3
{1:~ }{2:└────┘}{1: }|
{1:~ }|*5
|
]])
end)
local function with_ext_multigrid(multigrid, send_mouse_grid) local function with_ext_multigrid(multigrid, send_mouse_grid)
local screen, attrs local screen, attrs
before_each(function() before_each(function()