Skip to content

terminal: add visibility reports with GTK suspension tracking - #13494

Merged
mitchellh merged 2 commits into
ghostty-org:mainfrom
rockorager:visibility-reports
Jul 28, 2026
Merged

mitchellh merged 2 commits into
ghostty-org:mainfrom
rockorager:visibility-reports

Conversation

@rockorager

Copy link
Copy Markdown
Member

Summary

Applications cannot reliably determine whether an unfocused terminal is still
visible, so focus reports alone are insufficient for avoiding unnecessary
rendering.

This adds terminal visibility reporting by:

  • implementing private mode 2033
  • supporting CSI ? 998 n visibility queries and CSI ? 999 ; Ps n responses
  • reporting effective visibility changes while mode 2033 is enabled
  • preserving host-owned visibility state across terminal resets
  • treating unknown visibility conservatively as potentially visible

On GTK 4.12 and newer, surface visibility now combines widget mapping with the
toplevel suspended state. This allows Ghostty to recognize windows hidden on
another workspace or otherwise known by the compositor to be non-visible.
Older GTK versions retain the existing conservative behavior.

Testing

Added coverage for:

  • mode 2033 support and enable/disable behavior
  • explicit visibility queries
  • immediate reports when enabling the mode
  • visible and non-visible responses
  • visibility persistence across terminal resets
  • suppression of visibility queries in read-only mode

AI disclosure

Amp assisted with the implementation, tests, commit messages, and this pull
request description. I reviewed the resulting changes and understand how they
interact with the terminal, termio, surface, and GTK visibility paths.

Implements: #13451
Reference: https://rockorager.dev/misc/visibility-reports/

@rockorager
rockorager requested review from a team as code owners July 28, 2026 13:27
@ghostty-bot ghostty-bot Bot added the vt Control sequence related label Jul 28, 2026
Comment thread src/apprt/gtk/class/window.zig Outdated
@jcollie

jcollie commented Jul 28, 2026

Copy link
Copy Markdown
Member

Not as part of this PR, but "someone" should really add documentation regarding all of the modes that we support to the Ghostty website.

GTK exposes the Wayland xdg_toplevel suspended state when the
compositor knows a window is not visible. Ghostty previously only used
widget map state, so it could continue rendering a mapped surface on an
inactive workspace or behind other windows.

Combine the mapped and suspended states for surface occlusion and update
all displayed surfaces whenever the toplevel suspension state changes.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019fa965-aa5f-7099-85b4-a9679d2c8bd3
@rockorager
rockorager force-pushed the visibility-reports branch from aaf2bc3 to 5f6a5a4 Compare July 28, 2026 15:49

@tristan957 tristan957 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving the GTK part! I think the motivation for this mode makes a ton of sense. Getting others to buy in is a different story.

@rockorager

Copy link
Copy Markdown
Member Author

Getting others to buy in is a different story.

I've got feedback from Kovid, dnkl, and rapha (rio) that are supportive of this mode. In my view of the terminal world, that's a pretty healthy agreement :)

@mitchellh mitchellh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One request

Comment thread src/terminal/stream_terminal.zig
Applications cannot infer whether an unfocused terminal remains visible, so
focus reports are insufficient for avoiding expensive rendering while a
view is hidden.

Implement private mode 2033 and the visibility query/report sequences.
Track conservative per-surface visibility, report every effective change
while enabled, and always answer explicit queries and mode enables. Keep
view visibility across terminal resets because it is owned by the host,
not terminal state.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019fa965-aa5f-7099-85b4-a9679d2c8bd3
@rockorager
rockorager force-pushed the visibility-reports branch from 5f6a5a4 to 6c8c079 Compare July 28, 2026 16:04
@mitchellh
mitchellh merged commit 03eaa01 into ghostty-org:main Jul 28, 2026
93 checks passed
@github-actions github-actions Bot added this to the 1.4.0 milestone Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

vt Control sequence related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants