mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-07 03:48:21 +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
|
// MARK: Clipboard Confirmation
|
||||||
|
|
||||||
@objc private func onConfirmClipboardRequest(notification: SwiftUI.Notification) {
|
@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
|
// When our fullscreen state changes, we resync our appearance because some
|
||||||
// properties change when fullscreen or not.
|
// properties change when fullscreen or not.
|
||||||
guard let focusedSurface else { return }
|
guard let focusedSurface else { return }
|
||||||
|
@@ -9,6 +9,9 @@ class TerminalWindow: NSWindow {
|
|||||||
/// used by the manual float on top menu item feature.
|
/// used by the manual float on top menu item feature.
|
||||||
static let defaultLevelKey: String = "TerminalDefaultLevel"
|
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.
|
/// The configuration derived from the Ghostty config so we don't need to rely on references.
|
||||||
private(set) var derivedConfig: DerivedConfig?
|
private(set) var derivedConfig: DerivedConfig?
|
||||||
|
|
||||||
@@ -19,6 +22,15 @@ class TerminalWindow: NSWindow {
|
|||||||
|
|
||||||
// MARK: NSWindow Overrides
|
// 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() {
|
override func awakeFromNib() {
|
||||||
guard let appDelegate = NSApp.delegate as? AppDelegate else { return }
|
guard let appDelegate = NSApp.delegate as? AppDelegate else { return }
|
||||||
|
|
||||||
@@ -43,6 +55,18 @@ class TerminalWindow: NSWindow {
|
|||||||
hideWindowButtons()
|
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,
|
// 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
|
// zoomed state, etc. Note I tried to use SwiftUI here but ran into issues
|
||||||
// where buttons were not clickable.
|
// where buttons were not clickable.
|
||||||
@@ -115,6 +139,10 @@ class TerminalWindow: NSWindow {
|
|||||||
// Show/hide our reset zoom button depending on if we're zoomed.
|
// Show/hide our reset zoom button depending on if we're zoomed.
|
||||||
// We want to show it if we are zoomed.
|
// We want to show it if we are zoomed.
|
||||||
resetZoomTabButton.isHidden = !surfaceIsZoomed
|
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()
|
func fullscreenDidChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FullscreenDelegate {
|
|
||||||
func fullscreenDidChange() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The base class for fullscreen implementations, cannot be used as a FullscreenStyle on its own.
|
/// The base class for fullscreen implementations, cannot be used as a FullscreenStyle on its own.
|
||||||
class FullscreenBase {
|
class FullscreenBase {
|
||||||
let window: NSWindow
|
let window: NSWindow
|
||||||
@@ -269,6 +265,12 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
|||||||
window.styleMask = savedState.styleMask
|
window.styleMask = savedState.styleMask
|
||||||
window.setFrame(window.frameRect(forContentRect: savedState.contentFrame), display: true)
|
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
|
// 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.
|
// fix up the titlebar tabs here before we do everything below.
|
||||||
if let window = window as? TitlebarTabsVenturaTerminalWindow, window.titlebarTabs {
|
if let window = window as? TitlebarTabsVenturaTerminalWindow, window.titlebarTabs {
|
||||||
@@ -383,6 +385,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
|||||||
let tabGroupIndex: Int?
|
let tabGroupIndex: Int?
|
||||||
let contentFrame: NSRect
|
let contentFrame: NSRect
|
||||||
let styleMask: NSWindow.StyleMask
|
let styleMask: NSWindow.StyleMask
|
||||||
|
let titlebarAccessoryViewControllers: [NSTitlebarAccessoryViewController]
|
||||||
let dock: Bool
|
let dock: Bool
|
||||||
let menu: Bool
|
let menu: Bool
|
||||||
|
|
||||||
@@ -394,6 +397,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle {
|
|||||||
self.tabGroupIndex = window.tabGroup?.windows.firstIndex(of: window)
|
self.tabGroupIndex = window.tabGroup?.windows.firstIndex(of: window)
|
||||||
self.contentFrame = window.convertToScreen(contentView.frame)
|
self.contentFrame = window.convertToScreen(contentView.frame)
|
||||||
self.styleMask = window.styleMask
|
self.styleMask = window.styleMask
|
||||||
|
self.titlebarAccessoryViewControllers = window.titlebarAccessoryViewControllers
|
||||||
self.dock = window.screen?.hasDock ?? false
|
self.dock = window.screen?.hasDock ?? false
|
||||||
|
|
||||||
if let cgWindowId = window.cgWindowId {
|
if let cgWindowId = window.cgWindowId {
|
||||||
|
Reference in New Issue
Block a user