|
|
@@ -39,15 +39,19 @@ enum AppWindowConfiguration {
|
|
|
app.mainWindow
|
|
|
?? app.keyWindow
|
|
|
?? app.windows.first(where: { $0.isVisible && $0.canBecomeKey })
|
|
|
+ ?? app.windows.first(where: { $0.canBecomeKey })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@main
|
|
|
-class AppDelegate: NSObject, NSApplicationDelegate {
|
|
|
+class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
|
|
|
/// Avoids hammering StoreKit when `didBecomeActive` fires in quick succession (e.g. after system sheets).
|
|
|
private var lastSubscriptionRefreshAt: Date?
|
|
|
|
|
|
+ /// Window menu item that re-opens the main window after the user closes it with the red button.
|
|
|
+ private var showMainWindowMenuItem: NSMenuItem?
|
|
|
+
|
|
|
func applicationWillFinishLaunching(_ notification: Notification) {
|
|
|
AppLanguageManager.shared.applyStoredPreferenceOnLaunch()
|
|
|
AppAppearanceManager.shared.apply()
|
|
|
@@ -73,6 +77,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|
|
}
|
|
|
|
|
|
// Initial StoreKit refresh runs on `LoadingViewController` before the dashboard is shown.
|
|
|
+ installMainWindowMenuItem()
|
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
|
applyDefaultWindowSize()
|
|
|
}
|
|
|
@@ -111,12 +116,40 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|
|
/// Clicking the Dock icon after closing the window should bring it back.
|
|
|
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
|
|
|
guard !flag else { return true }
|
|
|
- let window = AppWindowConfiguration.mainWindow(in: sender)
|
|
|
- ?? sender.windows.first(where: { $0.canBecomeKey })
|
|
|
- window?.makeKeyAndOrderFront(self)
|
|
|
- sender.activate(ignoringOtherApps: true)
|
|
|
+ showMainWindow(self)
|
|
|
return true
|
|
|
}
|
|
|
+
|
|
|
+ /// Adds a persistent Window menu entry so reviewers and users can reopen the app after closing its window.
|
|
|
+ private func installMainWindowMenuItem() {
|
|
|
+ guard let windowMenu = NSApp.windowsMenu else { return }
|
|
|
+ guard showMainWindowMenuItem == nil else { return }
|
|
|
+
|
|
|
+ let item = NSMenuItem(
|
|
|
+ title: AppMarketingLinks.appDisplayName,
|
|
|
+ action: #selector(showMainWindow(_:)),
|
|
|
+ keyEquivalent: ""
|
|
|
+ )
|
|
|
+ item.target = self
|
|
|
+ showMainWindowMenuItem = item
|
|
|
+ windowMenu.insertItem(item, at: 0)
|
|
|
+ windowMenu.insertItem(NSMenuItem.separator(), at: 1)
|
|
|
+ windowMenu.delegate = self
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func showMainWindow(_ sender: Any?) {
|
|
|
+ guard let window = AppWindowConfiguration.mainWindow() else { return }
|
|
|
+ window.makeKeyAndOrderFront(sender)
|
|
|
+ NSApp.activate(ignoringOtherApps: true)
|
|
|
+ }
|
|
|
+
|
|
|
+ func menuNeedsUpdate(_ menu: NSMenu) {
|
|
|
+ guard menu === NSApp.windowsMenu, let item = showMainWindowMenuItem else { return }
|
|
|
+ let window = AppWindowConfiguration.mainWindow()
|
|
|
+ let isVisible = window?.isVisible == true
|
|
|
+ item.isEnabled = !isVisible
|
|
|
+ item.state = isVisible ? .on : .off
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// MARK: - Main window close (hide on red button, do not quit)
|