From b8a24e8bba97f288a4368ac7ccb0c0b664db5255 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 30 Oct 2023 09:19:13 -0700 Subject: [PATCH] macos: toggle fullscreen --- .../Terminal/TerminalController.swift | 39 +++++++++++++++++-- macos/Sources/Helpers/FullScreenHandler.swift | 3 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 80bb0a7f0..7dbe98313 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -1,7 +1,7 @@ import Foundation import Cocoa import SwiftUI -import Combine +import GhosttyKit class TerminalController: NSWindowController, NSWindowDelegate, TerminalViewDelegate { override var windowNibName: NSNib.Name? { "Terminal" } @@ -12,20 +12,31 @@ class TerminalController: NSWindowController, NSWindowDelegate, TerminalViewDele /// The currently focused surface. var focusedSurface: Ghostty.SurfaceView? = nil + /// Fullscreen state management. + private let fullscreenHandler = FullScreenHandler() + init(_ ghostty: Ghostty.AppState) { self.ghostty = ghostty super.init(window: nil) - // Register as observer for window-level manipulations that are best handled - // here at the controller layer rather than in the SwiftUI stack. let center = NotificationCenter.default - + center.addObserver( + self, + selector: #selector(onToggleFullscreen), + name: Ghostty.Notification.ghosttyToggleFullscreen, + object: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) is not supported for this view") } + deinit { + // Remove all of our notificationcenter subscriptions + let center = NotificationCenter.default + center.removeObserver(self) + } + //MARK: - NSWindowController override func windowWillLoad() { @@ -78,4 +89,24 @@ class TerminalController: NSWindowController, NSWindowDelegate, TerminalViewDele guard ghostty.windowStepResize else { return } self.window?.contentResizeIncrements = to } + + //MARK: - Notifications + + @objc private func onToggleFullscreen(notification: SwiftUI.Notification) { + guard let target = notification.object as? Ghostty.SurfaceView else { return } + guard target == self.focusedSurface else { return } + + // We need a window to fullscreen + guard let window = self.window else { return } + + // Check whether we use non-native fullscreen + guard let useNonNativeFullscreenAny = notification.userInfo?[Ghostty.Notification.NonNativeFullscreenKey] else { return } + guard let useNonNativeFullscreen = useNonNativeFullscreenAny as? ghostty_non_native_fullscreen_e else { return } + self.fullscreenHandler.toggleFullscreen(window: window, nonNativeFullscreen: useNonNativeFullscreen) + + // For some reason focus always gets lost when we toggle fullscreen, so we set it back. + if let focusedSurface { + Ghostty.moveFocus(to: focusedSurface) + } + } } diff --git a/macos/Sources/Helpers/FullScreenHandler.swift b/macos/Sources/Helpers/FullScreenHandler.swift index 28bf83149..a1caf8069 100644 --- a/macos/Sources/Helpers/FullScreenHandler.swift +++ b/macos/Sources/Helpers/FullScreenHandler.swift @@ -1,7 +1,8 @@ import SwiftUI import GhosttyKit -class FullScreenHandler { var previousTabGroup: NSWindowTabGroup? +class FullScreenHandler { + var previousTabGroup: NSWindowTabGroup? var previousTabGroupIndex: Int? var previousContentFrame: NSRect? var previousStyleMask: NSWindow.StyleMask? = nil