a73x

Session switch leaves the previous session's terminal title

open   by a73x

Labels: backlog, client, daily-driver

[claude 2026-08-23] Reported by the operator.

## Symptom

Switch sessions in the CLI wall (`Ctrl-\ n`) and the host terminal's title
bar keeps whatever the LAST session that set a title set. It is not reset
to anything belonging to the session now on screen.

## Why

Chain, as the code stands:

- The switch is demote(A) then promote(B). Promote resizes B's attach from
  0x0 to the terminal, which drives `sendResync` -> `sendSampledStateTo`
  (src/server.zig:3378).
- That sends `term_title` only when the session's engine title is non-empty
  (src/server.zig:3386). Same two rules as `sampleTermTitle`
  (src/server.zig:3125), whose doc comment states the policy outright: an
  empty title is never sent, because "silence is not set it to empty".
- The demote deliberately restores nothing. `wall_teardown`'s note
  (src/interact.zig:594) says a demote leaves the title standing because
  mux cannot read a title back to restore it TO; the wall pushes one title
  (`22;0t`) for its whole life and pops it at exit.

So: session B that never set a title says nothing, nothing is sent, and A's
title stands. Session B that HAS a title is already correct today.

## Direction (not decided)

The "we must not clobber the user's own title" argument is about the HOST
title bar before mux ran. Inside a wall that argument is already spent —
mux pushed the title stack at `wall_setup` and has been setting titles on
sessions' behalf ever since, and the user's own title is on the terminal's
stack and comes back at wall exit. So mux is entitled to a baseline of its
own for a title-less session, e.g. OSC 0 "mux: <session>" written on
promote when the promoted session's title is empty.

Two places it could live: client-side on promote, or daemon-side by making
`sendSampledStateTo` send a session-name default instead of nothing. The
daemon side keeps the one-policy rule (`sampleTermTitle` and `sendResync`
must agree) but changes what a non-wall attach sees too. Decide before
implementing.

## Repro

1. `mux` two sessions; in one run something that sets a title (`vim`), quit
   it or leave it, in the other run nothing that sets a title.
2. `Ctrl-\ n` to the title-less session.
3. Host title bar still reads the other session's title.

Comments

a73x   2026-08-29 12:30

2026-08-29: paths moved in the src/ split — src/server/server.zig (sendSampledStateTo, sampleTermTitle), src/tui/interact.zig (wall_teardown). Behaviour unchanged.