mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: change key window detection
This commit is contained in:
@ -7,7 +7,6 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A518502629A1A45100E4CC4F /* WindowTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A518502529A1A45100E4CC4F /* WindowTracker.swift */; };
|
||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
||||
A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; };
|
||||
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB529B6F47F0055DE60 /* AppState.swift */; };
|
||||
@ -21,7 +20,6 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A518502529A1A45100E4CC4F /* WindowTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowTracker.swift; sourceTree = "<group>"; };
|
||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
||||
A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = "<group>"; };
|
||||
A55B7BB529B6F47F0055DE60 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
|
||||
@ -57,7 +55,6 @@
|
||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
||||
A55685DF29A03A9F004303CE /* AppError.swift */,
|
||||
A59444F629A2ED5200725BBA /* SettingsView.swift */,
|
||||
A518502529A1A45100E4CC4F /* WindowTracker.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@ -178,7 +175,6 @@
|
||||
files = (
|
||||
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */,
|
||||
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */,
|
||||
A518502629A1A45100E4CC4F /* WindowTracker.swift in Sources */,
|
||||
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */,
|
||||
A55B7BBE29B701360055DE60 /* SplitView.swift in Sources */,
|
||||
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */,
|
||||
|
@ -31,11 +31,13 @@ extension Ghostty {
|
||||
@ObservedObject var surfaceView: SurfaceView
|
||||
|
||||
@FocusState private var surfaceFocus: Bool
|
||||
@Environment(\.isKeyWindow) private var isKeyWindow: Bool
|
||||
|
||||
// https://nilcoalescing.com/blog/DetectFocusedWindowOnMacOS/
|
||||
@Environment(\.controlActiveState) var controlActiveState
|
||||
|
||||
// This is true if the terminal is considered "focused". The terminal is focused if
|
||||
// it is both individually focused and the containing window is key.
|
||||
private var hasFocus: Bool { surfaceFocus && isKeyWindow }
|
||||
private var hasFocus: Bool { surfaceFocus && controlActiveState == .key }
|
||||
|
||||
var body: some View {
|
||||
// We use a GeometryReader to get the frame bounds so that our metal surface
|
||||
|
@ -23,7 +23,6 @@ struct GhosttyApp: App {
|
||||
case .ready:
|
||||
Ghostty.TerminalSplitView()
|
||||
.ghosttyApp(ghostty.app!)
|
||||
.modifier(WindowObservationModifier())
|
||||
}
|
||||
}.commands {
|
||||
CommandGroup(after: .newItem) {
|
||||
|
@ -1,90 +0,0 @@
|
||||
import SwiftUI
|
||||
|
||||
/// This modifier tracks whether the window is the key window in the isKeyWindow environment value.
|
||||
struct WindowObservationModifier: ViewModifier {
|
||||
@StateObject var windowObserver: WindowObserver = WindowObserver()
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.background(
|
||||
HostingWindowFinder { [weak windowObserver] window in
|
||||
windowObserver?.window = window
|
||||
}
|
||||
).environment(\.isKeyWindow, windowObserver.isKeyWindow)
|
||||
}
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
struct IsKeyWindowKey: EnvironmentKey {
|
||||
static var defaultValue: Bool = false
|
||||
typealias Value = Bool
|
||||
}
|
||||
|
||||
fileprivate(set) var isKeyWindow: Bool {
|
||||
get {
|
||||
self[IsKeyWindowKey.self]
|
||||
}
|
||||
set {
|
||||
self[IsKeyWindowKey.self] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WindowObserver: ObservableObject {
|
||||
@Published public private(set) var isKeyWindow: Bool = false
|
||||
|
||||
private var becomeKeyobserver: NSObjectProtocol?
|
||||
private var resignKeyobserver: NSObjectProtocol?
|
||||
|
||||
weak var window: NSWindow? {
|
||||
didSet {
|
||||
// Always remove our previous observers if we have any
|
||||
if let previous = self.becomeKeyobserver {
|
||||
NotificationCenter.default.removeObserver(previous)
|
||||
self.becomeKeyobserver = nil
|
||||
}
|
||||
if let previous = self.resignKeyobserver {
|
||||
NotificationCenter.default.removeObserver(previous)
|
||||
self.resignKeyobserver = nil
|
||||
}
|
||||
|
||||
// If our window is becoming nil then we clear everything
|
||||
guard let window = window else {
|
||||
self.isKeyWindow = false
|
||||
return
|
||||
}
|
||||
|
||||
self.isKeyWindow = window.isKeyWindow
|
||||
self.becomeKeyobserver = NotificationCenter.default.addObserver(
|
||||
forName: NSWindow.didBecomeKeyNotification,
|
||||
object: window,
|
||||
queue: .main
|
||||
) { (n) in
|
||||
self.isKeyWindow = true
|
||||
}
|
||||
|
||||
self.resignKeyobserver = NotificationCenter.default.addObserver(
|
||||
forName: NSWindow.didResignKeyNotification,
|
||||
object: window,
|
||||
queue: .main
|
||||
) { (n) in
|
||||
self.isKeyWindow = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This view calls the callback with the window value that hosts the view.
|
||||
struct HostingWindowFinder: NSViewRepresentable {
|
||||
var callback: (NSWindow?) -> ()
|
||||
|
||||
func makeNSView(context: Self.Context) -> NSView {
|
||||
let view = NSView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
DispatchQueue.main.async { [weak view] in
|
||||
self.callback(view?.window)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSView, context: Context) {}
|
||||
}
|
Reference in New Issue
Block a user