Skip to content

macos: add proxy icon hover mode and disabled state#12166

Open
MoonMao42 wants to merge 1 commit intoghostty-org:mainfrom
MoonMao42:proxy-icon-hover
Open

macos: add proxy icon hover mode and disabled state#12166
MoonMao42 wants to merge 1 commit intoghostty-org:mainfrom
MoonMao42:proxy-icon-hover

Conversation

@MoonMao42
Copy link
Copy Markdown

@MoonMao42 MoonMao42 commented Apr 7, 2026

Implements #5919.

Extends macos-titlebar-proxy-icon to three values:

  • visible — always show the proxy icon (old default)
  • hidden — show on hover via NSTrackingArea on the titlebar (new default)
  • disabled — never show, also disables drag-drop and cmd-click path menu

The hover tracking uses NSTrackingArea with .mouseEnteredAndExited on TerminalWindow.titlebarContainer. A cached currentPwdURL is kept separate from representedURL so switching from disabled back to visible/hidden restores the icon without waiting for the next cd.

Config changes apply immediately to open windows through GhosttyConfigDidChange.

Here's what the hover mode looks like:
proxy-icon

AI Usage

Used Claude Opus via Claude Code (GSD workflow) for initial config scaffolding. Swift/AppKit hover implementation written by hand. Codex used for review pass. I understand all the code.

Extend macos-titlebar-proxy-icon from two values (visible/hidden) to
three (visible/hidden/disabled). hidden now means show-on-hover using
NSTrackingArea on the titlebar, matching standard macOS behavior.
disabled completely removes the proxy icon. Default changes from
visible to hidden.

Config changes apply immediately to all open windows via
GhosttyConfigDidChange notification.

Closes ghostty-org#5919
@MoonMao42 MoonMao42 requested a review from a team as a code owner April 7, 2026 15:10
@ghostty-bot ghostty-bot bot added the os/macos label Apr 7, 2026
/// editor, etc.
@"macos-titlebar-proxy-icon": MacTitlebarProxyIcon = .visible,
/// open windows immediately.
@"macos-titlebar-proxy-icon": MacTitlebarProxyIcon = .hidden,
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.

We should not change the default to avoid surprising people that are used to (and perhaps prefer) the current behavior.


var macosTitlebarProxyIcon: MacOSTitlebarProxyIcon {
let defaultValue = MacOSTitlebarProxyIcon.visible
let defaultValue = MacOSTitlebarProxyIcon.hidden
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.

We should not change the default to avoid surprising people that are used to (and perhaps prefer) the current behavior.


init() {
self.macosTitlebarProxyIcon = .visible
self.macosTitlebarProxyIcon = .hidden
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.

We should not change the default to avoid surprising people that are used to (and perhaps prefer) the current behavior.

@MoonMao42
Copy link
Copy Markdown
Author

Always-visible is actually legacy macOS behavior from before Monterey. Since macOS 12 the system default has been hover-to-show — Finder, Xcode, etc. all do this now. Terminal.app still shows it permanently but that's more of a "hasn't been updated" thing than a deliberate choice.

The mapping from old to new: visible = same as before, always show. hidden = hover to show (what macOS does by default since Monterey). disabled = what hidden used to be, completely off.

Defaulting to hidden just matches what the OS does. But if you'd rather not change the default I can keep it at visible, no strong feelings.

@bo2themax
Copy link
Copy Markdown
Member

bo2themax commented Apr 8, 2026

Always-visible is actually legacy macOS behavior from before Monterey. Since macOS 12 the system default has been hover-to-show — Finder, Xcode, etc. all do this now. Terminal.app still shows it permanently but that's more of a "hasn't been updated" thing than a deliberate choice.

The mapping from old to new: visible = same as before, always show. hidden = hover to show (what macOS does by default since Monterey). disabled = what hidden used to be, completely off.

Defaulting to hidden just matches what the OS does. But if you'd rather not change the default I can keep it at visible, no strong feelings.

This is true when there is a toolbar, as I commented in the discussion.
So I would suggest adding an empty toolbar to hidden (hover to show), and removing it otherwise. This would match the system's default behaviour, without the hassle of adding a tracking area ourselves, but titlebarTextField and titlebarContainer may need some tweaks as well, depending on whether there is a toolbar or not.

let toolbar = NSToolbar(identifier: "TerminalToolbar")
self.toolbar = toolbar
toolbarStyle = .unifiedCompact

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants