Merge pull request #224 from mitchellh/quit-without-focus

macos: Cmd-Q without any window focus works
This commit is contained in:
Mitchell Hashimoto
2023-08-05 10:46:54 -07:00
committed by GitHub
2 changed files with 30 additions and 3 deletions

View File

@ -48,8 +48,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
if (windows.allSatisfy { !$0.isVisible }) { return .terminateNow }
// If the user is shutting down, restarting, or logging out, we don't confirm quit.
if let event = NSAppleEventManager.shared().currentAppleEvent {
if let why = event.attributeDescriptor(forKeyword: AEKeyword("why?")!) {
why: if let event = NSAppleEventManager.shared().currentAppleEvent {
// If all Ghostty windows are in the background (i.e. you Cmd-Q from the Cmd-Tab
// view), then this is null. I don't know why (pun intended) but we have to
// guard against it.
guard let keyword = AEKeyword("why?") else { break why }
if let why = event.attributeDescriptor(forKeyword: keyword) {
switch (why.typeCodeValue) {
case kAEShutDown:
fallthrough

View File

@ -24,6 +24,28 @@ struct PrimaryView: View {
@FocusedValue(\.ghosttySurfaceView) private var focusedSurface
@FocusedValue(\.ghosttySurfaceTitle) private var surfaceTitle
// This is true if this view should be the one to show the quit confirmation.
var ownsQuitConfirmation: Bool {
// We need to have a window to show a confirmation.
guard let window = self.window else { return false }
// If we are the key window then definitely yes.
if (window.isKeyWindow) { return true }
// If there is some other PrimaryWindow that is key, let it handle it.
let windows = NSApplication.shared.windows
if (windows.contains {
guard let primary = $0 as? PrimaryWindow else { return false }
return primary.isKeyWindow
}) { return false }
// We aren't the key window but also there is no key PrimaryWindow.
// If we are the FIRST PrimaryWindow in the windows array, then
// we take the job.
guard let firstWindow = (windows.first { $0 is PrimaryWindow }) else { return false }
return window == firstWindow
}
var body: some View {
switch ghostty.readiness {
case .loading:
@ -44,7 +66,7 @@ struct PrimaryView: View {
let toggleFullscreen = center.publisher(for: Ghostty.Notification.ghosttyToggleFullscreen)
let confirmQuitting = Binding<Bool>(get: {
self.appDelegate.confirmQuit && (self.window?.isKeyWindow ?? false)
self.appDelegate.confirmQuit && self.ownsQuitConfirmation
}, set: {
self.appDelegate.confirmQuit = $0
})