mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-05 19:08:17 +00:00
macos: add reset zoom to all window titles
This commit is contained in:
@@ -758,6 +758,8 @@ class BaseTerminalController: NSWindowController,
|
||||
}
|
||||
}
|
||||
|
||||
func fullscreenDidChange() {}
|
||||
|
||||
// MARK: Clipboard Confirmation
|
||||
|
||||
@objc private func onConfirmClipboardRequest(notification: SwiftUI.Notification) {
|
||||
|
@@ -145,7 +145,9 @@ class TerminalController: BaseTerminalController {
|
||||
}
|
||||
|
||||
|
||||
func fullscreenDidChange() {
|
||||
override func fullscreenDidChange() {
|
||||
super.fullscreenDidChange()
|
||||
|
||||
// When our fullscreen state changes, we resync our appearance because some
|
||||
// properties change when fullscreen or not.
|
||||
guard let focusedSurface else { return }
|
||||
|
@@ -9,6 +9,9 @@ class TerminalWindow: NSWindow {
|
||||
/// used by the manual float on top menu item feature.
|
||||
static let defaultLevelKey: String = "TerminalDefaultLevel"
|
||||
|
||||
/// The view model for SwiftUI views
|
||||
private var viewModel = ViewModel()
|
||||
|
||||
/// The configuration derived from the Ghostty config so we don't need to rely on references.
|
||||
private(set) var derivedConfig: DerivedConfig?
|
||||
|
||||
@@ -19,6 +22,15 @@ class TerminalWindow: NSWindow {
|
||||
|
||||
// MARK: NSWindow Overrides
|
||||
|
||||
override var toolbar: NSToolbar? {
|
||||
didSet {
|
||||
DispatchQueue.main.async {
|
||||
// When we have a toolbar, our SwiftUI view needs to know for layout
|
||||
self.viewModel.hasToolbar = self.toolbar != nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
guard let appDelegate = NSApp.delegate as? AppDelegate else { return }
|
||||
|
||||
@@ -43,6 +55,18 @@ class TerminalWindow: NSWindow {
|
||||
hideWindowButtons()
|
||||
}
|
||||
|
||||
// Create our reset zoom titlebar accessory.
|
||||
let resetZoomAccessory = NSTitlebarAccessoryViewController()
|
||||
resetZoomAccessory.layoutAttribute = .right
|
||||
resetZoomAccessory.view = NSHostingView(rootView: ResetZoomAccessoryView(
|
||||
viewModel: viewModel,
|
||||
action: { [weak self] in
|
||||
guard let self else { return }
|
||||
self.terminalController?.splitZoom(self)
|
||||
}))
|
||||
addTitlebarAccessoryViewController(resetZoomAccessory)
|
||||
resetZoomAccessory.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
// Setup the accessory view for tabs that shows our keyboard shortcuts,
|
||||
// zoomed state, etc. Note I tried to use SwiftUI here but ran into issues
|
||||
// where buttons were not clickable.
|
||||
@@ -115,6 +139,10 @@ class TerminalWindow: NSWindow {
|
||||
// Show/hide our reset zoom button depending on if we're zoomed.
|
||||
// We want to show it if we are zoomed.
|
||||
resetZoomTabButton.isHidden = !surfaceIsZoomed
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.viewModel.isSurfaceZoomed = self.surfaceIsZoomed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,3 +341,37 @@ class TerminalWindow: NSWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: SwiftUI View
|
||||
|
||||
extension TerminalWindow {
|
||||
class ViewModel: ObservableObject {
|
||||
@Published var isSurfaceZoomed: Bool = false
|
||||
@Published var hasToolbar: Bool = false
|
||||
}
|
||||
|
||||
struct ResetZoomAccessoryView: View {
|
||||
@ObservedObject var viewModel: ViewModel
|
||||
let action: () -> Void
|
||||
|
||||
var body: some View {
|
||||
if viewModel.isSurfaceZoomed {
|
||||
VStack {
|
||||
Button(action: action) {
|
||||
Image("ResetZoom")
|
||||
.foregroundColor(.accentColor)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Reset Split Zoom")
|
||||
.frame(width: 20, height: 20)
|
||||
Spacer()
|
||||
}
|
||||
// With a toolbar, the window title is taller, so we need more padding
|
||||
// to properly align.
|
||||
.padding(.top, viewModel.hasToolbar ? 10 : 5)
|
||||
// We always need space at the end of the titlebar
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -45,10 +45,6 @@ protocol FullscreenDelegate: AnyObject {
|
||||
func fullscreenDidChange()
|
||||
}
|
||||
|
||||
extension FullscreenDelegate {
|
||||
func fullscreenDidChange() {}
|
||||
}
|
||||
|
||||
/// The base class for fullscreen implementations, cannot be used as a FullscreenStyle on its own.
|
||||
class FullscreenBase {
|
||||
let window: NSWindow
|
||||
@@ -269,6 +265,12 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
||||
window.styleMask = savedState.styleMask
|
||||
window.setFrame(window.frameRect(forContentRect: savedState.contentFrame), display: true)
|
||||
|
||||
// Removing the "titled" style also derefs all our accessory view controllers
|
||||
// so we need to restore those.
|
||||
for c in savedState.titlebarAccessoryViewControllers {
|
||||
window.addTitlebarAccessoryViewController(c)
|
||||
}
|
||||
|
||||
// This is a hack that I want to remove from this but for now, we need to
|
||||
// fix up the titlebar tabs here before we do everything below.
|
||||
if let window = window as? TitlebarTabsVenturaTerminalWindow, window.titlebarTabs {
|
||||
@@ -383,6 +385,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
||||
let tabGroupIndex: Int?
|
||||
let contentFrame: NSRect
|
||||
let styleMask: NSWindow.StyleMask
|
||||
let titlebarAccessoryViewControllers: [NSTitlebarAccessoryViewController]
|
||||
let dock: Bool
|
||||
let menu: Bool
|
||||
|
||||
@@ -394,6 +397,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
||||
self.tabGroupIndex = window.tabGroup?.windows.firstIndex(of: window)
|
||||
self.contentFrame = window.convertToScreen(contentView.frame)
|
||||
self.styleMask = window.styleMask
|
||||
self.titlebarAccessoryViewControllers = window.titlebarAccessoryViewControllers
|
||||
self.dock = window.screen?.hasDock ?? false
|
||||
|
||||
if let cgWindowId = window.cgWindowId {
|
||||
|
Reference in New Issue
Block a user