Skip to content

Use the terminal's alternate screen for a full-window pane when clear-on-attach is off - #5580

Open
ejc3 wants to merge 1 commit into
tmux:masterfrom
ejc3:altscreen-upstream
Open

ejc3 wants to merge 1 commit into
tmux:masterfrom
ejc3:altscreen-upstream

Conversation

@ejc3

@ejc3 ejc3 commented Sep 8, 2026

Copy link
Copy Markdown

With clear-on-attach off, a full-screen program in a pane scrolls the terminal's scrollback away. tmux paints the pane's alternate screen onto the terminal's primary screen with line feeds, so every page less shows is scrolled into the terminal's scrollback and stays there after less quits. Paging through a file left 140 rows of it in the scrollback.

This sends smcup to the client when the active pane fills the window, is not in a mode, and enters its alternate screen, and rmcup when it leaves it. The program then draws on the terminal's alternate screen and the terminal restores the primary screen and scrollback itself on exit: 0 rows, with the output from before less intact.

The switch is made in server_client_check_redraw() after the tty is unfrozen, inside the same synchronized update as the redraw that follows, and forces a full redraw since the new screen has no status line. A tty flag, TTY_ALTSCREEN, records it. tty_stop_tty() leaves the alternate screen if the flag is set, so a detach or suspend does not leave the terminal in it, and a reattach while the program is still running enters it again. Both smcup and rmcup must be present, so a terminal with one but not the other is never put on a screen it cannot leave.

No change with clear-on-attach on, in a split, or for programs that do not use the alternate screen. The regress suite gives the same results as the parent commit.

…-on-attach is off

With clear-on-attach off the client terminal keeps its own scrollback on
the primary screen. A full-screen application in a pane, such as less or
vim, then scrolls that scrollback away: tmux paints the pane's alternate
screen with line feeds on the terminal's primary screen.

When the active pane fills the window, is not in a mode, and is in its
alternate screen, emit smcup to the client terminal before redrawing and
rmcup when the pane leaves it. The application draws on the terminal's
alternate screen and the terminal restores its scrollback on exit.

- tmux.h: TTY_ALTSCREEN flag recording that a pane put the terminal in
  its alternate screen.
- server-client.c: reconcile the terminal's alternate screen with the
  pane's in server_client_check_redraw() after the tty is unfrozen and
  before the redraw. Start the synchronized update before the switch so
  it and the redraw are one frame; leave the ACS character set first
  since the terminal saves it with the cursor; redraw everything with
  server_redraw_client() because the new screen has no status line or
  overlay. Require both smcup and rmcup so a terminal with one but not
  the other is never put on a screen it cannot leave.
- tty.c: leave the alternate screen in tty_stop_tty() if TTY_ALTSCREEN is
  set so a detach or suspend does not leave the terminal in it; clear the
  flag in tty_start_tty().
- tmux.1, options-table.c: describe the behaviour under clear-on-attach.

No change when clear-on-attach is on, when the terminal lacks smcup or
rmcup, in a split, or for applications that do not use the alternate
screen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs Work

Development

Successfully merging this pull request may close these issues.

1 participant