Skip to content

Commit a934fdd

Browse files
committed
feat: move positioning logic to Core/
1 parent 51ef84b commit a934fdd

File tree

3 files changed

+76
-36
lines changed

3 files changed

+76
-36
lines changed

Core/Sources/Core/Windows/WindowPositioning.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,39 @@ public enum WindowPositioning {
9595

9696
return frame
9797
}
98+
99+
public static func promptWindowOrigin(
100+
cursorLocation: Point,
101+
windowSize: Size,
102+
screenRect: Rect,
103+
offsetX: Double = 10,
104+
belowOffset: Double = 20,
105+
aboveOffset: Double = 30,
106+
padding: Double = 20
107+
) -> Point {
108+
var origin = cursorLocation
109+
origin.x += offsetX
110+
origin.y -= windowSize.height + belowOffset
111+
112+
if origin.x + windowSize.width + padding > screenRect.maxX {
113+
origin.x = screenRect.maxX - windowSize.width - padding
114+
}
115+
116+
if origin.x < screenRect.minX + padding {
117+
origin.x = screenRect.minX + padding
118+
}
119+
120+
if origin.y < screenRect.minY + padding {
121+
origin.y = cursorLocation.y + aboveOffset
122+
if origin.y + windowSize.height + padding > screenRect.maxY {
123+
origin.y = screenRect.maxY - windowSize.height - padding
124+
}
125+
}
126+
127+
if origin.y + windowSize.height + padding > screenRect.maxY {
128+
origin.y = screenRect.maxY - windowSize.height - padding
129+
}
130+
131+
return origin
132+
}
98133
}

Core/Tests/CoreTests/WindowsTests/WindowPositioningTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,37 @@ import Testing
7070
#expect(frame.origin == WindowPositioning.Point(x: 70, y: 10))
7171
#expect(frame.size == currentFrame.size)
7272
}
73+
74+
@Test func testPromptWindowOriginMovesAboveWhenBelowWouldOverflow() async throws {
75+
let screenRect = WindowPositioning.Rect(
76+
origin: .init(x: 0, y: 0),
77+
size: .init(width: 100, height: 100)
78+
)
79+
let cursorLocation = WindowPositioning.Point(x: 10, y: 10)
80+
let windowSize = WindowPositioning.Size(width: 40, height: 30)
81+
82+
let origin = WindowPositioning.promptWindowOrigin(
83+
cursorLocation: cursorLocation,
84+
windowSize: windowSize,
85+
screenRect: screenRect
86+
)
87+
88+
#expect(origin == WindowPositioning.Point(x: 20, y: 40))
89+
}
90+
91+
@Test func testPromptWindowOriginClampsToRightEdge() async throws {
92+
let screenRect = WindowPositioning.Rect(
93+
origin: .init(x: 0, y: 0),
94+
size: .init(width: 100, height: 100)
95+
)
96+
let cursorLocation = WindowPositioning.Point(x: 95, y: 50)
97+
let windowSize = WindowPositioning.Size(width: 40, height: 30)
98+
99+
let origin = WindowPositioning.promptWindowOrigin(
100+
cursorLocation: cursorLocation,
101+
windowSize: windowSize,
102+
screenRect: screenRect
103+
)
104+
105+
#expect(origin == WindowPositioning.Point(x: 40, y: 50))
106+
}

azooKeyMac/Windows/PromptInput/PromptInputWindow.swift

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Cocoa
2+
import Core
23
import Foundation
34
import SwiftUI
45

@@ -151,42 +152,12 @@ final class PromptInputWindow: NSWindow {
151152
return cursorLocation
152153
}
153154

154-
let screenFrame = screen.visibleFrame
155-
var origin = cursorLocation
156-
157-
// Offset slightly below and to the right of cursor
158-
origin.x += 10
159-
origin.y -= windowSize.height + 20
160-
161-
// Ensure window stays within screen bounds with padding
162-
let padding: CGFloat = 20
163-
164-
// Check right edge
165-
if origin.x + windowSize.width + padding > screenFrame.maxX {
166-
origin.x = screenFrame.maxX - windowSize.width - padding
167-
}
168-
169-
// Check left edge
170-
if origin.x < screenFrame.minX + padding {
171-
origin.x = screenFrame.minX + padding
172-
}
173-
174-
// Check bottom edge - if too low, show above cursor
175-
if origin.y < screenFrame.minY + padding {
176-
origin.y = cursorLocation.y + 30
177-
178-
// If still doesn't fit above, position at screen edge
179-
if origin.y + windowSize.height + padding > screenFrame.maxY {
180-
origin.y = screenFrame.maxY - windowSize.height - padding
181-
}
182-
}
183-
184-
// Check top edge
185-
if origin.y + windowSize.height + padding > screenFrame.maxY {
186-
origin.y = screenFrame.maxY - windowSize.height - padding
187-
}
188-
189-
return origin
155+
let origin = WindowPositioning.promptWindowOrigin(
156+
cursorLocation: WindowPositioning.Point(cursorLocation),
157+
windowSize: WindowPositioning.Size(windowSize),
158+
screenRect: WindowPositioning.Rect(screen.visibleFrame)
159+
)
160+
return origin.cgPoint
190161
}
191162

192163
override func close() {

0 commit comments

Comments
 (0)