mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: titlebar tab logic shuffling
This commit is contained in:
@ -206,30 +206,16 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
window.center()
|
window.center()
|
||||||
|
|
||||||
// Set the background color of the window
|
// Set the background color of the window
|
||||||
window.backgroundColor = NSColor(self.ghostty.config.backgroundColor)
|
window.backgroundColor = NSColor(ghostty.config.backgroundColor)
|
||||||
|
|
||||||
// Handle titlebar tabs config option
|
// Handle titlebar tabs config option
|
||||||
if (self.ghostty.config.macosTitlebarTabs) {
|
window.titlebarTabs = ghostty.config.macosTitlebarTabs
|
||||||
window.titlebarTabs = true
|
window.setTitlebarBackground(
|
||||||
window.titlebarAppearsTransparent = true
|
window
|
||||||
|
.backgroundColor
|
||||||
// We use the toolbar to anchor our tab bar positions in the titlebar,
|
.withAlphaComponent(ghostty.config.backgroundOpacity)
|
||||||
// so we make sure it's the right size/position, and exists.
|
.cgColor
|
||||||
window.toolbarStyle = .unifiedCompact
|
)
|
||||||
if (window.toolbar == nil) {
|
|
||||||
window.toolbar = NSToolbar(identifier: "Toolbar")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
window.titlebarTabs = false
|
|
||||||
window.titlebarAppearsTransparent = false
|
|
||||||
|
|
||||||
// "expanded" places the toolbar below the titlebar, so setting this style and
|
|
||||||
// removing the toolbar ensures that the titlebar will be the default height.
|
|
||||||
window.toolbarStyle = .expanded
|
|
||||||
if (window.toolbar != nil) {
|
|
||||||
window.toolbar = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize our content view to the SwiftUI root
|
// Initialize our content view to the SwiftUI root
|
||||||
window.contentView = NSHostingView(rootView: TerminalView(
|
window.contentView = NSHostingView(rootView: TerminalView(
|
||||||
@ -237,14 +223,6 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
viewModel: self,
|
viewModel: self,
|
||||||
delegate: self
|
delegate: self
|
||||||
))
|
))
|
||||||
|
|
||||||
// Give the titlebar a custom background color to account for transparent windows.
|
|
||||||
window.setTitlebarBackground(
|
|
||||||
window
|
|
||||||
.backgroundColor
|
|
||||||
.withAlphaComponent(self.ghostty.config.backgroundOpacity)
|
|
||||||
.cgColor
|
|
||||||
)
|
|
||||||
|
|
||||||
// In various situations, macOS automatically tabs new windows. Ghostty handles
|
// In various situations, macOS automatically tabs new windows. Ghostty handles
|
||||||
// its own tabbing so we DONT want this behavior. This detects this scenario and undoes
|
// its own tabbing so we DONT want this behavior. This detects this scenario and undoes
|
||||||
@ -327,10 +305,6 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
|
|
||||||
func windowDidBecomeKey(_ notification: Notification) {
|
func windowDidBecomeKey(_ notification: Notification) {
|
||||||
self.relabelTabs()
|
self.relabelTabs()
|
||||||
|
|
||||||
// Fix for titlebar tabs, see comment on implementation of fixUntabbedWindow for details.
|
|
||||||
guard let window = window as? TerminalWindow else { return }
|
|
||||||
window.fixUntabbedWindow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the window will be encoded. We handle the data encoding here in the
|
// Called when the window will be encoded. We handle the data encoding here in the
|
||||||
|
@ -1,60 +1,89 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
// Passes mouseDown events from this view to window.performDrag so that you can drag the window by it.
|
|
||||||
class WindowDragView: NSView {
|
|
||||||
override public func mouseDown(with event: NSEvent) {
|
|
||||||
// Drag the window for single left clicks, double clicks should bypass the drag handle.
|
|
||||||
if (event.type == .leftMouseDown && event.clickCount == 1) {
|
|
||||||
window?.performDrag(with: event)
|
|
||||||
NSCursor.closedHand.set()
|
|
||||||
} else {
|
|
||||||
super.mouseDown(with: event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func mouseEntered(with event: NSEvent) {
|
|
||||||
super.mouseEntered(with: event)
|
|
||||||
window?.disableCursorRects()
|
|
||||||
NSCursor.openHand.set()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func mouseExited(with event: NSEvent) {
|
|
||||||
super.mouseExited(with: event)
|
|
||||||
window?.enableCursorRects()
|
|
||||||
NSCursor.arrow.set()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func resetCursorRects() {
|
|
||||||
addCursorRect(bounds, cursor: .openHand)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let TabBarController = NSUserInterfaceItemIdentifier("_tabBarController")
|
|
||||||
|
|
||||||
class TerminalWindow: NSWindow {
|
class TerminalWindow: NSWindow {
|
||||||
// Both of these must be true for windows without decorations to be able to
|
// Both of these must be true for windows without decorations to be able to
|
||||||
// still become key/main and receive events.
|
// still become key/main and receive events.
|
||||||
override var canBecomeKey: Bool { return true }
|
override var canBecomeKey: Bool { return true }
|
||||||
override var canBecomeMain: Bool { return true }
|
override var canBecomeMain: Bool { return true }
|
||||||
|
|
||||||
|
// MARK: - NSWindow
|
||||||
|
|
||||||
|
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.
|
||||||
|
if let tabGroup = self.tabGroup, tabGroup.windows.count < 2 {
|
||||||
|
hideCustomTabBarViews()
|
||||||
|
}
|
||||||
|
|
||||||
|
super.becomeKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Titlebar Tabs
|
||||||
|
|
||||||
// Used by the window controller to enable/disable titlebar tabs.
|
// Used by the window controller to enable/disable titlebar tabs.
|
||||||
public var titlebarTabs = false
|
var titlebarTabs = false {
|
||||||
|
didSet {
|
||||||
|
changedTitlebarTabs(to: titlebarTabs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var windowButtonsBackdrop: NSView? = nil
|
||||||
|
private var windowDragHandle: WindowDragView? = nil
|
||||||
|
|
||||||
|
// The tab bar controller ID from macOS
|
||||||
|
static private let TabBarController = NSUserInterfaceItemIdentifier("_tabBarController")
|
||||||
|
|
||||||
|
/// This is called by titlebarTabs changing so that we can setup the rest of our window
|
||||||
|
private func changedTitlebarTabs(to newValue: Bool) {
|
||||||
|
self.titlebarAppearsTransparent = newValue
|
||||||
|
|
||||||
|
if (newValue) {
|
||||||
|
// We use the toolbar to anchor our tab bar positions in the titlebar,
|
||||||
|
// so we make sure it's the right size/position, and exists.
|
||||||
|
self.toolbarStyle = .unifiedCompact
|
||||||
|
if (self.toolbar == nil) {
|
||||||
|
self.toolbar = NSToolbar(identifier: "Toolbar")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// "expanded" places the toolbar below the titlebar, so setting this style and
|
||||||
|
// removing the toolbar ensures that the titlebar will be the default height.
|
||||||
|
self.toolbarStyle = .expanded
|
||||||
|
self.toolbar = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign a background color to the titlebar area.
|
||||||
|
func setTitlebarBackground(_ color: CGColor) {
|
||||||
|
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
||||||
|
$0.className == "NSTitlebarContainerView"
|
||||||
|
}) else { return }
|
||||||
|
|
||||||
|
titlebarContainer.wantsLayer = true
|
||||||
|
titlebarContainer.layer?.backgroundColor = color
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is called by macOS for native tabbing in order to add the tab bar. We hook into
|
||||||
|
// this, detect the tab bar being added, and override its behavior.
|
||||||
override func addTitlebarAccessoryViewController(_ childViewController: NSTitlebarAccessoryViewController) {
|
override func addTitlebarAccessoryViewController(_ childViewController: NSTitlebarAccessoryViewController) {
|
||||||
var isTabBar = false
|
let isTabBar = self.titlebarTabs && (
|
||||||
if (self.titlebarTabs && (
|
childViewController.layoutAttribute == .bottom ||
|
||||||
childViewController.layoutAttribute == .bottom ||
|
childViewController.identifier == Self.TabBarController
|
||||||
childViewController.identifier == TabBarController)
|
)
|
||||||
) {
|
|
||||||
// Ensure it has the right layoutAttribute
|
if (isTabBar) {
|
||||||
childViewController.layoutAttribute = .right
|
// Ensure it has the right layoutAttribute to force it next to our titlebar
|
||||||
// Hide the title text if the tab bar is showing.
|
childViewController.layoutAttribute = .right
|
||||||
|
|
||||||
|
// Hide the title text if the tab bar is showing since we show it in the tab
|
||||||
titleVisibility = .hidden
|
titleVisibility = .hidden
|
||||||
// Mark the controller for future reference (it gets re-used sometimes)
|
|
||||||
childViewController.identifier = TabBarController
|
// Mark the controller for future reference so we can easily find it. Otherwise
|
||||||
isTabBar = true
|
// the tab bar has no ID by default.
|
||||||
|
childViewController.identifier = Self.TabBarController
|
||||||
}
|
}
|
||||||
|
|
||||||
super.addTitlebarAccessoryViewController(childViewController)
|
super.addTitlebarAccessoryViewController(childViewController)
|
||||||
|
|
||||||
if (isTabBar) {
|
if (isTabBar) {
|
||||||
pushTabsToTitlebar(childViewController)
|
pushTabsToTitlebar(childViewController)
|
||||||
}
|
}
|
||||||
@ -63,103 +92,35 @@ class TerminalWindow: NSWindow {
|
|||||||
override func removeTitlebarAccessoryViewController(at index: Int) {
|
override func removeTitlebarAccessoryViewController(at index: Int) {
|
||||||
let childViewController = titlebarAccessoryViewControllers[index]
|
let childViewController = titlebarAccessoryViewControllers[index]
|
||||||
super.removeTitlebarAccessoryViewController(at: index)
|
super.removeTitlebarAccessoryViewController(at: index)
|
||||||
if (childViewController.layoutAttribute == .right) {
|
if (childViewController.identifier == Self.TabBarController) {
|
||||||
hideCustomTabBarViews()
|
hideCustomTabBarViews()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a hack - provide a function for the window controller to call in windowDidBecomeKey
|
// To be called immediately after the tab bar is disabled.
|
||||||
// to check if it's no longer tabbed and fix its appearing if so. This is required because the
|
private func hideCustomTabBarViews() {
|
||||||
// removeTitlebarAccessoryViewControlle hook does not catch the creation of a new window by
|
// Hide the window buttons backdrop.
|
||||||
// "tearing off" a tab from a tabbed window.
|
windowButtonsBackdrop?.isHidden = true
|
||||||
public func fixUntabbedWindow() {
|
|
||||||
if let tabGroup = self.tabGroup, tabGroup.windows.count < 2 {
|
// Hide the window drag handle.
|
||||||
hideCustomTabBarViews()
|
windowDragHandle?.isHidden = true
|
||||||
}
|
|
||||||
}
|
// Enable the window title text.
|
||||||
|
titleVisibility = .visible
|
||||||
// Assign a background color to the titlebar area.
|
}
|
||||||
public func setTitlebarBackground(_ color: CGColor) {
|
|
||||||
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
|
||||||
$0.className == "NSTitlebarContainerView"
|
|
||||||
}) else { return }
|
|
||||||
|
|
||||||
titlebarContainer.wantsLayer = true
|
|
||||||
titlebarContainer.layer?.backgroundColor = color
|
|
||||||
}
|
|
||||||
|
|
||||||
private var windowButtonsBackdrop: NSView? = nil
|
|
||||||
|
|
||||||
private func addWindowButtonsBackdrop(titlebarView: NSView, toolbarView: NSView) {
|
|
||||||
guard windowButtonsBackdrop == nil else { return }
|
|
||||||
|
|
||||||
windowButtonsBackdrop = NSView()
|
|
||||||
|
|
||||||
guard let windowButtonsBackdrop = windowButtonsBackdrop else { return }
|
|
||||||
|
|
||||||
windowButtonsBackdrop.identifier = NSUserInterfaceItemIdentifier("_windowButtonsBackdrop")
|
|
||||||
titlebarView.addSubview(windowButtonsBackdrop)
|
|
||||||
windowButtonsBackdrop.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
windowButtonsBackdrop.leftAnchor.constraint(equalTo: toolbarView.leftAnchor).isActive = true
|
|
||||||
windowButtonsBackdrop.rightAnchor.constraint(equalTo: toolbarView.leftAnchor, constant: 80).isActive = true
|
|
||||||
windowButtonsBackdrop.topAnchor.constraint(equalTo: toolbarView.topAnchor).isActive = true
|
|
||||||
windowButtonsBackdrop.heightAnchor.constraint(equalTo: toolbarView.heightAnchor).isActive = true
|
|
||||||
windowButtonsBackdrop.wantsLayer = true
|
|
||||||
windowButtonsBackdrop.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.45)
|
|
||||||
|
|
||||||
let topBorder = NSView()
|
|
||||||
windowButtonsBackdrop.addSubview(topBorder)
|
|
||||||
topBorder.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
topBorder.leftAnchor.constraint(equalTo: windowButtonsBackdrop.leftAnchor).isActive = true
|
|
||||||
topBorder.rightAnchor.constraint(equalTo: windowButtonsBackdrop.rightAnchor).isActive = true
|
|
||||||
topBorder.topAnchor.constraint(equalTo: windowButtonsBackdrop.topAnchor).isActive = true
|
|
||||||
topBorder.bottomAnchor.constraint(equalTo: windowButtonsBackdrop.topAnchor, constant: 1).isActive = true
|
|
||||||
topBorder.wantsLayer = true
|
|
||||||
topBorder.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.85)
|
|
||||||
}
|
|
||||||
|
|
||||||
var windowDragHandle: WindowDragView? = nil
|
|
||||||
|
|
||||||
private func addWindowDragHandle(titlebarView: NSView, toolbarView: NSView) {
|
|
||||||
guard windowDragHandle == nil else { return }
|
|
||||||
|
|
||||||
windowDragHandle = WindowDragView()
|
|
||||||
|
|
||||||
guard let windowDragHandle = windowDragHandle else { return }
|
|
||||||
|
|
||||||
windowDragHandle.identifier = NSUserInterfaceItemIdentifier("_windowDragHandle")
|
|
||||||
titlebarView.superview?.addSubview(windowDragHandle)
|
|
||||||
windowDragHandle.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
windowDragHandle.leftAnchor.constraint(equalTo: toolbarView.leftAnchor).isActive = true
|
|
||||||
windowDragHandle.rightAnchor.constraint(equalTo: toolbarView.rightAnchor).isActive = true
|
|
||||||
windowDragHandle.topAnchor.constraint(equalTo: toolbarView.topAnchor).isActive = true
|
|
||||||
windowDragHandle.bottomAnchor.constraint(equalTo: toolbarView.topAnchor, constant: 12).isActive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// To be called immediately after the tab bar is disabled.
|
|
||||||
public func hideCustomTabBarViews() {
|
|
||||||
// Hide the window buttons backdrop.
|
|
||||||
windowButtonsBackdrop?.isHidden = true
|
|
||||||
// Hide the window drag handle.
|
|
||||||
windowDragHandle?.isHidden = true
|
|
||||||
// Enable the window title text.
|
|
||||||
titleVisibility = .visible
|
|
||||||
}
|
|
||||||
|
|
||||||
private func pushTabsToTitlebar(_ tabBarController: NSTitlebarAccessoryViewController) {
|
private func pushTabsToTitlebar(_ tabBarController: NSTitlebarAccessoryViewController) {
|
||||||
let accessoryView = tabBarController.view
|
let accessoryView = tabBarController.view
|
||||||
guard let accessoryClipView = accessoryView.superview else { return }
|
guard let accessoryClipView = accessoryView.superview else { return }
|
||||||
guard let titlebarView = accessoryClipView.superview else { return }
|
guard let titlebarView = accessoryClipView.superview else { return }
|
||||||
|
|
||||||
guard titlebarView.className == "NSTitlebarView" else { return }
|
guard titlebarView.className == "NSTitlebarView" else { return }
|
||||||
|
|
||||||
guard let toolbarView = titlebarView.subviews.first(where: {
|
guard let toolbarView = titlebarView.subviews.first(where: {
|
||||||
$0.className == "NSToolbarView"
|
$0.className == "NSToolbarView"
|
||||||
}) else { return }
|
}) else { return }
|
||||||
|
|
||||||
addWindowButtonsBackdrop(titlebarView: titlebarView, toolbarView: toolbarView)
|
addWindowButtonsBackdrop(titlebarView: titlebarView, toolbarView: toolbarView)
|
||||||
windowButtonsBackdrop?.isHidden = false
|
|
||||||
guard let windowButtonsBackdrop = windowButtonsBackdrop else { return }
|
guard let windowButtonsBackdrop = windowButtonsBackdrop else { return }
|
||||||
|
windowButtonsBackdrop.isHidden = false
|
||||||
|
|
||||||
addWindowDragHandle(titlebarView: titlebarView, toolbarView: toolbarView)
|
addWindowDragHandle(titlebarView: titlebarView, toolbarView: toolbarView)
|
||||||
windowDragHandle?.isHidden = false
|
windowDragHandle?.isHidden = false
|
||||||
@ -186,7 +147,52 @@ class TerminalWindow: NSWindow {
|
|||||||
self.markHierarchyForLayout(accessoryView)
|
self.markHierarchyForLayout(accessoryView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func addWindowButtonsBackdrop(titlebarView: NSView, toolbarView: NSView) {
|
||||||
|
guard windowButtonsBackdrop == nil else { return }
|
||||||
|
|
||||||
|
let view = NSView()
|
||||||
|
view.identifier = NSUserInterfaceItemIdentifier("_windowButtonsBackdrop")
|
||||||
|
titlebarView.addSubview(view)
|
||||||
|
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.leftAnchor.constraint(equalTo: toolbarView.leftAnchor).isActive = true
|
||||||
|
view.rightAnchor.constraint(equalTo: toolbarView.leftAnchor, constant: 80).isActive = true
|
||||||
|
view.topAnchor.constraint(equalTo: toolbarView.topAnchor).isActive = true
|
||||||
|
view.heightAnchor.constraint(equalTo: toolbarView.heightAnchor).isActive = true
|
||||||
|
view.wantsLayer = true
|
||||||
|
view.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.45)
|
||||||
|
|
||||||
|
let topBorder = NSView()
|
||||||
|
view.addSubview(topBorder)
|
||||||
|
topBorder.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
topBorder.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
|
||||||
|
topBorder.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
|
||||||
|
topBorder.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||||
|
topBorder.bottomAnchor.constraint(equalTo: view.topAnchor, constant: 1).isActive = true
|
||||||
|
topBorder.wantsLayer = true
|
||||||
|
topBorder.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.85)
|
||||||
|
|
||||||
|
windowButtonsBackdrop = view
|
||||||
|
}
|
||||||
|
|
||||||
|
private func addWindowDragHandle(titlebarView: NSView, toolbarView: NSView) {
|
||||||
|
guard windowDragHandle == nil else { return }
|
||||||
|
|
||||||
|
let view = WindowDragView()
|
||||||
|
view.identifier = NSUserInterfaceItemIdentifier("_windowDragHandle")
|
||||||
|
titlebarView.superview?.addSubview(view)
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.leftAnchor.constraint(equalTo: toolbarView.leftAnchor).isActive = true
|
||||||
|
view.rightAnchor.constraint(equalTo: toolbarView.rightAnchor).isActive = true
|
||||||
|
view.topAnchor.constraint(equalTo: toolbarView.topAnchor).isActive = true
|
||||||
|
view.bottomAnchor.constraint(equalTo: toolbarView.topAnchor, constant: 12).isActive = true
|
||||||
|
|
||||||
|
windowDragHandle = view
|
||||||
|
}
|
||||||
|
|
||||||
|
// This forces this view and all subviews to update layout and redraw. This is
|
||||||
|
// a hack (see the caller).
|
||||||
private func markHierarchyForLayout(_ view: NSView) {
|
private func markHierarchyForLayout(_ view: NSView) {
|
||||||
view.needsUpdateConstraints = true
|
view.needsUpdateConstraints = true
|
||||||
view.needsLayout = true
|
view.needsLayout = true
|
||||||
@ -197,3 +203,32 @@ class TerminalWindow: NSWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Passes mouseDown events from this view to window.performDrag so that you can drag the window by it.
|
||||||
|
fileprivate class WindowDragView: NSView {
|
||||||
|
override public func mouseDown(with event: NSEvent) {
|
||||||
|
// Drag the window for single left clicks, double clicks should bypass the drag handle.
|
||||||
|
if (event.type == .leftMouseDown && event.clickCount == 1) {
|
||||||
|
window?.performDrag(with: event)
|
||||||
|
NSCursor.closedHand.set()
|
||||||
|
} else {
|
||||||
|
super.mouseDown(with: event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func mouseEntered(with event: NSEvent) {
|
||||||
|
super.mouseEntered(with: event)
|
||||||
|
window?.disableCursorRects()
|
||||||
|
NSCursor.openHand.set()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func mouseExited(with event: NSEvent) {
|
||||||
|
super.mouseExited(with: event)
|
||||||
|
window?.enableCursorRects()
|
||||||
|
NSCursor.arrow.set()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func resetCursorRects() {
|
||||||
|
addCursorRect(bounds, cursor: .openHand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -203,7 +203,7 @@ extension Ghostty {
|
|||||||
var v = false;
|
var v = false;
|
||||||
let key = "macos-titlebar-tabs"
|
let key = "macos-titlebar-tabs"
|
||||||
_ = ghostty_config_get(config, &v, key, UInt(key.count))
|
_ = ghostty_config_get(config, &v, key, UInt(key.count))
|
||||||
return v
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var backgroundColor: Color {
|
var backgroundColor: Color {
|
||||||
|
Reference in New Issue
Block a user