diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index b0c2df1ca..21f5188de 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -269,12 +269,14 @@ class TerminalController: NSWindowController, NSWindowDelegate, // Handle titlebar tabs config option. Something about what we do while setting up the // titlebar tabs interferes with the window restore process unless window.tabbingMode // is set to .preferred, so we set it, and switch back to automatic as soon as we can. - if (ghostty.config.macosTitlebarTabs) { + if (ghostty.config.macosTitlebarStyle == "tabs") { window.tabbingMode = .preferred window.titlebarTabs = true DispatchQueue.main.async { window.tabbingMode = .automatic } + } else if (ghostty.config.macosTitlebarStyle == "transparent") { + window.transparentTabs = true } if window.hasStyledTabs { diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index ce6f25e1e..9e4d3600e 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -175,16 +175,15 @@ class TerminalWindow: NSWindow { var hasStyledTabs: Bool { // If we have titlebar tabs then we always style. guard !titlebarTabs else { return true } - - // This should never happen, but if we don't have a theme set then - // we just style the tabs. Either response here is probably okay. - guard let windowTheme else { return true } - - // We only style if the window theme is auto. Any other specific - // window theme type will always show up as that native theme. - return windowTheme == .auto + + // We style the tabs if they're transparent + return transparentTabs } - + + // Set to true if the background color should bleed through the titlebar/tab bar. + // This only applies to non-titlebar tabs. + var transparentTabs: Bool = false + var hasVeryDarkBackground: Bool { backgroundColor.luminance < 0.05 } diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index 2f455e578..64a627091 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -228,12 +228,14 @@ extension Ghostty { return String(cString: ptr) } - var macosTitlebarTabs: Bool { - guard let config = self.config else { return false } - var v = false; - let key = "macos-titlebar-tabs" - _ = ghostty_config_get(config, &v, key, UInt(key.count)) - return v + var macosTitlebarStyle: String { + let defaultValue = "transparent" + guard let config = self.config else { return defaultValue } + var v: UnsafePointer? = nil + let key = "macos-titlebar-style" + guard ghostty_config_get(config, &v, key, UInt(key.count)) else { return defaultValue } + guard let ptr = v else { return defaultValue } + return String(cString: ptr) } var backgroundColor: Color { diff --git a/src/config/Config.zig b/src/config/Config.zig index cf38788cb..26c5fb9e1 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -662,7 +662,7 @@ keybind: Keybinds = .{}, /// * `light` - Use the light theme regardless of system theme. /// * `dark` - Use the dark theme regardless of system theme. /// -/// On macOS, if `macos-titlebar-tabs` is set, the window theme will be +/// On macOS, if `macos-titlebar-style` is "tabs", the window theme will be /// automatically set based on the luminosity of the terminal background color. /// This only applies to terminal windows. This setting will still apply to /// non-terminal windows within Ghostty. @@ -958,23 +958,30 @@ keybind: Keybinds = .{}, /// @"macos-non-native-fullscreen": NonNativeFullscreen = .false, -/// If `true`, places the tab bar in the titlebar for tabbed windows. +/// The style of the macOS titlebar. Available values are: "native", +/// "transparent", and "tabs". /// -/// When this is true, the titlebar will also always appear even when -/// fullscreen (native fullscreen) with only one tab. This is not considered -/// a bug but if you'd like to improve this behavior then I'm open to it and -/// please contribute to the project. +/// The "native" style uses the native macOS titlebar with zero customization. +/// The titlebar will match your window theme (see `window-theme`). /// -/// This option intercepts the native tab bar view from macOS and forces it to use -/// different positioning. Because of this, it might be buggy or break entirely if -/// macOS changes the way its native tab bar view is constructed or managed. -/// This has been tested on macOS 14. +/// The "transparent" style is the same as "native" but the titlebar will +/// be transparent and allow your window background color to come through. +/// This makes a more seamless window appearance but looks a little less +/// typical for a macOS application and may not work well with all themes. /// -/// For macOS 13 users: saved window state will not restore tabs correctly -/// if this is enabled. macOS 14 does not have this issue. +/// The "tabs" style is a completely custom titlebar that integrates the +/// tab bar into the titlebar. This titlebar always matches the background +/// color of the terminal. There are some limitations to this style: +/// On macOS 13 and below, saved window state will not restore tabs correctly. +/// macOS 14 does not have this issue and any other macOS version has not +/// been tested. /// -/// This option only applies to new windows when changed. -@"macos-titlebar-tabs": bool = false, +/// The default value is "transparent". This is an opinionated choice +/// but its one I think is the most aesthetically pleasing and works in +/// most cases. +/// +/// Changing this option at runtime only applies to new windows. +@"macos-titlebar-style": MacTitlebarStyle = .transparent, /// If `true`, the *Option* key will be treated as *Alt*. This makes terminal /// sequences expecting *Alt* to work properly, but will break Unicode input @@ -3509,6 +3516,13 @@ pub const WindowColorspace = enum { @"display-p3", }; +/// See macos-titlebar-style +pub const MacTitlebarStyle = enum { + native, + transparent, + tabs, +}; + /// See gtk-single-instance pub const GtkSingleInstance = enum { desktop,