aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2021-03-14 08:35:48 +0100
committerGitHub <noreply@github.com>2021-03-14 08:35:48 +0100
commit3c8583e43bcb644d75c17c072ddf6f067439fde1 (patch)
tree5bff3f568eeefe2cdac24bea446dbc6ca6f14e4e
parent314b222c25f1f21713082d3cb17f5fa442a8b3ec (diff)
parent8fe19d9d89d90eed347d9bfeb99446c0f400cca1 (diff)
downloadrneovim-3c8583e43bcb644d75c17c072ddf6f067439fde1.tar.gz
rneovim-3c8583e43bcb644d75c17c072ddf6f067439fde1.tar.bz2
rneovim-3c8583e43bcb644d75c17c072ddf6f067439fde1.zip
Merge pull request #14020 from chentau/float_resize
Update lines after shrinking floating window
-rw-r--r--src/nvim/grid_defs.h8
-rw-r--r--src/nvim/screen.c3
-rw-r--r--src/nvim/ui_compositor.c17
-rw-r--r--src/nvim/window.c2
-rw-r--r--test/functional/ui/float_spec.lua149
5 files changed, 174 insertions, 5 deletions
diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h
index e14aae73d8..752be4f5a8 100644
--- a/src/nvim/grid_defs.h
+++ b/src/nvim/grid_defs.h
@@ -76,6 +76,12 @@ typedef struct {
int comp_row;
int comp_col;
+ // Requested width and height of the grid upon resize. Used by
+ // `ui_compositor` to correctly determine which regions need to
+ // be redrawn.
+ int comp_width;
+ int comp_height;
+
// z-index of the grid. Grids with higher index is draw on top.
// default_grid.comp_index is always zero.
size_t comp_index;
@@ -86,6 +92,6 @@ typedef struct {
} ScreenGrid;
#define SCREEN_GRID_INIT { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, false, \
- false, 0, 0, false, true, 0, 0, 0, false }
+ false, 0, 0, false, true, 0, 0, 0, 0, 0, false }
#endif // NVIM_GRID_DEFS_H
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index aa3a7ae7ed..467cac4f27 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6274,6 +6274,9 @@ retry:
tab_page_click_defs = new_tab_page_click_defs;
tab_page_click_defs_size = Columns;
+ default_grid.comp_height = Rows;
+ default_grid.comp_width = Columns;
+
default_grid.row_offset = 0;
default_grid.col_offset = 0;
default_grid.handle = DEFAULT_GRID_HANDLE;
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index 06efc9fa99..946215d957 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -127,6 +127,9 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
bool valid, bool on_top)
{
bool moved;
+
+ grid->comp_height = height;
+ grid->comp_width = width;
if (grid->comp_index != 0) {
moved = (row != grid->comp_row) || (col != grid->comp_col);
if (ui_comp_should_draw()) {
@@ -334,17 +337,25 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
sattr_T *bg_attrs = &default_grid.attrs[default_grid.line_offset[row]
+(size_t)startcol];
+ int grid_width, grid_height;
while (col < endcol) {
int until = 0;
for (size_t i = 0; i < kv_size(layers); i++) {
ScreenGrid *g = kv_A(layers, i);
- if (g->comp_row > row || row >= g->comp_row + g->Rows
+ // compose_line may have been called after a shrinking operation but
+ // before the resize has actually been applied. Therefore, we need to
+ // first check to see if any grids have pending updates to width/height,
+ // to ensure that we don't accidentally put any characters into `linebuf`
+ // that have been invalidated.
+ grid_width = MIN(g->Columns, g->comp_width);
+ grid_height = MIN(g->Rows, g->comp_height);
+ if (g->comp_row > row || row >= g->comp_row + grid_height
|| g->comp_disabled) {
continue;
}
- if (g->comp_col <= col && col < g->comp_col+g->Columns) {
+ if (g->comp_col <= col && col < g->comp_col + grid_width) {
grid = g;
- until = g->comp_col+g->Columns;
+ until = g->comp_col + grid_width;
} else if (g->comp_col > col) {
until = MIN(until, g->comp_col);
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 7558e0e3ba..aa8d8727e7 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -710,7 +710,7 @@ int win_fdccol_count(win_T *wp)
}
-static void ui_ext_win_position(win_T *wp)
+void ui_ext_win_position(win_T *wp)
{
if (!wp->w_floating) {
ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow,
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 32f9ae030f..3ad14e749e 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -5433,6 +5433,155 @@ describe('floatwin', function()
]])
end
end)
+
+ it("correctly redraws when overlaid windows are resized #13991", function()
+ helpers.source([[
+ let popup_config = {"relative" : "editor",
+ \ "width" : 7,
+ \ "height" : 3,
+ \ "row" : 1,
+ \ "col" : 1,
+ \ "style" : "minimal"}
+
+ let border_config = {"relative" : "editor",
+ \ "width" : 9,
+ \ "height" : 5,
+ \ "row" : 0,
+ \ "col" : 0,
+ \ "style" : "minimal"}
+
+ let popup_buffer = nvim_create_buf(v:false, v:true)
+ let border_buffer = nvim_create_buf(v:false, v:true)
+ let popup_win = nvim_open_win(popup_buffer, v:true, popup_config)
+ let border_win = nvim_open_win(border_buffer, v:false, border_config)
+
+ call nvim_buf_set_lines(popup_buffer, 0, -1, v:true,
+ \ ["long", "longer", "longest"])
+
+ call nvim_buf_set_lines(border_buffer, 0, -1, v:true,
+ \ ["---------", "- -", "- -"])
+ ]])
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {2:^long }|
+ {2:longer }|
+ {2:longest}|
+ ## grid 6
+ {2:---------}|
+ {2:- -}|
+ {2:- -}|
+ {2: }|
+ {2: }|
+ ]], attr_ids={
+ [1] = {foreground = Screen.colors.Blue1, bold = true};
+ [2] = {background = Screen.colors.LightMagenta};
+ }, float_pos={
+ [5] = { {
+ id = 1002
+ }, "NW", 1, 1, 1, true },
+ [6] = { {
+ id = 1003
+ }, "NW", 1, 0, 0, true }
+ }}
+ else
+ screen:expect([[
+ {1:---------} |
+ {1:-^long -}{0: }|
+ {1:-longer -}{0: }|
+ {1: longest }{0: }|
+ {1: }{0: }|
+ {0:~ }|
+ |
+ ]])
+ end
+
+ helpers.source([[
+ let new_popup_config = {"width" : 1, "height" : 3}
+ let new_border_config = {"width" : 3, "height" : 5}
+
+ function! Resize()
+ call nvim_win_set_config(g:popup_win, g:new_popup_config)
+ call nvim_win_set_config(g:border_win, g:new_border_config)
+
+ call nvim_buf_set_lines(g:border_buffer, 0, -1, v:true,
+ \ ["---", "- -", "- -"])
+ endfunction
+
+ nnoremap zz <cmd>call Resize()<cr>
+ ]])
+
+ helpers.feed("zz")
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {2:^l}|
+ {2:o}|
+ {2:n}|
+ ## grid 6
+ {2:---}|
+ {2:- -}|
+ {2:- -}|
+ {2: }|
+ {2: }|
+ ]], attr_ids={
+ [1] = {foreground = Screen.colors.Blue1, bold = true};
+ [2] = {background = Screen.colors.LightMagenta};
+ }, float_pos={
+ [5] = { {
+ id = 1002
+ }, "NW", 1, 1, 1, true },
+ [6] = { {
+ id = 1003
+ }, "NW", 1, 0, 0, true }
+ }}
+ else
+ screen:expect([[
+ {1:---} |
+ {1:-^l-}{0: }|
+ {1:-o-}{0: }|
+ {1: n }{0: }|
+ {1: }{0: }|
+ {0:~ }|
+ |
+ ]])
+ end
+ end)
end
describe('with ext_multigrid', function()