mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-09-19 15:17:21 +03:00
Cancel relaunch when closing documens is cancelled
This commit is contained in:
parent
ff28b552e3
commit
c9b7a5a034
@ -17,6 +17,7 @@ Change Log
|
||||
- Improve VoiceOver accessibility.
|
||||
- Update the AppleScript guide in the help.
|
||||
- Change the behavior to include the last line in the calculation when specifying lines with a negative value in the Go to Line command or via AppleScript.
|
||||
- Make sure the application relaunchs even other tasks interrupt before termination.
|
||||
- [dev] Update the build environment to Xcode 13 (Swift 5.5).
|
||||
- [non-AppStore ver.] Update Sparkle to 2.0.0-beta.3.
|
||||
|
||||
|
@ -56,6 +56,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Public Properties
|
||||
|
||||
var needsRelaunch = false
|
||||
|
||||
|
||||
// MARK: Private Properties
|
||||
|
||||
private var menuUpdateObservers: Set<AnyCancellable> = []
|
||||
@ -179,6 +184,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
|
||||
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
||||
NSApp.reply(toApplicationShouldTerminate: true)
|
||||
return .terminateLater
|
||||
}
|
||||
|
||||
/// store last version before termination
|
||||
func applicationWillTerminate(_ notification: Notification) {
|
||||
|
||||
@ -196,6 +206,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
if isLatest {
|
||||
UserDefaults.standard[.lastVersion] = thisVersion
|
||||
}
|
||||
|
||||
if self.needsRelaunch {
|
||||
NSApp.relaunch()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,6 +201,16 @@ final class DocumentController: NSDocumentController {
|
||||
}
|
||||
|
||||
|
||||
override func closeAllDocuments(withDelegate delegate: Any?, didCloseAllSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
|
||||
|
||||
let context = DelegateContext(delegate: delegate,
|
||||
selector: didCloseAllSelector,
|
||||
contextInfo: contextInfo)
|
||||
|
||||
super.closeAllDocuments(withDelegate: self, didCloseAllSelector: #selector(documentController(_:didCloseAll:contextInfo:)), contextInfo: bridgeWrapped(context))
|
||||
}
|
||||
|
||||
|
||||
/// return availability of actions
|
||||
override func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
|
||||
|
||||
@ -256,6 +266,14 @@ final class DocumentController: NSDocumentController {
|
||||
|
||||
// MARK: Private Methods
|
||||
|
||||
private struct DelegateContext {
|
||||
|
||||
var delegate: Any?
|
||||
var selector: Selector?
|
||||
var contextInfo: UnsafeMutableRawPointer?
|
||||
}
|
||||
|
||||
|
||||
/// transient document to be replaced or nil
|
||||
private var transientDocumentToReplace: Document? {
|
||||
|
||||
@ -316,6 +334,30 @@ final class DocumentController: NSDocumentController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// callback from document after calling `closeAllDocuments(withDelegate:didCloseAllSelector:contextInfo)`.
|
||||
@objc private func documentController(_ documentController: NSDocumentController, didCloseAll: Bool, contextInfo: UnsafeMutableRawPointer) {
|
||||
|
||||
// cancel relaunching
|
||||
if !didCloseAll {
|
||||
(NSApp.delegate as? AppDelegate)?.needsRelaunch = false
|
||||
}
|
||||
|
||||
// manually invoke the original delegate method
|
||||
guard
|
||||
let context: DelegateContext = bridgeUnwrapped(contextInfo),
|
||||
let delegate = context.delegate as? NSObject,
|
||||
let selector = context.selector,
|
||||
let objcClass = objc_getClass(delegate.className) as? AnyClass,
|
||||
let method = class_getMethodImplementation(objcClass, selector)
|
||||
else { return assertionFailure() }
|
||||
|
||||
typealias Signature = @convention(c) (AnyObject, Selector, AnyObject, Bool, UnsafeMutableRawPointer?) -> Void
|
||||
let function = unsafeBitCast(method, to: Signature.self)
|
||||
|
||||
function(delegate, selector, self, didCloseAll, context.contextInfo)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,7 +126,8 @@ final class GeneralPaneController: NSViewController {
|
||||
|
||||
switch returnCode {
|
||||
case .alertFirstButtonReturn: // = Restart Now
|
||||
NSApp.relaunch()
|
||||
(NSApp.delegate as? AppDelegate)?.needsRelaunch = true
|
||||
NSApp.terminate(self)
|
||||
case .alertSecondButtonReturn: // = Later
|
||||
break // do nothing
|
||||
case .alertThirdButtonReturn: // = Cancel
|
||||
|
@ -34,7 +34,6 @@ extension NSApplication {
|
||||
let command = String(format: "sleep 2; open \"%@\"", escapedPath)
|
||||
|
||||
Process.launchedProcess(launchPath: "/bin/sh", arguments: ["-c", command])
|
||||
self.terminate(nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user