diff --git a/include/ghostty.h b/include/ghostty.h index 99276cf23..c71831efe 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -412,6 +412,7 @@ typedef enum { GHOSTTY_FULLSCREEN_NATIVE, GHOSTTY_FULLSCREEN_NON_NATIVE, GHOSTTY_FULLSCREEN_NON_NATIVE_VISIBLE_MENU, + GHOSTTY_FULLSCREEN_NON_NATIVE_PADDED_NOTCH, } ghostty_action_fullscreen_e; // apprt.action.SecureInput diff --git a/macos/Sources/Features/Terminal/TerminalManager.swift b/macos/Sources/Features/Terminal/TerminalManager.swift index 42e35b90e..2db29aec9 100644 --- a/macos/Sources/Features/Terminal/TerminalManager.swift +++ b/macos/Sources/Features/Terminal/TerminalManager.swift @@ -86,7 +86,7 @@ class TerminalManager { // fullscreen for the logic later in this method. c.toggleFullscreen(mode: .native) - case .nonNative, .nonNativeVisibleMenu: + case .nonNative, .nonNativeVisibleMenu, .nonNativePaddedNotch: // If we're non-native then we have to do it on a later loop // so that the content view is setup. DispatchQueue.main.async { diff --git a/macos/Sources/Ghostty/FullscreenMode+Extension.swift b/macos/Sources/Ghostty/FullscreenMode+Extension.swift index fffd8e84b..0c0bba908 100644 --- a/macos/Sources/Ghostty/FullscreenMode+Extension.swift +++ b/macos/Sources/Ghostty/FullscreenMode+Extension.swift @@ -13,6 +13,9 @@ extension FullscreenMode { case GHOSTTY_FULLSCREEN_NON_NATIVE_VISIBLE_MENU: .nonNativeVisibleMenu + case GHOSTTY_FULLSCREEN_NON_NATIVE_PADDED_NOTCH: + .nonNativePaddedNotch + default: nil } diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index 9c8042c63..22d66a1a8 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -216,6 +216,8 @@ extension Ghostty { .nonNative case "visible-menu": .nonNativeVisibleMenu + case "padded-notch": + .nonNativePaddedNotch default: defaultValue } diff --git a/macos/Sources/Helpers/Fullscreen.swift b/macos/Sources/Helpers/Fullscreen.swift index 320eca013..59865fc9e 100644 --- a/macos/Sources/Helpers/Fullscreen.swift +++ b/macos/Sources/Helpers/Fullscreen.swift @@ -6,6 +6,7 @@ enum FullscreenMode { case native case nonNative case nonNativeVisibleMenu + case nonNativePaddedNotch /// Initializes the fullscreen style implementation for the mode. This will not toggle any /// fullscreen properties. This may fail if the window isn't configured properly for a given @@ -20,6 +21,9 @@ enum FullscreenMode { case .nonNativeVisibleMenu: return NonNativeFullscreenVisibleMenu(window) + + case .nonNativePaddedNotch: + return NonNativeFullscreenPaddedNotch(window) } } } @@ -141,6 +145,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { struct Properties { var hideMenu: Bool = true + var paddedNotch: Bool = false } private var savedState: SavedState? @@ -278,6 +283,9 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { // put an #available check, but it was in a bug fix release so I think // if a bug is reported to Ghostty we can just advise the user to // update. + } else if (properties.paddedNotch) { + // We are hiding the menu, we may need to avoid the notch. + frame.size.height -= screen.safeAreaInsets.top } return frame @@ -349,3 +357,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { class NonNativeFullscreenVisibleMenu: NonNativeFullscreen { override var properties: Properties { Properties(hideMenu: false) } } + +class NonNativeFullscreenPaddedNotch: NonNativeFullscreen { + override var properties: Properties { Properties(paddedNotch: true) } +} diff --git a/src/Surface.zig b/src/Surface.zig index 3bee52196..4f340ee41 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -4201,6 +4201,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool .false => .native, .true => .macos_non_native, .@"visible-menu" => .macos_non_native_visible_menu, + .@"padded-notch" => .macos_non_native_padded_notch, }, ), diff --git a/src/apprt/action.zig b/src/apprt/action.zig index fe2039e52..78f55c8a5 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -385,6 +385,7 @@ pub const Fullscreen = enum(c_int) { /// window. This is much faster to enter and exit than the native mode. macos_non_native, macos_non_native_visible_menu, + macos_non_native_padded_notch, }; pub const SecureInput = enum(c_int) { diff --git a/src/config/Config.zig b/src/config/Config.zig index 802c77e2e..d191de53a 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1819,9 +1819,14 @@ keybind: Keybinds = .{}, /// /// Allowable values are: /// -/// * `visible-menu` - Use non-native macOS fullscreen, keep the menu bar visible /// * `true` - Use non-native macOS fullscreen, hide the menu bar /// * `false` - Use native macOS fullscreen +/// * `visible-menu` - Use non-native macOS fullscreen, keep the menu bar +/// visible +/// * `padded-notch` - Use non-native macOS fullscreen, hide the menu bar, +/// but ensure the window is not obscured by the notch on applicable +/// devices. The area around the notch will remain transparent currently, +/// but in the future we may fill it with the window background color. /// /// Changing this option at runtime works, but will only apply to the next /// time the window is made fullscreen. If a window is already fullscreen, @@ -4095,6 +4100,7 @@ pub const NonNativeFullscreen = enum(c_int) { false, true, @"visible-menu", + @"padded-notch", }; /// Valid values for macos-option-as-alt.