Skip to content

Allow scrollback in the alternate screen via mouse/trackpad (Terminal.app and iTerm2 do) #583

Description

@HookHM

Describe the bug
SwiftTerm hard-disables view-level scrollback whenever the alternate screen buffer is active. canScroll (AppleTerminalView.swift:1815–1822) returns false as soon as terminal.isDisplayBufferAlternate is true, so the user cannot scroll back into the normal buffer with the trackpad/mouse wheel.

Apple's Terminal.app and iTerm2 behave differently: they keep the normal buffer's scrollback accessible via mouse/trackpad scrolling even while the alternate screen is active. This is a long-standing convenience that lets users scroll back into what they were looking at before a full-screen TUI took over the viewport.

The practical impact: when running a TUI app in SwiftTerm, mouse-wheel/trackpad scrolling does nothing — the scroll bar may briefly appear (if the host app forwards the event), but the content does not move.

To Reproduce

  1. Embed a LocalProcessTerminalView in an AppKit/SwiftUI app.
  2. Run a TUI app that switches to the alternate screen — for example Claude Code ≥ V2.1.110 with /tui fullscreen enabled (this mode uses the alternate screen with the app's own virtualized scrollback).
  3. Try to scroll up with the trackpad or mouse wheel.
  4. Observe: nothing scrolls. The same Claude session in Terminal.app under the same /tui fullscreen mode scrolls normally with trackpad/mouse wheel into the previously visible (normal-buffer) content.

Expected behavior
Mouse/trackpad scrolling should remain functional in the alternate screen, navigating the normal buffer's scrollback — matching Terminal.app / iTerm2 behavior.

Screenshots
N/A (scrolling behavior).

Desktop (please complete the following information):

  • OS: macOS 26.5
  • App type: native AppKit/SwiftUI (no browser)
  • SwiftTerm version: 1.13.0

Smartphone (please complete the following information):
N/A

Additional context
Possible direction for a fix: relax canScroll to also allow scrollback while in the alternate screen — or expose a public option (e.g. allowScrollbackInAlternateBuffer) so embedders can opt in to the Terminal.app behavior. The relevant guard is the !terminal.isDisplayBufferAlternate check in canScroll.

Related but distinct: issue #559 (the userScrolling flag is never set, so output snaps the viewport back to the bottom). This issue here is about scrollback being entirely disabled in the alternate screen; #559 is about scrollback being undone by output even when it is available. Different code paths, different fixes — but both are scroll-related gaps relative to Terminal.app / iTerm2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions