Skip to content

Instantly share code, notes, and snippets.

@dsanson
Created May 25, 2020 21:21

Revisions

  1. dsanson created this gist May 25, 2020.
    87 changes: 87 additions & 0 deletions fish-kitty-terminal-dimensions.diff
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,87 @@
    --- a/src/common.cpp
    +++ b/src/common.cpp
    @@ -103,7 +103,7 @@ static relaxed_atomic_t<pid_t> initial_fg_process_group{-1};
    /// This struct maintains the current state of the terminal size. It is updated on demand after
    /// receiving a SIGWINCH. Use common_get_width()/common_get_height() to read it lazily.
    static constexpr struct winsize k_invalid_termsize = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
    -static owning_lock<struct winsize> s_termsize{k_invalid_termsize};
    +static relaxed_atomic_t<struct winsize> s_termsize(k_invalid_termsize);

    static relaxed_atomic_bool_t s_termsize_valid{false};

    @@ -1749,8 +1749,9 @@ bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t e
    void invalidate_termsize(bool invalidate_vars) {
    s_termsize_valid = false;
    if (invalidate_vars) {
    - auto termsize = s_termsize.acquire();
    - termsize->ws_col = termsize->ws_row = USHRT_MAX;
    + struct winsize termsize = s_termsize;
    + termsize.ws_col = termsize.ws_row = USHRT_MAX;
    + termsize = s_termsize;
    }
    }

    @@ -1818,42 +1819,27 @@ static void export_new_termsize(struct winsize *new_termsize, env_stack_t &vars)
    #endif
    }

    -/// Get the current termsize, lazily computing it. Return by reference if it changed.
    -static struct winsize get_current_winsize_prim(bool *changed, const environment_t &vars) {
    - auto termsize = s_termsize.acquire();
    - if (s_termsize_valid) return *termsize;
    +/// Updates termsize as needed, and returns a copy of the winsize.
    +struct winsize get_current_winsize() {
    + struct winsize termsize = s_termsize;
    + if (s_termsize_valid) return termsize;

    struct winsize new_termsize = {0, 0, 0, 0};
    #ifdef HAVE_WINSIZE
    errno = 0;
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &new_termsize) != -1 &&
    - new_termsize.ws_col == termsize->ws_col && new_termsize.ws_row == termsize->ws_row) {
    + new_termsize.ws_col == termsize.ws_col && new_termsize.ws_row == termsize.ws_row) {
    s_termsize_valid = true;
    - return *termsize;
    + return termsize;
    }
    #endif
    + auto &vars = env_stack_t::globals();
    validate_new_termsize(&new_termsize, vars);
    - termsize->ws_col = new_termsize.ws_col;
    - termsize->ws_row = new_termsize.ws_row;
    - *changed = true;
    + export_new_termsize(&new_termsize, vars);
    + termsize.ws_col = new_termsize.ws_col;
    + termsize.ws_row = new_termsize.ws_row;
    + s_termsize = termsize;
    s_termsize_valid = true;
    - return *termsize;
    -}
    -
    -/// Updates termsize as needed, and returns a copy of the winsize.
    -struct winsize get_current_winsize() {
    - bool changed = false;
    - auto &vars = env_stack_t::globals();
    - struct winsize termsize = get_current_winsize_prim(&changed, vars);
    - if (changed) {
    - // TODO: this may call us reentrantly through the environment dispatch mechanism. We need to
    - // rationalize this.
    - export_new_termsize(&termsize, vars);
    - // Hack: due to the dispatch the termsize may have just become invalid. Stomp it back to
    - // valid. What a mess.
    - *s_termsize.acquire() = termsize;
    - s_termsize_valid = true;
    - }
    return termsize;
    }

    --- a/src/common.h
    +++ b/src/common.h
    @@ -494,7 +494,6 @@ class owning_lock {

    public:
    owning_lock(Data &&d) : data(std::move(d)) {}
    - owning_lock(const Data &d) : data(d) {}
    owning_lock() : data() {}

    acquired_lock<Data> acquire() { return {lock, &data}; }