mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
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:
@ -184,6 +184,13 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
||||||
window.appearance = appearance
|
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
|
/// 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) {
|
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
|
||||||
}
|
}
|
||||||
@ -305,6 +311,9 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
window.tabGroup?.removeWindow(window)
|
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.
|
// Shows the "+" button in the tab bar, responds to that click.
|
||||||
|
@ -16,6 +16,16 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var titleFont: NSFont? {
|
||||||
|
get {
|
||||||
|
titleTextField.font
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
titleTextField.font = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override init(identifier: NSToolbar.Identifier) {
|
override init(identifier: NSToolbar.Identifier) {
|
||||||
super.init(identifier: identifier)
|
super.init(identifier: identifier)
|
||||||
|
|
||||||
|
@ -8,6 +8,12 @@ class TerminalWindow: NSWindow {
|
|||||||
|
|
||||||
// MARK: - NSWindow
|
// MARK: - NSWindow
|
||||||
|
|
||||||
|
override var title: String {
|
||||||
|
didSet {
|
||||||
|
tab.attributedTitle = attributedTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func becomeKey() {
|
override func becomeKey() {
|
||||||
// This is required because the removeTitlebarAccessoryViewControlle hook does not
|
// 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.
|
// 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 {
|
if titlebarTabs {
|
||||||
updateNewTabButtonOpacity()
|
updateNewTabButtonOpacity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tab.attributedTitle = attributedTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
override func resignKey() {
|
override func resignKey() {
|
||||||
@ -28,6 +36,8 @@ class TerminalWindow: NSWindow {
|
|||||||
if titlebarTabs {
|
if titlebarTabs {
|
||||||
updateNewTabButtonOpacity()
|
updateNewTabButtonOpacity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tab.attributedTitle = attributedTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Titlebar Tabs
|
// 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 windowButtonsBackdrop: WindowButtonsBackdropView? = nil
|
||||||
private var windowDragHandle: WindowDragView? = nil
|
private var windowDragHandle: WindowDragView? = nil
|
||||||
private var storedTitlebarBackgroundColor: CGColor? = nil
|
private var storedTitlebarBackgroundColor: CGColor? = nil
|
||||||
|
@ -198,6 +198,15 @@ extension Ghostty {
|
|||||||
return v
|
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 {
|
var macosTitlebarTabs: Bool {
|
||||||
guard let config = self.config else { return false }
|
guard let config = self.config else { return false }
|
||||||
var v = false;
|
var v = false;
|
||||||
|
@ -603,6 +603,11 @@ keybind: Keybinds = .{},
|
|||||||
/// borders.
|
/// borders.
|
||||||
@"window-decoration": bool = true,
|
@"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:
|
/// The theme to use for the windows. Valid values:
|
||||||
///
|
///
|
||||||
/// * `auto` - Determine the theme based on the configured terminal
|
/// * `auto` - Determine the theme based on the configured terminal
|
||||||
|
Reference in New Issue
Block a user