mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
When Nvim is started in one terminal emulator,
suspended, and later resumed in a different terminal emulator (as can
happen when using e.g. a multiplexer), the new terminal emulator will
not have all of the same modes enabled that the original terminal
emulator had. This is a problem in particular for in-band resize events
because we were disabling the SIGWINCH signal handler when we determined
that the terminal supported this mode.
However, if the new terminal does not support this mode then the
SIGWINCH handler remains disabled, and Neovim no longer properly
resizes. Instead of disabling the SIGWINCH handler, we track the state
of the resize events mode internally. If the mode is enabled then we
return early from the SIGWINCH handler before performing any ioctls or
other system calls. But if the mode is not enabled we proceed as normal.
(cherry picked from commit b1679f0ab6
)
This commit is contained in:
@@ -113,7 +113,15 @@ struct TUIData {
|
||||
bool set_cursor_color_as_str;
|
||||
bool cursor_has_color;
|
||||
bool is_starting;
|
||||
bool did_set_grapheme_cluster_mode;
|
||||
bool resize_events_enabled;
|
||||
|
||||
// Terminal modes that Nvim enabled that it must disable on exit
|
||||
struct {
|
||||
bool grapheme_clusters : 1;
|
||||
bool theme_updates : 1;
|
||||
bool resize_events : 1;
|
||||
} modes;
|
||||
|
||||
FILE *screenshot;
|
||||
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
|
||||
HlAttrs clear_attrs;
|
||||
@@ -246,15 +254,25 @@ void tui_handle_term_mode(TUIData *tui, TermMode mode, TermModeState state)
|
||||
case kTermModeGraphemeClusters:
|
||||
if (!is_set) {
|
||||
tui_set_term_mode(tui, mode, true);
|
||||
tui->did_set_grapheme_cluster_mode = true;
|
||||
tui->modes.grapheme_clusters = true;
|
||||
}
|
||||
break;
|
||||
case kTermModeThemeUpdates:
|
||||
tui_set_term_mode(tui, mode, true);
|
||||
if (!is_set) {
|
||||
tui_set_term_mode(tui, mode, true);
|
||||
tui->modes.theme_updates = true;
|
||||
}
|
||||
break;
|
||||
case kTermModeResizeEvents:
|
||||
signal_watcher_stop(&tui->winch_handle);
|
||||
tui_set_term_mode(tui, mode, true);
|
||||
if (!is_set) {
|
||||
tui_set_term_mode(tui, mode, true);
|
||||
tui->modes.resize_events = true;
|
||||
}
|
||||
|
||||
// We track both whether the mode is enabled AND if Nvim was the one to enable it
|
||||
tui->resize_events_enabled = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -358,7 +376,10 @@ static void terminfo_start(TUIData *tui)
|
||||
tui->overflow = false;
|
||||
tui->set_cursor_color_as_str = false;
|
||||
tui->cursor_has_color = false;
|
||||
tui->did_set_grapheme_cluster_mode = false;
|
||||
tui->resize_events_enabled = false;
|
||||
tui->modes.grapheme_clusters = false;
|
||||
tui->modes.resize_events = false;
|
||||
tui->modes.theme_updates = false;
|
||||
tui->showing_mode = SHAPE_IDX_N;
|
||||
tui->unibi_ext.enable_mouse = -1;
|
||||
tui->unibi_ext.disable_mouse = -1;
|
||||
@@ -519,7 +540,9 @@ static void terminfo_disable(TUIData *tui)
|
||||
{
|
||||
// Disable theme update notifications. We do this first to avoid getting any
|
||||
// more notifications after we reset the cursor and any color palette changes.
|
||||
tui_set_term_mode(tui, kTermModeThemeUpdates, false);
|
||||
if (tui->modes.theme_updates) {
|
||||
tui_set_term_mode(tui, kTermModeThemeUpdates, false);
|
||||
}
|
||||
|
||||
// Destroy output stuff
|
||||
tui_mode_change(tui, NULL_STRING, SHAPE_IDX_N);
|
||||
@@ -532,9 +555,12 @@ static void terminfo_disable(TUIData *tui)
|
||||
// Reset the key encoding
|
||||
tui_reset_key_encoding(tui);
|
||||
|
||||
// Disable resize events
|
||||
tui_set_term_mode(tui, kTermModeResizeEvents, false);
|
||||
if (tui->did_set_grapheme_cluster_mode) {
|
||||
// Disable terminal modes that we enabled
|
||||
if (tui->modes.resize_events) {
|
||||
tui_set_term_mode(tui, kTermModeResizeEvents, false);
|
||||
}
|
||||
|
||||
if (tui->modes.grapheme_clusters) {
|
||||
tui_set_term_mode(tui, kTermModeGraphemeClusters, false);
|
||||
}
|
||||
|
||||
@@ -680,7 +706,7 @@ static void sigwinch_cb(SignalWatcher *watcher, int signum, void *cbdata)
|
||||
{
|
||||
got_winch++;
|
||||
TUIData *tui = cbdata;
|
||||
if (tui_is_stopped(tui)) {
|
||||
if (tui_is_stopped(tui) || tui->resize_events_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user