macos: configurable titlebar fonts

Add support for configurable fonts for window and tab titles. This is
only implemented for macOS (and could be macOS-only if other platforms
aren't able to support this using their windowing toolkits). It plays
nicely with regular and titlebar tabs.
This commit is contained in:
Jon Parise
2024-02-08 13:25:54 -08:00
parent 7f59d844c0
commit baf75dfaaf
5 changed files with 78 additions and 3 deletions

View File

@ -184,6 +184,13 @@ class TerminalController: NSWindowController, NSWindowDelegate,
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
window.appearance = appearance
}
// Set the font for the window and tab titles.
if let titleFontName = ghostty.config.windowTitleFontFamily {
window.titlebarFont = NSFont(name: titleFontName, size: NSFont.systemFontSize)
} else {
window.titlebarFont = nil
}
}
/// Update all surfaces with the focus state. This ensures that libghostty has an accurate view about
@ -261,7 +268,6 @@ class TerminalController: NSWindowController, NSWindowDelegate,
if (ghostty.config.macosTitlebarTabs) {
window.tabbingMode = .preferred
window.titlebarTabs = true
syncAppearance()
DispatchQueue.main.async {
window.tabbingMode = .automatic
}
@ -305,6 +311,9 @@ class TerminalController: NSWindowController, NSWindowDelegate,
window.tabGroup?.removeWindow(window)
}
}
// Apply any additional appearance-related properties to the new window.
syncAppearance()
}
// Shows the "+" button in the tab bar, responds to that click.

View File

@ -16,6 +16,16 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
}
}
var titleFont: NSFont? {
get {
titleTextField.font
}
set {
titleTextField.font = newValue
}
}
override init(identifier: NSToolbar.Identifier) {
super.init(identifier: identifier)

View File

@ -8,6 +8,12 @@ class TerminalWindow: NSWindow {
// MARK: - NSWindow
override var title: String {
didSet {
tab.attributedTitle = attributedTitle
}
}
override func becomeKey() {
// This is required because the removeTitlebarAccessoryViewControlle hook does not
// catch the creation of a new window by "tearing off" a tab from a tabbed window.
@ -20,6 +26,8 @@ class TerminalWindow: NSWindow {
if titlebarTabs {
updateNewTabButtonOpacity()
}
tab.attributedTitle = attributedTitle
}
override func resignKey() {
@ -28,6 +36,8 @@ class TerminalWindow: NSWindow {
if titlebarTabs {
updateNewTabButtonOpacity()
}
tab.attributedTitle = attributedTitle
}
// MARK: - Titlebar Tabs
@ -39,6 +49,38 @@ class TerminalWindow: NSWindow {
}
}
// Used to set the titlebar font.
var titlebarFont: NSFont? {
didSet {
titlebarTextField?.font = titlebarFont
tab.attributedTitle = attributedTitle
if let toolbar = toolbar as? TerminalToolbar {
toolbar.titleFont = titlebarFont
}
}
}
// Find the NSTextField responsible for displaying the titlebar's title.
private var titlebarTextField: NSTextField? {
guard let titlebarContainer = contentView?.superview?.subviews
.first(where: { $0.className == "NSTitlebarContainerView" }) else { return nil }
guard let titlebarView = titlebarContainer.subviews
.first(where: { $0.className == "NSTitlebarView" }) else { return nil }
return titlebarView.subviews.first(where: { $0 is NSTextField }) as? NSTextField
}
// Return a styled representation of our title property.
private var attributedTitle: NSAttributedString? {
guard let titlebarFont else { return nil }
let attributes: [NSAttributedString.Key: Any] = [
.font: titlebarFont,
.foregroundColor: isKeyWindow ? NSColor.labelColor : NSColor.secondaryLabelColor,
]
return NSAttributedString(string: title, attributes: attributes)
}
private var windowButtonsBackdrop: WindowButtonsBackdropView? = nil
private var windowDragHandle: WindowDragView? = nil
private var storedTitlebarBackgroundColor: CGColor? = nil

View File

@ -198,6 +198,15 @@ extension Ghostty {
return v
}
var windowTitleFontFamily: String? {
guard let config = self.config else { return nil }
var v: UnsafePointer<Int8>? = nil
let key = "window-title-font-family"
guard ghostty_config_get(config, &v, key, UInt(key.count)) else { return nil }
guard let ptr = v else { return nil }
return String(cString: ptr)
}
var macosTitlebarTabs: Bool {
guard let config = self.config else { return false }
var v = false;

View File

@ -603,6 +603,11 @@ keybind: Keybinds = .{},
/// borders.
@"window-decoration": bool = true,
/// The font that will be used for the application's window and tab titles.
///
/// This is currently only supported on macOS.
@"window-title-font-family": ?[:0]const u8 = null,
/// The theme to use for the windows. Valid values:
///
/// * `auto` - Determine the theme based on the configured terminal