Finishes #378
Supercedes #4159
This adds a new enum value for `macos-non-native-fullscreen`:
`padded-notch`. This value will add padding to the top of the window to
account for the notch on applicable devices while still hiding the
menu.
This value is preferred over "visible-menu" by some people because for
screens without a notch, the window will take up the full height.
The plan in the future is that we may color the padded area when a notch
is present. In this commit it appears as transparent.
Related to #5361
The fix in 5361 wasn't sufficient since it only applied if our app was
in the foreground. Our quick terminal is a non-activating NSPanel to
allow it to work on any space (fullscreen included). This means that
Ghostty doesn't become the active app when the quick terminal is shown
and another app is in the foreground.
To work around this, we now hide the dock globally when the quick
terminal is shown AND the dock is in a conflicting position. We restore
this state when the quick terminal is hidden, loses focus, or Ghostty is
quit.
Fixes#5328
The dock sits above the level of the quick terminal, and the quick
terminal frame typical includes the dock. Hence, if the dock is visible
and the quick terminal would conflict with it, then part of the terminal
is obscured.
This commit makes the dock autohide if the quick terminal would conflict
with it. The autohide is disabled when the quick terminal is closed.
We can't set our window level above the dock, as this would prevent
things such as input methods from rendering properly in the quick
terminal window.
iTerm2 (the only other macOS terminal I know of that supports a dropdown
mode) frames the terminal around the dock. I think this looks less
aesthetically pleasing and I prefer autohiding the dock instead.
We can introduce a setting to change this behavior if desired later.
Additionally, this commit introduces a mechanism to safely set
app-global presentation options from multiple sources without stepping
on each other.
Two major changes:
1. Hiding uses `NSApp.hide` which hides all windows, preserves tabs, and
yields focus to the next app.
2. Unhiding manually tracks and brings forward only the windows we hid.
Proper focus should be retained.
Fixes#4539
AquaSKK is a Japanese IME (Input Method Editor) for macOS. It uses
keyboard inputs to switch between input modes. I don't know any other
IMEs that do this, but it's possible that there are others. Prior to
this change, the keyboard inputs to switch between input modes were
being sent to the terminal, resulting in erroneous characters being
written.
This change adds a check during keyDown events to see if the input
source changed _during the event_. If it did, we assume an IME captured
it and we don't pass the event to the terminal.
This makes AquaSKK functional in Ghostty.
Fixes#3072
Previously, when `window-theme = auto`, the appearance was delayed
enough on the DispatchQueue that the window was already visible. This
would result in the window appearing with the wrong appearance before
switching to the correct one.
For annoying reasons, we can't set the NSApplication.shared.appearance
in `applicationDidFinishLaunching` because it results in a deadlock with
AppKit.
This commit moves to set the `NSWindow.appearance` in `windowDidLoad`
(and any config sync) to ensure that the appearance is set before the
window is visible.
This is probably the right solution anyways because this allows windows
with different background colors to each have their own distinct
appearance.
Fixes#2516
Those changes mean that when we have one ghostty window in non-native
fullscreen and another ghostty window not in fullscreen switching to not
fullscreen window won't cause appearing menu bar and dock. I think it
looks good:

If we implement detection and make menu bar and dock appear for not
fullscreen window in this case it will cause the fullscreen window to
change its size and will look bad.
Non-native fullscreen works bad with multiple screens in either way.
E.g. switching to a non-native fullscreen window would cause menubar
disappering on another screen or switching to not fullscreen window
would show menu bar over fullscreen window on another screen. I think
nobody would want non-native fullscreen with multiple screens.
Fixes#2840
Related to #2842
This builds on #2842 by missing a key situation: when native fullscreen
is toggled using the menu bar items it doesn't go through our
`FullscreenStyle` machinery so we don't trigger fullscreen change
events.
This commit makes it so that our FullscreenStyle always listens for
native fullscreen change (even in non-native modes) to fire a fullscreen
did change event. This way we can always rely on the event to be fired
when fullscreen changes no matter what.
Fixes#2462
This sets up a listener for screen parameter changes. This only triggers
when a screen is added, removed, or a parameter such as its resolution
changes. This doesn't trigger when a window is simply moved from one
screen to another.
On parameter change, we ensure that the window is within the bounds of
the screen. As an exception, if the window was previously already
outside the bounds of the screen, we don't move it back in.
macOS 12 is officially EOL by Apple and the project only supports
officially supported versions of macOS. Once publicly released, users on
older macOS versions will have to use older released builds.
Fixes#2370
Comparing NSScreens directly was fragile. It appears that AppKit/Cocoa
can return different instances of NSScreen for the same screen for
unknown reasons between calls to windowDidChangeScreen. I don't fully
understand why this happens.
In any case, our comparison was not safe. Instad, we now keep track of
of the CGDirectDisplayID for each screen and compare those instead.
First, this commit modifies libghostty to use a single unified action
dispatch system based on a tagged union versus the one-off callback
system that was previously in place. This change simplifies the code on
both the core and consumer sides of the library. Importantly, as we
introduce new actions, we can now maintain ABI compatibility so long as
our union size does not change (something I don't promise yet).
Second, this moves a lot more of the functions call on a surface into
the action system. This affects all apprts and continues the previous
work of introducing a more unified API for optional surface features.
This was breaking various other features:
- Popovers stopped working
- Split divider drag gestures stopped working
For now we document the top part of the window is draggable... we
can look into removing that limitation later.
This only works on macOS 15 because it uses the new `pointerStyle` API.
I don't have the interest to backport this to older macOS versions but
I'm happy to accept a PR if someone else wants to do it.