macos: set background opacity/blur on window controller not surface

This commit is contained in:
Mitchell Hashimoto
2024-06-07 12:31:45 -07:00
parent 6dd88a1bb2
commit 25484d2ccc
5 changed files with 25 additions and 46 deletions

View File

@ -513,7 +513,6 @@ ghostty_surface_config_s ghostty_surface_config_new();
ghostty_surface_t ghostty_surface_new(ghostty_app_t, ghostty_surface_config_s*);
void ghostty_surface_free(ghostty_surface_t);
ghostty_app_t ghostty_surface_app(ghostty_surface_t);
bool ghostty_surface_transparent(ghostty_surface_t);
bool ghostty_surface_needs_confirm_quit(ghostty_surface_t);
void ghostty_surface_refresh(ghostty_surface_t);
void ghostty_surface_draw(ghostty_surface_t);
@ -586,7 +585,7 @@ bool ghostty_inspector_metal_shutdown(ghostty_inspector_t);
// APIs I'd like to get rid of eventually but are still needed for now.
// Don't use these unless you know what you're doing.
void ghostty_set_window_background_blur(ghostty_surface_t, void*);
void ghostty_set_window_background_blur(ghostty_app_t, void*);
#ifdef __cplusplus
}

View File

@ -166,6 +166,16 @@ class TerminalController: NSWindowController, NSWindowDelegate,
private func syncAppearance() {
guard let window = self.window as? TerminalWindow else { return }
// If our window is not visible, then delay this. This is possible specifically
// during state restoration but probably in other scenarios as well. To delay,
// we just loop directly on the dispatch queue. We have to delay because some
// APIs such as window blur have no effect unless the window is visible.
guard window.isVisible else {
// Weak window so that if the window changes or is destroyed we aren't holding a ref
DispatchQueue.main.async { [weak self] in self?.syncAppearance() }
return
}
// Set the font for the window and tab titles.
if let titleFontName = ghostty.config.windowTitleFontFamily {
window.titlebarFont = NSFont(name: titleFontName, size: NSFont.systemFontSize)
@ -173,6 +183,18 @@ class TerminalController: NSWindowController, NSWindowDelegate,
window.titlebarFont = nil
}
// If we have window transparency then set it transparent. Otherwise set it opaque.
if (ghostty.config.backgroundOpacity < 1) {
window.isOpaque = false
window.hasShadow = false
window.backgroundColor = .clear
ghostty_set_window_background_blur(ghostty.app, Unmanaged.passUnretained(window).toOpaque())
} else {
window.isOpaque = true
window.hasShadow = true
window.backgroundColor = .windowBackgroundColor
}
guard window.hasStyledTabs else { return }
// The titlebar is always updated. We don't need to worry about opacity

View File

@ -342,40 +342,6 @@ extension Ghostty {
// MARK: - NSView
override func viewDidMoveToWindow() {
// Set our background blur if requested
setWindowBackgroundBlur(window)
}
/// This function sets the window background to blur if it is configured on the surface.
private func setWindowBackgroundBlur(_ targetWindow: NSWindow?) {
// Surface must desire transparency
guard let surface = self.surface,
ghostty_surface_transparent(surface) else { return }
// Our target should always be our own view window
guard let target = targetWindow,
let window = self.window,
target == window else { return }
// If our window is not visible, then delay this. This is possible specifically
// during state restoration but probably in other scenarios as well. To delay,
// we just loop directly on the dispatch queue.
guard window.isVisible else {
// Weak window so that if the window changes or is destroyed we aren't holding a ref
DispatchQueue.main.async { [weak self, weak window] in self?.setWindowBackgroundBlur(window) }
return
}
// Set the window transparency settings
window.isOpaque = false
window.hasShadow = false
window.backgroundColor = .clear
// If we have a blur, set the blur
ghostty_set_window_background_blur(surface, Unmanaged.passUnretained(window).toOpaque())
}
override func becomeFirstResponder() -> Bool {
let result = super.becomeFirstResponder()
if (result) { focusDidChange(true) }

View File

@ -1474,11 +1474,6 @@ pub const CAPI = struct {
return surface.app;
}
/// Returns true if the surface has transparency set.
export fn ghostty_surface_transparent(surface: *Surface) bool {
return surface.app.config.@"background-opacity" < 1.0;
}
/// Returns true if the surface needs to confirm quitting.
export fn ghostty_surface_needs_confirm_quit(surface: *Surface) bool {
return surface.core_surface.needsConfirmQuit();
@ -1850,13 +1845,13 @@ pub const CAPI = struct {
/// This uses an undocumented, non-public API because this is what
/// every terminal appears to use, including Terminal.app.
export fn ghostty_set_window_background_blur(
ptr: *Surface,
app: *App,
window: *anyopaque,
) void {
// This is only supported on macOS
if (comptime builtin.target.os.tag != .macos) return;
const config = ptr.app.config;
const config = app.config;
// Do nothing if we don't have background transparency enabled
if (config.@"background-opacity" >= 1.0) return;

View File

@ -368,9 +368,6 @@ palette: Palette = .{},
/// The opacity level (opposite of transparency) of the background. A value of
/// 1 is fully opaque and a value of 0 is fully transparent. A value less than 0
/// or greater than 1 will be clamped to the nearest valid value.
///
/// Changing this value at runtime (and reloading config) will only affect new
/// windows, tabs, and splits.
@"background-opacity": f64 = 1.0,
/// A positive value enables blurring of the background when background-opacity