feat: add liquid glass background effect support
parent
0f98e3b905
commit
a02364cbef
|
|
@ -44,6 +44,9 @@ class TerminalWindow: NSWindow {
|
|||
true
|
||||
}
|
||||
|
||||
/// Glass effect view for liquid glass background when transparency is enabled
|
||||
private var glassEffectView: NSView?
|
||||
|
||||
/// Gets the terminal controller from the window controller.
|
||||
var terminalController: TerminalController? {
|
||||
windowController as? TerminalController
|
||||
|
|
@ -476,6 +479,11 @@ class TerminalWindow: NSWindow {
|
|||
// Terminal.app more easily.
|
||||
backgroundColor = .white.withAlphaComponent(0.001)
|
||||
|
||||
// Add liquid glass behind terminal content
|
||||
if #available(macOS 26.0, *), derivedConfig.backgroundGlassStyle != "off" {
|
||||
setupGlassLayer()
|
||||
}
|
||||
|
||||
if let appDelegate = NSApp.delegate as? AppDelegate {
|
||||
ghostty_set_window_background_blur(
|
||||
appDelegate.ghostty.app,
|
||||
|
|
@ -484,6 +492,11 @@ class TerminalWindow: NSWindow {
|
|||
} else {
|
||||
isOpaque = true
|
||||
|
||||
// Remove liquid glass when not transparent
|
||||
if #available(macOS 26.0, *) {
|
||||
removeGlassLayer()
|
||||
}
|
||||
|
||||
let backgroundColor = preferredBackgroundColor ?? NSColor(surfaceConfig.backgroundColor)
|
||||
self.backgroundColor = backgroundColor.withAlphaComponent(1)
|
||||
}
|
||||
|
|
@ -562,6 +575,51 @@ class TerminalWindow: NSWindow {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: Glass
|
||||
|
||||
@available(macOS 26.0, *)
|
||||
private func setupGlassLayer() {
|
||||
guard let contentView = contentView else { return }
|
||||
|
||||
// Remove existing glass effect view
|
||||
glassEffectView?.removeFromSuperview()
|
||||
|
||||
// Get the window content view (parent of the NSHostingView)
|
||||
guard let windowContentView = contentView.superview else { return }
|
||||
|
||||
// Create NSGlassEffectView for native glass effect
|
||||
let effectView = NSGlassEffectView()
|
||||
|
||||
// Map Ghostty config to NSGlassEffectView style
|
||||
let glassStyle = derivedConfig.backgroundGlassStyle
|
||||
switch glassStyle {
|
||||
case "regular":
|
||||
effectView.style = NSGlassEffectView.Style.regular
|
||||
case "clear":
|
||||
effectView.style = NSGlassEffectView.Style.clear
|
||||
default:
|
||||
// Should not reach here since we check for "off" before calling setupGlassLayer()
|
||||
return
|
||||
}
|
||||
|
||||
effectView.cornerRadius = 18
|
||||
effectView.tintColor = preferredBackgroundColor
|
||||
|
||||
effectView.frame = windowContentView.bounds
|
||||
effectView.autoresizingMask = [.width, .height]
|
||||
|
||||
// Position BELOW the terminal content to act as background
|
||||
windowContentView.addSubview(effectView, positioned: .below, relativeTo: contentView)
|
||||
glassEffectView = effectView
|
||||
}
|
||||
|
||||
@available(macOS 26.0, *)
|
||||
private func removeGlassLayer() {
|
||||
glassEffectView?.removeFromSuperview()
|
||||
glassEffectView = nil
|
||||
}
|
||||
|
||||
>>>>>>> Conflict 4 of 4 ends
|
||||
// MARK: Config
|
||||
|
||||
struct DerivedConfig {
|
||||
|
|
@ -569,12 +627,14 @@ class TerminalWindow: NSWindow {
|
|||
let backgroundColor: NSColor
|
||||
let backgroundOpacity: Double
|
||||
let macosWindowButtons: Ghostty.MacOSWindowButtons
|
||||
let backgroundGlassStyle: String
|
||||
|
||||
init() {
|
||||
self.title = nil
|
||||
self.backgroundColor = NSColor.windowBackgroundColor
|
||||
self.backgroundOpacity = 1
|
||||
self.macosWindowButtons = .visible
|
||||
self.backgroundGlassStyle = "off"
|
||||
}
|
||||
|
||||
init(_ config: Ghostty.Config) {
|
||||
|
|
@ -582,6 +642,7 @@ class TerminalWindow: NSWindow {
|
|||
self.backgroundColor = NSColor(config.backgroundColor)
|
||||
self.backgroundOpacity = config.backgroundOpacity
|
||||
self.macosWindowButtons = config.macosWindowButtons
|
||||
self.backgroundGlassStyle = config.backgroundGlassStyle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,6 +261,17 @@ extension Ghostty {
|
|||
return MacOSWindowButtons(rawValue: str) ?? defaultValue
|
||||
}
|
||||
|
||||
var backgroundGlassStyle: String {
|
||||
let defaultValue = "off"
|
||||
guard let config = self.config else { return defaultValue }
|
||||
var v: UnsafePointer<Int8>? = nil
|
||||
let key = "background-glass-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 macosTitlebarStyle: String {
|
||||
let defaultValue = "transparent"
|
||||
guard let config = self.config else { return defaultValue }
|
||||
|
|
@ -635,7 +646,7 @@ extension Ghostty.Config {
|
|||
static let title = BellFeatures(rawValue: 1 << 3)
|
||||
static let border = BellFeatures(rawValue: 1 << 4)
|
||||
}
|
||||
|
||||
|
||||
enum MacDockDropBehavior: String {
|
||||
case new_tab = "new-tab"
|
||||
case new_window = "new-window"
|
||||
|
|
|
|||
|
|
@ -950,6 +950,24 @@ palette: Palette = .{},
|
|||
/// doing so.
|
||||
@"background-blur": BackgroundBlur = .false,
|
||||
|
||||
/// The style of the glass effect when `background-opacity` is less than 1
|
||||
/// and the terminal is using a modern glass effect (macOS 26.0+ only).
|
||||
///
|
||||
/// Valid values are:
|
||||
///
|
||||
/// * `off` - No glass effect
|
||||
/// * `regular` - Standard glass effect with some opacity
|
||||
/// * `clear` - Highly transparent glass effect
|
||||
///
|
||||
/// This setting only takes effect on macOS 26.0+ when transparency is enabled
|
||||
/// (`background-opacity` < 1). On older macOS versions or when transparency
|
||||
/// is disabled, this setting has no effect.
|
||||
///
|
||||
/// The default value is `off`.
|
||||
///
|
||||
/// Available since: 1.2.2
|
||||
@"background-glass-style": BackgroundGlassStyle = .off,
|
||||
|
||||
/// The opacity level (opposite of transparency) of an unfocused split.
|
||||
/// Unfocused splits by default are slightly faded out to make it easier to see
|
||||
/// which split is focused. To disable this feature, set this value to 1.
|
||||
|
|
@ -8383,6 +8401,13 @@ pub const BackgroundBlur = union(enum) {
|
|||
}
|
||||
};
|
||||
|
||||
/// See background-glass-style
|
||||
pub const BackgroundGlassStyle = enum {
|
||||
off,
|
||||
regular,
|
||||
clear,
|
||||
};
|
||||
|
||||
/// See window-decoration
|
||||
pub const WindowDecoration = enum(c_int) {
|
||||
auto,
|
||||
|
|
|
|||
Loading…
Reference in New Issue