mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #1437 from mitchellh/theme-auto
config: add window-theme = auto for automatic choosing based on bg color
This commit is contained in:
@ -377,6 +377,11 @@ class AppDelegate: NSObject,
|
|||||||
// Config could change window appearance
|
// Config could change window appearance
|
||||||
syncAppearance()
|
syncAppearance()
|
||||||
|
|
||||||
|
// Update all of our windows
|
||||||
|
terminalManager.windows.forEach { window in
|
||||||
|
window.controller.configDidReload()
|
||||||
|
}
|
||||||
|
|
||||||
// If we have configuration errors, we need to show them.
|
// If we have configuration errors, we need to show them.
|
||||||
let c = ConfigurationErrorsController.sharedInstance
|
let c = ConfigurationErrorsController.sharedInstance
|
||||||
c.errors = state.config.errors
|
c.errors = state.config.errors
|
||||||
@ -399,6 +404,11 @@ class AppDelegate: NSObject,
|
|||||||
let appearance = NSAppearance(named: .aqua)
|
let appearance = NSAppearance(named: .aqua)
|
||||||
NSApplication.shared.appearance = appearance
|
NSApplication.shared.appearance = appearance
|
||||||
|
|
||||||
|
case "auto":
|
||||||
|
let color = OSColor(ghostty.config.backgroundColor)
|
||||||
|
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
||||||
|
NSApplication.shared.appearance = appearance
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NSApplication.shared.appearance = nil
|
NSApplication.shared.appearance = nil
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,10 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
|
|
||||||
//MARK: - Methods
|
//MARK: - Methods
|
||||||
|
|
||||||
|
func configDidReload() {
|
||||||
|
syncAppearance()
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the accessory view of each tab according to the keyboard
|
/// Update the accessory view of each tab according to the keyboard
|
||||||
/// shortcut that activates it (if any). This is called when the key window
|
/// shortcut that activates it (if any). This is called when the key window
|
||||||
/// changes and when a window is closed.
|
/// changes and when a window is closed.
|
||||||
@ -151,6 +155,20 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
self.relabelTabs()
|
self.relabelTabs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func syncAppearance() {
|
||||||
|
guard let window = self.window as? TerminalWindow else { return }
|
||||||
|
|
||||||
|
// We match the appearance depending on the lightness/darkness of the
|
||||||
|
// background color. We have to do this because our titlebars in tabs inherit
|
||||||
|
// our background color for the focused tab but use the macOS theme for the
|
||||||
|
// rest of the titlebar.
|
||||||
|
if (window.titlebarTabs) {
|
||||||
|
let color = OSColor(ghostty.config.backgroundColor)
|
||||||
|
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
||||||
|
window.appearance = appearance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - NSWindowController
|
//MARK: - NSWindowController
|
||||||
|
|
||||||
override func windowWillLoad() {
|
override func windowWillLoad() {
|
||||||
@ -214,6 +232,7 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
if (ghostty.config.macosTitlebarTabs) {
|
if (ghostty.config.macosTitlebarTabs) {
|
||||||
window.tabbingMode = .preferred
|
window.tabbingMode = .preferred
|
||||||
window.titlebarTabs = true
|
window.titlebarTabs = true
|
||||||
|
syncAppearance()
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
window.tabbingMode = .automatic
|
window.tabbingMode = .automatic
|
||||||
}
|
}
|
||||||
|
@ -59,16 +59,6 @@ class TerminalWindow: NSWindow {
|
|||||||
}) {
|
}) {
|
||||||
toolbarTitleView.isHidden = true
|
toolbarTitleView.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// We match the appearance depending on the lightness/darkness of the
|
|
||||||
// background color. We have to do this because our titlebars in tabs inherit
|
|
||||||
// our background color for the focused tab but use the macOS theme for the
|
|
||||||
// rest of the titlebar.
|
|
||||||
if let appDelegate = NSApp.delegate as? AppDelegate {
|
|
||||||
let color = OSColor(appDelegate.ghostty.config.backgroundColor)
|
|
||||||
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
|
||||||
self.appearance = appearance
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// "expanded" places the toolbar below the titlebar, so setting this style and
|
// "expanded" places the toolbar below the titlebar, so setting this style and
|
||||||
// removing the toolbar ensures that the titlebar will be the default height.
|
// removing the toolbar ensures that the titlebar will be the default height.
|
||||||
|
@ -133,6 +133,14 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
|
|||||||
c.adw_style_manager_set_color_scheme(
|
c.adw_style_manager_set_color_scheme(
|
||||||
style_manager,
|
style_manager,
|
||||||
switch (config.@"window-theme") {
|
switch (config.@"window-theme") {
|
||||||
|
.auto => auto: {
|
||||||
|
const lum = config.background.toTerminalRGB().perceivedLuminance();
|
||||||
|
break :auto if (lum > 0.5)
|
||||||
|
c.ADW_COLOR_SCHEME_PREFER_LIGHT
|
||||||
|
else
|
||||||
|
c.ADW_COLOR_SCHEME_PREFER_DARK;
|
||||||
|
},
|
||||||
|
|
||||||
.system => c.ADW_COLOR_SCHEME_PREFER_LIGHT,
|
.system => c.ADW_COLOR_SCHEME_PREFER_LIGHT,
|
||||||
.dark => c.ADW_COLOR_SCHEME_FORCE_DARK,
|
.dark => c.ADW_COLOR_SCHEME_FORCE_DARK,
|
||||||
.light => c.ADW_COLOR_SCHEME_FORCE_LIGHT,
|
.light => c.ADW_COLOR_SCHEME_FORCE_LIGHT,
|
||||||
|
@ -600,9 +600,13 @@ keybind: Keybinds = .{},
|
|||||||
/// borders.
|
/// borders.
|
||||||
@"window-decoration": bool = true,
|
@"window-decoration": bool = true,
|
||||||
|
|
||||||
/// The theme to use for the windows. The default is `system` which means that
|
/// The theme to use for the windows. Valid values:
|
||||||
/// whatever the system theme is will be used. This can also be set to `light`
|
///
|
||||||
/// or `dark` to force a specific theme regardless of the system settings.
|
/// * `auto` - Determine the theme based on the configured terminal
|
||||||
|
/// background color.
|
||||||
|
/// * `system` - Use the system theme.
|
||||||
|
/// * `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-tabs` is set, the window theme will be
|
||||||
/// automatically set based on the luminosity of the terminal background color.
|
/// automatically set based on the luminosity of the terminal background color.
|
||||||
@ -610,7 +614,7 @@ keybind: Keybinds = .{},
|
|||||||
/// non-terminal windows within Ghostty.
|
/// non-terminal windows within Ghostty.
|
||||||
///
|
///
|
||||||
/// This is currently only supported on macOS and Linux.
|
/// This is currently only supported on macOS and Linux.
|
||||||
@"window-theme": WindowTheme = .system,
|
@"window-theme": WindowTheme = .auto,
|
||||||
|
|
||||||
/// The colorspace to use for the terminal window. The default is `srgb` but
|
/// The colorspace to use for the terminal window. The default is `srgb` but
|
||||||
/// this can also be set to `display-p3` to use the Display P3 colorspace.
|
/// this can also be set to `display-p3` to use the Display P3 colorspace.
|
||||||
@ -3342,6 +3346,7 @@ pub const OSCColorReportFormat = enum {
|
|||||||
|
|
||||||
/// The default window theme.
|
/// The default window theme.
|
||||||
pub const WindowTheme = enum {
|
pub const WindowTheme = enum {
|
||||||
|
auto,
|
||||||
system,
|
system,
|
||||||
light,
|
light,
|
||||||
dark,
|
dark,
|
||||||
|
@ -144,6 +144,17 @@ pub const RGB = struct {
|
|||||||
return std.math.pow(f64, (normalized + 0.055) / 1.055, 2.4);
|
return std.math.pow(f64, (normalized + 0.055) / 1.055, 2.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates "perceived luminance" which is better for determining
|
||||||
|
/// light vs dark.
|
||||||
|
///
|
||||||
|
/// Source: https://www.w3.org/TR/AERT/#color-contrast
|
||||||
|
pub fn perceivedLuminance(self: RGB) f64 {
|
||||||
|
const r_f64: f64 = @floatFromInt(self.r);
|
||||||
|
const g_f64: f64 = @floatFromInt(self.g);
|
||||||
|
const b_f64: f64 = @floatFromInt(self.b);
|
||||||
|
return 0.299 * (r_f64 / 255) + 0.587 * (g_f64 / 255) + 0.114 * (b_f64 / 255);
|
||||||
|
}
|
||||||
|
|
||||||
test "size" {
|
test "size" {
|
||||||
try std.testing.expectEqual(@as(usize, 24), @bitSizeOf(RGB));
|
try std.testing.expectEqual(@as(usize, 24), @bitSizeOf(RGB));
|
||||||
try std.testing.expectEqual(@as(usize, 3), @sizeOf(RGB));
|
try std.testing.expectEqual(@as(usize, 3), @sizeOf(RGB));
|
||||||
|
Reference in New Issue
Block a user