mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #9079 from bfredl/tui_cursor
TUI cursor fixes: avoid memory errors after resize with invalid cursor position
This commit is contained in:
commit
f4b2b66661
@ -88,7 +88,6 @@ typedef struct {
|
|||||||
bool cont_received;
|
bool cont_received;
|
||||||
UGrid grid;
|
UGrid grid;
|
||||||
kvec_t(Rect) invalid_regions;
|
kvec_t(Rect) invalid_regions;
|
||||||
bool did_resize;
|
|
||||||
int row, col;
|
int row, col;
|
||||||
int out_fd;
|
int out_fd;
|
||||||
bool scroll_region_is_full_screen;
|
bool scroll_region_is_full_screen;
|
||||||
@ -577,7 +576,7 @@ static void final_column_wrap(UI *ui)
|
|||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
UGrid *grid = &data->grid;
|
UGrid *grid = &data->grid;
|
||||||
if (grid->col == ui->width) {
|
if (grid->row != -1 && grid->col == ui->width) {
|
||||||
grid->col = 0;
|
grid->col = 0;
|
||||||
if (grid->row < MIN(ui->height, grid->height - 1)) {
|
if (grid->row < MIN(ui->height, grid->height - 1)) {
|
||||||
grid->row++;
|
grid->row++;
|
||||||
@ -647,6 +646,9 @@ static void cursor_goto(UI *ui, int row, int col)
|
|||||||
ugrid_goto(grid, row, col);
|
ugrid_goto(grid, row, col);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (grid->row == -1) {
|
||||||
|
goto safe_move;
|
||||||
|
}
|
||||||
if (0 == col ? col != grid->col :
|
if (0 == col ? col != grid->col :
|
||||||
row != grid->row ? false :
|
row != grid->row ? false :
|
||||||
1 == col ? 2 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
|
1 == col ? 2 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
|
||||||
@ -725,6 +727,8 @@ static void cursor_goto(UI *ui, int row, int col)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safe_move:
|
||||||
unibi_goto(ui, row, col);
|
unibi_goto(ui, row, col);
|
||||||
ugrid_goto(grid, row, col);
|
ugrid_goto(grid, row, col);
|
||||||
}
|
}
|
||||||
@ -773,18 +777,7 @@ static void clear_region(UI *ui, int top, int bot, int left, int right,
|
|||||||
cursor_goto(ui, row, col);
|
cursor_goto(ui, row, col);
|
||||||
print_cell(ui, cell);
|
print_cell(ui, cell);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data->did_resize && top == 0) {
|
|
||||||
// TODO(bfredl): the first line of the screen doesn't gets properly
|
|
||||||
// cleared after resize by the loop above, so redraw the final state
|
|
||||||
// after the next flush.
|
|
||||||
invalidate(ui, 0, bot, left, right);
|
|
||||||
data->did_resize = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore cursor
|
|
||||||
cursor_goto(ui, data->row, data->col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_scroll_region(UI *ui, int top, int bot, int left, int right)
|
static void set_scroll_region(UI *ui, int top, int bot, int left, int right)
|
||||||
@ -808,7 +801,7 @@ static void set_scroll_region(UI *ui, int top, int bot, int left, int right)
|
|||||||
unibi_out(ui, unibi_set_right_margin_parm);
|
unibi_out(ui, unibi_set_right_margin_parm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unibi_goto(ui, grid->row, grid->col);
|
grid->row = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_scroll_region(UI *ui, bool fullwidth)
|
static void reset_scroll_region(UI *ui, bool fullwidth)
|
||||||
@ -836,7 +829,7 @@ static void reset_scroll_region(UI *ui, bool fullwidth)
|
|||||||
}
|
}
|
||||||
unibi_out_ext(ui, data->unibi_ext.disable_lr_margin);
|
unibi_out_ext(ui, data->unibi_ext.disable_lr_margin);
|
||||||
}
|
}
|
||||||
unibi_goto(ui, grid->row, grid->col);
|
grid->row = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
|
static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
|
||||||
@ -844,7 +837,6 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
|
|||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
UGrid *grid = &data->grid;
|
UGrid *grid = &data->grid;
|
||||||
ugrid_resize(grid, (int)width, (int)height);
|
ugrid_resize(grid, (int)width, (int)height);
|
||||||
data->did_resize = true;
|
|
||||||
|
|
||||||
// resize might not always be followed by a clear before flush
|
// resize might not always be followed by a clear before flush
|
||||||
// so clip the invalid region
|
// so clip the invalid region
|
||||||
@ -864,6 +856,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
|
|||||||
}
|
}
|
||||||
} else { // Already handled the SIGWINCH signal; avoid double-resize.
|
} else { // Already handled the SIGWINCH signal; avoid double-resize.
|
||||||
got_winch = false;
|
got_winch = false;
|
||||||
|
grid->row = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,9 +873,10 @@ static void tui_grid_clear(UI *ui, Integer g)
|
|||||||
static void tui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
|
static void tui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
|
||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
|
|
||||||
|
// cursor position is validated in tui_flush
|
||||||
data->row = (int)row;
|
data->row = (int)row;
|
||||||
data->col = (int)col;
|
data->col = (int)col;
|
||||||
cursor_goto(ui, (int)row, (int)col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape tui_cursor_decode_shape(const char *shape_str)
|
CursorShape tui_cursor_decode_shape(const char *shape_str)
|
||||||
@ -1070,7 +1064,6 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
|
|||||||
if (!data->scroll_region_is_full_screen) {
|
if (!data->scroll_region_is_full_screen) {
|
||||||
reset_scroll_region(ui, fullwidth);
|
reset_scroll_region(ui, fullwidth);
|
||||||
}
|
}
|
||||||
cursor_goto(ui, data->row, data->col);
|
|
||||||
|
|
||||||
if (!(data->bce || no_bg(ui, data->clear_attrs))) {
|
if (!(data->bce || no_bg(ui, data->clear_attrs))) {
|
||||||
// Scrolling will leave wrong background in the cleared area on non-BCE
|
// Scrolling will leave wrong background in the cleared area on non-BCE
|
||||||
|
@ -32,7 +32,6 @@ void ugrid_resize(UGrid *grid, int width, int height)
|
|||||||
grid->cells[i] = xcalloc((size_t)width, sizeof(UCell));
|
grid->cells[i] = xcalloc((size_t)width, sizeof(UCell));
|
||||||
}
|
}
|
||||||
|
|
||||||
grid->row = grid->col = 0;
|
|
||||||
grid->width = width;
|
grid->width = width;
|
||||||
grid->height = height;
|
grid->height = height;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ local nvim_prog = helpers.nvim_prog
|
|||||||
local nvim_set = helpers.nvim_set
|
local nvim_set = helpers.nvim_set
|
||||||
local ok = helpers.ok
|
local ok = helpers.ok
|
||||||
local read_file = helpers.read_file
|
local read_file = helpers.read_file
|
||||||
local wait = helpers.wait
|
|
||||||
|
|
||||||
if helpers.pending_win32(pending) then return end
|
if helpers.pending_win32(pending) then return end
|
||||||
|
|
||||||
@ -473,14 +472,24 @@ describe("tui 't_Co' (terminal colors)", function()
|
|||||||
nvim_prog,
|
nvim_prog,
|
||||||
nvim_set))
|
nvim_set))
|
||||||
|
|
||||||
feed_data(":echo &t_Co\n")
|
|
||||||
wait()
|
|
||||||
local tline
|
local tline
|
||||||
if maxcolors == 8 or maxcolors == 16 then
|
if maxcolors == 8 or maxcolors == 16 then
|
||||||
tline = "~ "
|
tline = "~ "
|
||||||
else
|
else
|
||||||
tline = "{4:~ }"
|
tline = "{4:~ }"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
screen:expect(string.format([[
|
||||||
|
{1: } |
|
||||||
|
%s|
|
||||||
|
%s|
|
||||||
|
%s|
|
||||||
|
%s|
|
||||||
|
|
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]], tline, tline, tline, tline))
|
||||||
|
|
||||||
|
feed_data(":echo &t_Co\n")
|
||||||
screen:expect(string.format([[
|
screen:expect(string.format([[
|
||||||
{1: } |
|
{1: } |
|
||||||
%s|
|
%s|
|
||||||
|
Loading…
Reference in New Issue
Block a user