i need do something in background when user click the red x at upper left of NSWindow,
NSWindowDelegate method windowShouldClose(_:) return false, but the window close. and the GCD closure never call.
the console log is 1 - 2 - 3 - 5 - 7, and i want it be 1 - 2 - 3 - 5 - 4 - 7.
what's the problem of the code?
EDIT: In face, i want window just hidden when user click red x, and i will do something background, and then close window after 1 second.
class ViewController: NSViewController, NSWindowDelegate {
override func viewWillAppear() {
super.viewWillAppear()
view.window?.delegate = self
}
func windowShouldClose(_ sender: NSWindow) -> Bool {
print("1")
if sender.isVisible {
print("2")
sender.orderOut(nil)
// do something here
print("3")
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print("4")
sender.close()
}
print("5")
return false
} else {
print("6")
return true
}
}
func windowWillClose(_ notification: Notification) {
print("7")
}
}
Finally:
1 - 2 - 3 - 5 - 4 - 7
class ViewController: NSViewController, NSWindowDelegate {
override func viewWillAppear() {
super.viewWillAppear()
view.window?.delegate = self
}
func windowShouldClose(_ sender: NSWindow) -> Bool {
print("1")
if sender.isVisible {
print("2")
sender.orderBack(nil)
// do something here
print("3")
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print("4")
sender.close()
}
print("5")
return false
} else {
print("6")
return true
}
}
func windowWillClose(_ notification: Notification) {
print("7")
}
}
Thanks for Malik and Parag Bafna.
orderOut
call inside windowShouldClose
is creating the issue.
Use orderBack
and isKeyWindow
check
func windowShouldClose(_ sender: NSWindow) -> Bool {
print("1")
if sender.isKeyWindow {
print("2")
sender.orderBack(nil)
// do something here
print("3")
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print("4")
sender.performClose(nil)
}
print("5")
return false
} else {
print("6")
return true
}
}
or return false from applicationShouldTerminateAfterLastWindowClosed