AppDelegate.swift 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import AppKit
  2. @MainActor
  3. final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
  4. private var windowObservers: [NSObjectProtocol] = []
  5. func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
  6. false
  7. }
  8. func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
  9. if !flag {
  10. showMainWindow()
  11. }
  12. return true
  13. }
  14. func applicationDidFinishLaunching(_ notification: Notification) {
  15. installWindowObservers()
  16. configureMainWindows()
  17. }
  18. func applicationDidBecomeActive(_ notification: Notification) {
  19. configureMainWindows()
  20. showMainWindowIfNeeded()
  21. }
  22. func windowShouldClose(_ sender: NSWindow) -> Bool {
  23. sender.orderOut(nil)
  24. return false
  25. }
  26. func configureMainWindows() {
  27. for window in NSApp.windows where isMainAppWindow(window) {
  28. window.isReleasedWhenClosed = false
  29. if window.delegate !== self {
  30. window.delegate = self
  31. }
  32. }
  33. }
  34. private func installWindowObservers() {
  35. let center = NotificationCenter.default
  36. windowObservers = [
  37. center.addObserver(
  38. forName: NSWindow.didBecomeKeyNotification,
  39. object: nil,
  40. queue: .main
  41. ) { [weak self] _ in
  42. Task { @MainActor in
  43. self?.configureMainWindows()
  44. }
  45. },
  46. center.addObserver(
  47. forName: NSApplication.didUpdateNotification,
  48. object: nil,
  49. queue: .main
  50. ) { [weak self] _ in
  51. Task { @MainActor in
  52. self?.configureMainWindows()
  53. }
  54. },
  55. ]
  56. }
  57. private func showMainWindowIfNeeded() {
  58. guard !NSApp.windows.contains(where: { isMainAppWindow($0) && $0.isVisible }) else { return }
  59. showMainWindow()
  60. }
  61. private func showMainWindow() {
  62. guard let window = NSApp.windows.first(where: isMainAppWindow) else { return }
  63. window.makeKeyAndOrderFront(nil)
  64. NSApp.activate(ignoringOtherApps: true)
  65. }
  66. private func isMainAppWindow(_ window: NSWindow) -> Bool {
  67. guard window.canBecomeMain, !(window is NSPanel) else { return false }
  68. if window.title == "Sign in to Reddit" { return false }
  69. return window.level == .normal
  70. }
  71. }