# --------------------------------------------------------------------------- # Statusline element-flicker fix (2026-08-19). # Sourced at the end of ~/.yadr/.tmux.conf, so these override what it sets. # Kept HERE so a yadr re-bootstrap cannot clobber it. # # SYMPTOM dissimulo reported: "the statusbar is having a seizure -- elements # appear and disappear at random." NOT the whole bar blanking (a 30fps screen # recording of the bar showed zero frame-to-frame variation, and a whole-desktop # capture showed nothing changing near it). Individual ELEMENTS winking out. # # CAUSE: `#(...)` in a status format is a tmux JOB. While that job is being # (re)started its expansion is EMPTY, so the element vanishes until it finishes. # tmux re-runs those jobs whenever the status is redrawn and the job is not # already running -- and status redraws are driven by PANE ACTIVITY, not by # `status-interval`. With a busy TUI in the pane (a `claude` session) the jobs # were being restarted several times a second, so the username and the IP # flickered in and out constantly. Measured: `#(whoami)` and `#(tmux-net)` # expanded EMPTY in 30 out of 30 consecutive renders. # # FIX: resolve both into tmux USER OPTIONS and reference those. `#{@user}` and # `#{@net}` are plain variable lookups -- no job, so nothing can ever be # half-started and render empty. Rendered text is byte-identical to before. # @user - a username cannot change within a session: read it ONCE. # @net - the IP CAN change, so refresh on a slow background loop # (4 forks/minute instead of several a second). The loop exits by # itself when tmux goes away, because `tmux set` then fails. # # Bonus, already measured: this also cut the tmux server from ~25% of a core to # ~12% and eliminated the fork churn (17 execs/10s -> 0). # # DO NOT "simplify" #{@user}/#{@net} back to #(whoami)/#(~/.local/bin/tmux-net). # That is the bug, not a tidier way of writing it. # --------------------------------------------------------------------------- run-shell 'tmux set -g @user "$(whoami)"' run-shell 'tmux set -g @net "$($HOME/.local/bin/tmux-net)"' run-shell -b 'while sleep 60; do tmux set -g @net "$($HOME/.local/bin/tmux-net)" 2>/dev/null || exit 0; done' # These lengths are measured against the RAW format string, NOT the rendered # width: tmux applies them as #{T;=/N:status-right}, truncating BEFORE the # #[...] style directives are stripped. status-right renders ~46 columns but is # ~129 characters of source. A cap below the raw length severs the string # mid-way, which looks exactly like 'the right side of the bar disappeared'. # Set here as well as in .tmux.conf so this file stays self-sufficient. set -g status-left-length 451 set -g status-right-length 451 set -g status-left '#[fg=colour235,bg=colour252,bold] ❐ #S #[fg=colour252,bg=colour238,nobold]❯#[fg=colour245,bg=colour238,bold] #{@user} ' # The trailing %S is drawn in bg-on-bg (colour234 on colour234) so it is # INVISIBLE, but it makes the status string CHANGE every second. # # WHY THAT MATTERS -- the second half of the bug: tmux only repaints the status # line when its computed content DIFFERS from what it last drew. With the clock # at minute resolution and @user/@net static, the string was byte-identical for # up to 60s at a stretch; so when anything wiped the bar it STAYED wiped until # the minute rolled over. That is the "sometimes the entire bar disappears" half. # A once-per-second change forces a repaint, so a wipe self-heals within ~1s. # It costs one redraw of one row and NO forks (that is only affordable because # the #() jobs above became #{@user}/#{@net}). set -g status-right '#[bold][#[nobold,fg=colour229]#h#[fg=default] / #[fg=colour229]#{@net}#[fg=default,bold]]#[nobold,fg=colour255] %-I:%M%P %d-%b-%Y #[fg=colour39]★ Stardate %Y.%j#[fg=colour255] ' # ---- circled window numbers, stamped asynchronously ---------------------- # The icon is computed ONCE per window change and stored as a window-level # user option; the format below is a plain #{@icon} lookup. The old version # nested ten #{?#{==:#{window_index},N},...} conditionals evaluated for every # window on every redraw, and redraws follow PANE ACTIVITY, not status-interval. # run-shell -b is backgrounded, so none of this sits on the render path. set -g window-status-format '#[fg=colour235,bg=colour252,nobold] #{?#{@icon},#{@icon},#{window_index}} #{b:pane_current_path} #W ' set -g window-status-current-format '#[fg=colour234,bg=colour39,bold] [#[fg=colour232,bold]#{?window_zoomed_flag,#[fg=colour228],} #{?#{@icon},#{@icon},#{window_index}} #{b:pane_current_path} #W #[fg=colour234,bold]] ' run-shell -b '$HOME/.local/bin/tmux-window-icons' set-hook -g after-new-window 'run-shell -b "$HOME/.local/bin/tmux-window-icons"' set-hook -g window-linked 'run-shell -b "$HOME/.local/bin/tmux-window-icons"' set-hook -g window-unlinked 'run-shell -b "$HOME/.local/bin/tmux-window-icons"' set-hook -g session-window-changed 'run-shell -b "$HOME/.local/bin/tmux-window-icons"'