| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import AppKit
- @MainActor
- final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
- private var windowObservers: [NSObjectProtocol] = []
- private var shouldCenterMainWindowOnShow = true
- private var centeringDeadline: Date?
- func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
- false
- }
- func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
- if !flag {
- showMainWindow()
- }
- return true
- }
- func applicationDidFinishLaunching(_ notification: Notification) {
- installWindowObservers()
- configureMainWindows()
- beginCenteringMainWindow()
- }
- func applicationDidBecomeActive(_ notification: Notification) {
- configureMainWindows()
- showMainWindowIfNeeded()
- RedditWebViewStore.shared.handleApplicationDidBecomeActive()
- }
- func windowShouldClose(_ sender: NSWindow) -> Bool {
- if isMainAppWindow(sender) {
- shouldCenterMainWindowOnShow = true
- centeringDeadline = nil
- }
- sender.orderOut(nil)
- return false
- }
- func windowWillMiniaturize(_ sender: NSWindow) {
- guard isMainAppWindow(sender) else { return }
- RedditWebViewStore.shared.suspendMediaPlaybackForWindowMinimize()
- }
- func windowDidDeminiaturize(_ sender: NSWindow) {
- guard isMainAppWindow(sender) else { return }
- RedditWebViewStore.shared.resumeMediaPlaybackAfterWindowDeminiaturize()
- }
- func windowDidMove(_ sender: NSWindow) {
- guard isMainAppWindow(sender), isCenteringMainWindow else { return }
- AppWindow.centerOnScreen(sender)
- }
- func configureMainWindows() {
- for window in NSApp.windows where isMainAppWindow(window) {
- window.isReleasedWhenClosed = false
- window.isRestorable = false
- window.setFrameAutosaveName("")
- if window.delegate !== self {
- window.delegate = self
- }
- }
- }
- func centerMainWindow() {
- beginCenteringMainWindow()
- }
- private var isCenteringMainWindow: Bool {
- guard shouldCenterMainWindowOnShow else { return false }
- if let centeringDeadline {
- return Date() < centeringDeadline
- }
- return true
- }
- private func beginCenteringMainWindow() {
- shouldCenterMainWindowOnShow = true
- centeringDeadline = Date().addingTimeInterval(0.6)
- centerMainWindowIfNeeded()
- }
- private func finishCenteringMainWindow() {
- shouldCenterMainWindowOnShow = false
- centeringDeadline = nil
- }
- private func centerMainWindowIfNeeded() {
- guard isCenteringMainWindow else { return }
- guard let window = NSApp.windows.first(where: isMainAppWindow) else { return }
- let centerAction = { [weak self] in
- guard let self, self.isCenteringMainWindow else { return }
- AppWindow.centerOnScreen(window)
- }
- centerAction()
- DispatchQueue.main.async(execute: centerAction)
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.15, execute: centerAction)
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { [weak self] in
- centerAction()
- self?.finishCenteringMainWindow()
- }
- }
- private func installWindowObservers() {
- let center = NotificationCenter.default
- windowObservers = [
- center.addObserver(
- forName: NSWindow.didBecomeKeyNotification,
- object: nil,
- queue: .main
- ) { [weak self] _ in
- Task { @MainActor in
- self?.configureMainWindows()
- }
- },
- center.addObserver(
- forName: NSApplication.didUpdateNotification,
- object: nil,
- queue: .main
- ) { [weak self] _ in
- Task { @MainActor in
- self?.configureMainWindows()
- }
- },
- ]
- }
- private func showMainWindowIfNeeded() {
- guard !NSApp.windows.contains(where: { isMainAppWindow($0) && $0.isVisible }) else { return }
- showMainWindow()
- }
- private func showMainWindow() {
- guard let window = NSApp.windows.first(where: isMainAppWindow) else { return }
- beginCenteringMainWindow()
- window.makeKeyAndOrderFront(nil)
- NSApp.activate(ignoringOtherApps: true)
- }
- private func isMainAppWindow(_ window: NSWindow) -> Bool {
- guard window.canBecomeMain, !(window is NSPanel) else { return false }
- if window.title == "Sign in to Reddit" { return false }
- return window.level == .normal
- }
- }
|