fix(tui): resize at startup #17795

* fix(test): screen.lua nil index
  When actual_rows and expected_rows are different avoid a nil index.
* fix(tui): resize at startup
  The deleted code is not needed after 402b4e8.
  It caused the condition to false positive when the function was called
  more than once before startup (first normal mode). Being itself what
  set the dimension and not the user, locking the size of the screen to
  an incorrect size.
  Make got_winch an int to mitigate: tui_grid_resize changing the size
  of the host terminal between the signal handler and the call to
  sigwinch_cb. Since the actual signal handler uv__signal_handle doesn't
  directly call the callback, the event loop does.

Fixes #17285
Fixes #15044
Fixes #11330
This commit is contained in:
Javier Lopez 2022-07-04 15:09:47 -05:00 committed by GitHub
parent ab5929e1b0
commit 1803b0ffd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 19 deletions

View File

@ -137,8 +137,7 @@ struct TUIData {
char *space_buf;
};
static bool got_winch = false;
static bool did_user_set_dimensions = false;
static int got_winch = 0;
static bool cursor_style_enabled = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@ -535,7 +534,7 @@ static void sigcont_cb(SignalWatcher *watcher, int signum, void *data)
static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data)
{
got_winch = true;
got_winch++;
UI *ui = data;
if (tui_is_stopped(ui)) {
return;
@ -987,7 +986,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
r->right = MIN(r->right, grid->width);
}
if (!got_winch && (!data->is_starting || did_user_set_dimensions)) {
if (!got_winch && !data->is_starting) {
// Resize the _host_ terminal.
UNIBI_SET_NUM_VAR(data->params[0], (int)height);
UNIBI_SET_NUM_VAR(data->params[1], (int)width);
@ -997,7 +996,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
reset_scroll_region(ui, ui->width == grid->width);
}
} else { // Already handled the SIGWINCH signal; avoid double-resize.
got_winch = false;
got_winch = got_winch > 0 ? got_winch - 1 : 0;
grid->row = -1;
}
}
@ -1504,23 +1503,13 @@ static void tui_guess_size(UI *ui)
TUIData *data = ui->data;
int width = 0, height = 0;
// 1 - look for non-default 'columns' and 'lines' options during startup
if (data->is_starting && (Columns != DFLT_COLS || Rows != DFLT_ROWS)) {
did_user_set_dimensions = true;
assert(Columns >= 0);
assert(Rows >= 0);
width = Columns;
height = Rows;
goto end;
}
// 2 - try from a system call(ioctl/TIOCGWINSZ on unix)
// 1 - try from a system call(ioctl/TIOCGWINSZ on unix)
if (data->out_isatty
&& !uv_tty_get_winsize(&data->output_handle.tty, &width, &height)) {
goto end;
}
// 3 - use $LINES/$COLUMNS if available
// 2 - use $LINES/$COLUMNS if available
const char *val;
int advance;
if ((val = os_getenv("LINES"))
@ -1530,7 +1519,7 @@ static void tui_guess_size(UI *ui)
goto end;
}
// 4 - read from terminfo if available
// 3 - read from terminfo if available
height = unibi_get_num(data->ut, unibi_lines);
width = unibi_get_num(data->ut, unibi_columns);

View File

@ -85,6 +85,24 @@ describe('TUI', function()
assert_alive()
end)
it('resize at startup', function()
-- Issues: #17285 #15044 #11330
screen:try_resize(50, 10)
feed_command([[call termopen([v:progpath, '--clean', '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile']) | sleep 500m | vs new]])
screen:expect([[
{1: } |
{4:~ }{4:~ }|
{4:~ }{4:~ }|
{4:~ }{4:~ }|
{4:~ }{4:~ }|
{4:~ }{5:[No Name] 0,0-1 All}|
{4:~ } |
{5:new }{MATCH:<.*[/\]nvim }|
|
{3:-- TERMINAL --} |
]])
end)
it('accepts resize while pager is active', function()
child_session:request("nvim_command", [[
set more

View File

@ -383,7 +383,7 @@ function Screen:expect(expected, attr_ids, ...)
for i, row in ipairs(expected_rows) do
msg_expected_rows[i] = row
local m = (row ~= actual_rows[i] and row:match('{MATCH:(.*)}') or nil)
if row ~= actual_rows[i] and (not m or not actual_rows[i]:match(m)) then
if row ~= actual_rows[i] and (not m or not (actual_rows[i] and actual_rows[i]:match(m))) then
msg_expected_rows[i] = '*' .. msg_expected_rows[i]
if i <= #actual_rows then
actual_rows[i] = '*' .. actual_rows[i]