Introduce termsize_container_t

fish's handling of terminal sizes is currently rather twisted. The
essential problem is that the terminal size may change at any point from a
SIGWINCH, and common_get_{width,height} may modify it and post variable
change events from arbitrary locations.

Tighten up the semantics. Assign responsibility for managing the tty size
to a new class, `termsize_container_t`. Rationalize locking and reentrancy.

Explicitly nail down the relationship between $COLUMNS/$LINES and the tty
size. The new semantics are: whatever changed most recently takes
precendence.
This commit is contained in:
ridiculousfish
2020-06-07 16:05:52 -07:00
parent d5a239e59e
commit 340c8490f6
6 changed files with 314 additions and 8 deletions

View File

@@ -32,6 +32,7 @@
#include "path.h"
#include "proc.h"
#include "reader.h"
#include "termsize.h"
#include "wutil.h" // IWYU pragma: keep
/// Some configuration path environment variables.
@@ -49,10 +50,6 @@ extern char **environ;
static constexpr wchar_t PATH_ARRAY_SEP = L':';
static constexpr wchar_t NONPATH_ARRAY_SEP = L' ';
// Default terminal sizes.
static constexpr size_t DFLT_TERM_COL = 80;
static constexpr size_t DFLT_TERM_ROW = 24;
bool curses_initialized = false;
/// Does the terminal have the "eat_newline_glitch".
@@ -363,10 +360,11 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
}
// Initialize termsize variables.
auto termsize = termsize_container_t::shared().initialize(vars);
if (vars.get(L"COLUMNS").missing_or_empty())
vars.set_one(L"COLUMNS", ENV_GLOBAL, to_string(DFLT_TERM_COL));
vars.set_one(L"COLUMNS", ENV_GLOBAL, to_string(termsize.width));
if (vars.get(L"LINES").missing_or_empty())
vars.set_one(L"LINES", ENV_GLOBAL, to_string(DFLT_TERM_ROW));
vars.set_one(L"LINES", ENV_GLOBAL, to_string(termsize.height));
// Set fish_bind_mode to "default".
vars.set_one(FISH_BIND_MODE_VAR, ENV_GLOBAL, DEFAULT_BIND_MODE);