Skip to content

fix: let a user's own tmux work inside a persistent session, and size terminal text on its own (#159) - #170

Merged
kipavy merged 1 commit into
devfrom
fix/tmux-transparency-and-terminal-font-size
Aug 24, 2026
Merged

fix: let a user's own tmux work inside a persistent session, and size terminal text on its own (#159)#170
kipavy merged 1 commit into
devfrom
fix/tmux-transparency-and-terminal-font-size

Conversation

@kipavy

@kipavy kipavy commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Closes #159.

Why tmux looked broken

Persistent sessions (on by default) wrap the remote shell in tmux -L voltius new-session -A -s voltius_<uuid>. tmux exports $TMUX into that shell, and a tmux client given no -L/-S takes its socket from $TMUX. So inside a Voltius session:

  • tmux ls listed Voltius's private sessions (voltius_35917e3f…) instead of the user's own;
  • tmux attach -t <their session> refused with "sessions should be nested with care, unset $TMUX to force";
  • and the wrapper owned C-b, so even a forced nest lost every prefix key.

The reporter's screenshots show exactly this: Termius, which does not wrap, lists their real noa / nb2 / gsuid / ai-shell sessions.

What changed

persistent_exec_command now:

  • prepends unset TMUX TMUX_PANE (screen: unset STY WINDOW) to the pane command, so the shell inside starts with a clean multiplexer environment. Nothing in Voltius reads those back — every control path names the socket and session explicitly;
  • gives up the prefix with prefix None, written into the config file (cold server) and pushed with set -g (a server an earlier session left running, which never re-reads -f). Version-gated to tmux 2.1+, the first release that accepts None as a key name; older tmux keeps C-b but still gets the clean environment.

The wrapper stays invisible: status line off, no prefix, and the user's own tmux behaves as it does over plain ssh.

Terminal font size

The same report asks for a terminal font size independent of the overall UI scale. terminalFontSize existed only as a theme field, editable only in the Theme Creator, so changing it meant cloning a theme or scaling the whole interface.

  • New Terminal Font Size card in Settings → Appearance, overriding the active theme. getActiveTheme folds the override in, so xterm, the CodeMirror editor, --t-terminal-font-size and the theme chip all agree.
  • On mobile, a two-finger pinch on the terminal drives the same value.
  • It is deliberately device-scoped — a size that reads well on a phone does not on a desktop — so it is not in the uiPreferences sync wire.
  • The UI-scale card's stepper is now a shared StepperCard, used by both settings.

Verification

  • cargo test --lib shell_integration: 20/20, including the dropbear payload-length cap.
  • vitest run: 500 files / 3878 tests pass; tsc --noEmit clean.
  • The generated wrapper was rendered and syntax-checked under both dash and bash, and the tmux version gate was table-tested (3.4, 3.5a, 2.1, 2.9aprefix None; 2.0, 1.8, empty → left alone).

Live run

Both halves were driven in the headless dev build, not just compiled.

The wrapper was run against a real tmux 3.7c (installed on the throwaway ssh-host-1), with the payload rendered exactly as persistent_exec_command emits it. Inside the wrapper's pane:

TMUX=[] TMUX_PANE=[]
user tmux ls:      mine: 1 windows (created Mon Aug 24 15:00:47 2026)
voltius socket ls: voltius_probe: 1 windows (attached)
wrapper prefix:    prefix None

The user's own tmux ls now lists their session and not ours, persistence still works on the private socket, and tmux attach -t mine from inside the pane attached — status line drawn, tmux list-clients -t mine reports 1 client — where it used to refuse with "sessions should be nested with care".

In the app: Settings → Appearance shows the new card; stepping it 14 → 20px moved --t-terminal-font-size to 20px and persisted terminalFontSize: 20. With a live local shell open, 12px vs 26px visibly resizes the terminal text (grid refits to 67×21) while the settings modal, sidebar and tab bar stay pixel-identical. Reset returns to the theme's 14px and clears the override; the UI-scale card still steps 100% → 105% → reset after the shared-stepper refactor.

The mobile pinch is covered by unit tests only — no touch device was driven.

… terminal text on its own (#159)

Persistent sessions wrap the remote shell in `tmux -L voltius`, and tmux
exports `$TMUX` into that shell. A tmux client given no `-L`/`-S` takes its
socket from `$TMUX`, so the user's own `tmux ls` listed Voltius's private
sessions instead of theirs and `tmux attach` refused to nest outright. The
wrapper also owned `C-b`, so even a forced nest lost every prefix key.

The pane command now unsets the multiplexer environment (`TMUX`/`TMUX_PANE`,
`STY`/`WINDOW` for screen), and the wrapper gives up its prefix with
`prefix None` — set both in the config file, for a cold server, and with a
`set -g` push, for a server an earlier session left running. The prefix is
version-gated to tmux 2.1+, the first release that accepts `None` as a key;
older tmux keeps `C-b` but still gets the clean environment.

Terminal font size only existed inside a theme, so changing it meant cloning
a theme or scaling the whole UI. It is now a setting of its own in
Appearance, overriding the active theme, and on mobile a two-finger pinch on
the terminal drives the same value. It stays device-scoped: a size that reads
well on a phone does not read well on a desktop, so it is not synced.
@kipavy
kipavy merged commit c881568 into dev Aug 24, 2026
4 checks passed
@kipavy
kipavy deleted the fix/tmux-transparency-and-terminal-font-size branch August 24, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant