Преглед изворни кода

Center the main window on launch and reopen.

Disable macOS window restoration and explicitly position the app in the screen center so it no longer reopens in the previous corner.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 пре 4 недеља
родитељ
комит
7fa79fd458

+ 56 - 0
Reddit App/App/AppDelegate.swift

@@ -3,6 +3,8 @@ import AppKit
 @MainActor
 @MainActor
 final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
 final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
     private var windowObservers: [NSObjectProtocol] = []
     private var windowObservers: [NSObjectProtocol] = []
+    private var shouldCenterMainWindowOnShow = true
+    private var centeringDeadline: Date?
 
 
     func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
     func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
         false
         false
@@ -18,6 +20,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
     func applicationDidFinishLaunching(_ notification: Notification) {
     func applicationDidFinishLaunching(_ notification: Notification) {
         installWindowObservers()
         installWindowObservers()
         configureMainWindows()
         configureMainWindows()
+        beginCenteringMainWindow()
     }
     }
 
 
     func applicationDidBecomeActive(_ notification: Notification) {
     func applicationDidBecomeActive(_ notification: Notification) {
@@ -26,6 +29,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
     }
     }
 
 
     func windowShouldClose(_ sender: NSWindow) -> Bool {
     func windowShouldClose(_ sender: NSWindow) -> Bool {
+        if isMainAppWindow(sender) {
+            shouldCenterMainWindowOnShow = true
+            centeringDeadline = nil
+        }
         sender.orderOut(nil)
         sender.orderOut(nil)
         return false
         return false
     }
     }
@@ -40,15 +47,63 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
         RedditWebViewStore.shared.resumeMediaPlaybackAfterWindowDeminiaturize()
         RedditWebViewStore.shared.resumeMediaPlaybackAfterWindowDeminiaturize()
     }
     }
 
 
+    func windowDidMove(_ sender: NSWindow) {
+        guard isMainAppWindow(sender), isCenteringMainWindow else { return }
+        AppWindow.centerOnScreen(sender)
+    }
+
     func configureMainWindows() {
     func configureMainWindows() {
         for window in NSApp.windows where isMainAppWindow(window) {
         for window in NSApp.windows where isMainAppWindow(window) {
             window.isReleasedWhenClosed = false
             window.isReleasedWhenClosed = false
+            window.isRestorable = false
+            window.setFrameAutosaveName("")
             if window.delegate !== self {
             if window.delegate !== self {
                 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() {
     private func installWindowObservers() {
         let center = NotificationCenter.default
         let center = NotificationCenter.default
 
 
@@ -81,6 +136,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
 
 
     private func showMainWindow() {
     private func showMainWindow() {
         guard let window = NSApp.windows.first(where: isMainAppWindow) else { return }
         guard let window = NSApp.windows.first(where: isMainAppWindow) else { return }
+        beginCenteringMainWindow()
         window.makeKeyAndOrderFront(nil)
         window.makeKeyAndOrderFront(nil)
         NSApp.activate(ignoringOtherApps: true)
         NSApp.activate(ignoringOtherApps: true)
     }
     }

+ 1 - 0
Reddit App/App/RedditAppApp.swift

@@ -22,6 +22,7 @@ struct RedditAppApp: App {
                 }
                 }
         }
         }
         .defaultSize(width: AppWindow.width, height: AppWindow.height)
         .defaultSize(width: AppWindow.width, height: AppWindow.height)
+        .defaultPosition(.center)
         .windowStyle(.hiddenTitleBar)
         .windowStyle(.hiddenTitleBar)
         .commands {
         .commands {
             CommandGroup(replacing: .newItem) {}
             CommandGroup(replacing: .newItem) {}

+ 21 - 0
Reddit App/Utilities/AppWindow.swift

@@ -1,3 +1,4 @@
+import AppKit
 import CoreGraphics
 import CoreGraphics
 
 
 enum AppWindow {
 enum AppWindow {
@@ -11,4 +12,24 @@ enum AppWindow {
 
 
     /// Small top breathing room for the embedded Reddit panel.
     /// Small top breathing room for the embedded Reddit panel.
     static let redditTopInset: CGFloat = 30
     static let redditTopInset: CGFloat = 30
+
+    @MainActor
+    static func centerOnScreen(_ window: NSWindow) {
+        guard !window.styleMask.contains(.fullScreen) else { return }
+
+        let screen = NSScreen.main ?? window.screen
+        guard let screen else {
+            window.center()
+            return
+        }
+
+        var frame = window.frame
+        frame.size = NSSize(width: width, height: height)
+
+        let visible = screen.visibleFrame
+        frame.origin.x = visible.origin.x + ((visible.width - frame.width) / 2)
+        frame.origin.y = visible.origin.y + ((visible.height - frame.height) / 2)
+
+        window.setFrame(frame, display: true)
+    }
 }
 }

+ 2 - 1
Reddit App/Views/Components/MainWindowLifecycleConfigurator.swift

@@ -7,12 +7,13 @@ struct MainWindowLifecycleConfigurator: NSViewRepresentable {
         view.onWindowChange = { window in
         view.onWindowChange = { window in
             guard let window, let delegate = NSApp.delegate as? AppDelegate else { return }
             guard let window, let delegate = NSApp.delegate as? AppDelegate else { return }
             delegate.configureMainWindows()
             delegate.configureMainWindows()
+            delegate.centerMainWindow()
         }
         }
         return view
         return view
     }
     }
 
 
     func updateNSView(_ nsView: WindowObservationView, context: Context) {
     func updateNSView(_ nsView: WindowObservationView, context: Context) {
-        guard let window = nsView.window, let delegate = NSApp.delegate as? AppDelegate else { return }
+        guard nsView.window != nil, let delegate = NSApp.delegate as? AppDelegate else { return }
         delegate.configureMainWindows()
         delegate.configureMainWindows()
     }
     }
 }
 }