fix: persist window centers and preserve them across tool size changes
This commit is contained in:
@@ -159,6 +159,8 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
|
||||
updateResults()
|
||||
if let command {
|
||||
executeCommand(command)
|
||||
// Validate the final size; compact Notes may fit where the launcher did not.
|
||||
if command == .notes { restorePosition() }
|
||||
}
|
||||
window?.deminiaturize(nil)
|
||||
showWindow(nil)
|
||||
@@ -203,22 +205,22 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
|
||||
|
||||
private func savePosition() {
|
||||
guard launcherFrameBeforeReview == nil, let window, let screen = window.screen, let identifier = displayIdentifier(screen) else { return }
|
||||
UserDefaults.standard.set([
|
||||
"display": identifier, "x": window.frame.minX, "y": window.frame.minY
|
||||
defaults.set([
|
||||
"display": identifier, "centerX": window.frame.midX, "centerY": window.frame.midY
|
||||
], forKey: Self.positionKey)
|
||||
}
|
||||
|
||||
private func restorePosition() {
|
||||
guard let window else { return }
|
||||
let saved = UserDefaults.standard.dictionary(forKey: Self.positionKey)
|
||||
let saved = defaults.dictionary(forKey: Self.positionKey)
|
||||
let savedScreen = NSScreen.screens.first { displayIdentifier($0) == saved?["display"] as? String }
|
||||
guard let screen = savedScreen ?? NSScreen.main ?? NSScreen.screens.first else { return }
|
||||
var origin: CGPoint?
|
||||
if savedScreen != nil, let x = saved?["x"] as? Double, let y = saved?["y"] as? Double {
|
||||
origin = CGPoint(x: x, y: y)
|
||||
var center: CGPoint?
|
||||
if savedScreen != nil, let x = saved?["centerX"] as? Double, let y = saved?["centerY"] as? Double {
|
||||
center = CGPoint(x: x, y: y)
|
||||
}
|
||||
let frame = LauncherAlignment.restoredFrame(
|
||||
savedOrigin: origin, windowSize: window.frame.size, visibleFrame: screen.visibleFrame
|
||||
savedCenter: center, windowSize: window.frame.size, visibleFrame: screen.visibleFrame
|
||||
)
|
||||
if window.frame.origin != frame.origin { window.setFrameOrigin(frame.origin) }
|
||||
}
|
||||
@@ -919,11 +921,14 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
|
||||
self.searchField.isHidden = false
|
||||
self.launcherViews.first?.isHidden = false
|
||||
self.launcherViews.first?.setAccessibilityHidden(false)
|
||||
if command == .notes, let previousFrame {
|
||||
self.window?.styleMask = [.borderless]
|
||||
self.window?.minSize = .zero
|
||||
self.window?.appearance = NSAppearance(named: .darkAqua)
|
||||
self.window?.setFrame(previousFrame, display: true)
|
||||
if command == .notes, let previousFrame, let window = self.window {
|
||||
let frame = LauncherAlignment.restoredFrame(
|
||||
savedCenter: CGPoint(x: window.frame.midX, y: window.frame.midY),
|
||||
windowSize: previousFrame.size, visibleFrame: window.screen?.visibleFrame ?? previousFrame)
|
||||
window.styleMask = [.borderless]
|
||||
window.minSize = .zero
|
||||
window.appearance = NSAppearance(named: .darkAqua)
|
||||
window.setFrame(frame, display: true)
|
||||
if let material = content as? NSVisualEffectView { roundMaterialCorners(material, radius: 24) }
|
||||
}
|
||||
self.activeCommand = nil
|
||||
@@ -970,14 +975,14 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
|
||||
window?.standardWindowButton(.zoomButton)?.isHidden = true
|
||||
launcherViews.first?.isHidden = true
|
||||
launcherViews.first?.setAccessibilityHidden(true)
|
||||
if var frame = window?.frame {
|
||||
let available = window?.screen?.visibleFrame.size ?? savedSize
|
||||
let size = NSSize(width: min(max(savedSize.width, 570), available.width),
|
||||
height: min(max(savedSize.height, 260), available.height))
|
||||
frame.origin.x += (frame.width - size.width) / 2
|
||||
frame.origin.y = frame.maxY - size.height
|
||||
frame.size = size
|
||||
window?.setFrame(frame, display: true)
|
||||
if let previousFrame, let window {
|
||||
let visibleFrame = window.screen?.visibleFrame ?? previousFrame
|
||||
let size = NSSize(width: min(max(savedSize.width, 570), visibleFrame.width),
|
||||
height: min(max(savedSize.height, 260), visibleFrame.height))
|
||||
let frame = LauncherAlignment.restoredFrame(
|
||||
savedCenter: CGPoint(x: previousFrame.midX, y: previousFrame.midY),
|
||||
windowSize: size, visibleFrame: visibleFrame)
|
||||
window.setFrame(frame, display: true)
|
||||
}
|
||||
if let material = content as? NSVisualEffectView { roundMaterialCorners(material, radius: 14) }
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ public struct LauncherAlignment: Sendable {
|
||||
)
|
||||
}
|
||||
|
||||
public static func restoredFrame(savedOrigin: CGPoint?, windowSize: CGSize, visibleFrame: CGRect) -> CGRect {
|
||||
if let savedOrigin, savedOrigin.x.isFinite, savedOrigin.y.isFinite {
|
||||
let saved = CGRect(origin: savedOrigin, size: windowSize)
|
||||
public static func restoredFrame(savedCenter: CGPoint?, windowSize: CGSize, visibleFrame: CGRect) -> CGRect {
|
||||
if let savedCenter, savedCenter.x.isFinite, savedCenter.y.isFinite {
|
||||
let saved = CGRect(x: savedCenter.x - windowSize.width / 2,
|
||||
y: savedCenter.y - windowSize.height / 2,
|
||||
width: windowSize.width, height: windowSize.height)
|
||||
if visibleFrame.contains(saved) { return saved }
|
||||
}
|
||||
var frame = LauncherAlignment(
|
||||
|
||||
Reference in New Issue
Block a user