Skip to content

Commit a74e3ec

Browse files
committed
🔀 Merge branch develop into subsurface-gestures
2 parents e6e76fe + 891c574 commit a74e3ec

5 files changed

Lines changed: 88 additions & 0 deletions

File tree

‎Loop/Extensions/NSScreen+Extensions.swift‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ extension NSScreen {
2929
let mouseLocation = NSEvent.mouseLocation
3030
let screens = NSScreen.screens
3131

32+
// Ask SkyLight first so we match WindowServer's tie-breaking at display boundaries.
33+
if let primary = screens.first,
34+
let displayID = SkyLightToolBelt.bestManagedDisplayID(forCGPoint: mouseLocation.flipY(screen: primary)),
35+
let match = screens.first(where: { $0.displayID == displayID }) {
36+
return match
37+
}
38+
3239
// CGRect.contains uses half-open intervals [minX, maxX) × [minY, maxY),
3340
// excluding points on the maxX/maxY edges. So we cannot use frame.contains(_:)
3441
return screens.first {

‎Loop/Private APIs/SkyLightSymbolLoader.swift‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,26 @@ extension SkyLightSymbolLoader {
8181
@available(macOS 26.0, *)
8282
static let SLSWindowIteratorGetResolvedCornerRadii: SLSWindowIteratorGetResolvedCornerRadiiFunc? = loadSymbol("SLSWindowIteratorGetResolvedCornerRadii")
8383

84+
typealias SLSFindWindowByGeometryFunc = @convention(c) (
85+
_ cid: SLSConnectionID,
86+
_ filterWindowID: CGWindowID,
87+
_ flags: Int32,
88+
_ reserved: Int32,
89+
_ screenPoint: UnsafePointer<CGPoint>,
90+
_ outWindowPoint: UnsafeMutablePointer<CGPoint>,
91+
_ outWindowID: UnsafeMutablePointer<CGWindowID>,
92+
_ outWindowCID: UnsafeMutablePointer<Int32>
93+
) -> CGError
94+
static let SLSFindWindowByGeometry: SLSFindWindowByGeometryFunc? = loadSymbol("SLSFindWindowByGeometry")
95+
96+
/// Returns the UUID (`CFString`) of the display containing `point`, using the same
97+
/// tie-breaking WindowServer uses internally. `nil` if no managed display contains it.
98+
typealias SLSCopyBestManagedDisplayForPointFunc = @convention(c) (
99+
_ cid: SLSConnectionID,
100+
_ point: CGPoint
101+
) -> Unmanaged<CFString>?
102+
static let SLSCopyBestManagedDisplayForPoint: SLSCopyBestManagedDisplayForPointFunc? = loadSymbol("SLSCopyBestManagedDisplayForPoint")
103+
84104
typealias SLSSetWindowBackgroundBlurRadiusFunc = @convention(c) (_ connection: SLSConnectionID, _ wid: CGWindowID, _ radius: Int) -> OSStatus
85105
static let SLSSetWindowBackgroundBlurRadius: SLSSetWindowBackgroundBlurRadiusFunc? = loadSymbol("SLSSetWindowBackgroundBlurRadius")
86106

‎Loop/Private APIs/SkyLightToolBelt.swift‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,49 @@ enum SkyLightToolBelt {
121121
}
122122
}
123123

124+
/// Returns the display ID containing the given point, using the same tie-breaking
125+
/// WindowServer uses at display boundaries.
126+
/// - Parameter cgPoint: The point in the CoreGraphics coordinate system.
127+
/// - Returns: The matching `CGDirectDisplayID`, or `nil` if the point isn't on any managed display.
128+
static func bestManagedDisplayID(forCGPoint cgPoint: CGPoint) -> CGDirectDisplayID? {
129+
guard let SLSMainConnectionID = SkyLightSymbolLoader.SLSMainConnectionID,
130+
let SLSCopyBestManagedDisplayForPoint = SkyLightSymbolLoader.SLSCopyBestManagedDisplayForPoint
131+
else {
132+
return nil
133+
}
134+
135+
guard let uuidString = SLSCopyBestManagedDisplayForPoint(SLSMainConnectionID(), cgPoint)?.takeRetainedValue(),
136+
let uuid = CFUUIDCreateFromString(nil, uuidString)
137+
else {
138+
return nil
139+
}
140+
141+
let displayID = CGDisplayGetDisplayIDFromUUID(uuid)
142+
return displayID != 0 ? displayID : nil
143+
}
144+
145+
/// Finds the topmost window at a given screen position.
146+
/// - Parameter position: The screen position to check.
147+
/// - Returns: The `CGWindowID` of the window at the position, or `nil` if none found.
148+
static func windowIDAtPosition(_ position: CGPoint) -> CGWindowID? {
149+
guard let SLSMainConnectionID = SkyLightSymbolLoader.SLSMainConnectionID,
150+
let SLSFindWindowByGeometry = SkyLightSymbolLoader.SLSFindWindowByGeometry
151+
else {
152+
return nil
153+
}
154+
155+
let cid = SLSMainConnectionID()
156+
var screenPoint = position
157+
var windowPoint = CGPoint.zero
158+
var hitWindowID: CGWindowID = 0
159+
var windowCID: Int32 = 0
160+
161+
let status = SLSFindWindowByGeometry(cid, 0, 1, 0, &screenPoint, &windowPoint, &hitWindowID, &windowCID)
162+
guard status == .success else { return nil }
163+
164+
return hitWindowID != 0 ? hitWindowID : nil
165+
}
166+
124167
/// Captures images for each of the windows that are passed in.
125168
/// - Parameter windowIDs: The `CGWindowID`s for each of the windows to capture.
126169
/// - Returns: An array of `CGImage`s for each window, in the same order as the windows that were passed in.

‎Loop/Window Management/Window/Window.swift‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ final class Window {
9191
)
9292
}
9393

94+
/// Retrieve a window from a `CGWindowID`.
95+
/// - Parameter windowID: The window ID to look up.
96+
static func fromWindowID(_ windowID: CGWindowID) throws -> Window {
97+
guard let windowInfoList = CGWindowListCopyWindowInfo([.optionIncludingWindow], windowID) as? [[String: AnyObject]],
98+
let windowInfo = windowInfoList.first
99+
else {
100+
throw WindowError.cannotGetWindow
101+
}
102+
103+
return try fromWindowInfo(windowInfo)
104+
}
105+
94106
/// Retrieve a window from an entry in a dictionary returned by `CGWindowListCopyWindowInfo`.
95107
/// - Parameter windowInfo: The dictionary containing information about the window.
96108
static func fromWindowInfo(_ windowInfo: [String: AnyObject]) throws -> Window {

‎Loop/Window Management/Window/WindowUtility.swift‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ enum WindowUtility {
5454
/// - Parameter position: The position to check for
5555
/// - Returns: The window at the given position, if any
5656
static func windowAtPosition(_ position: CGPoint) -> Window? {
57+
// Try SkyLight first, as it is faster and doesn't deadlock on own process
58+
if let windowID = SkyLightToolBelt.windowIDAtPosition(position),
59+
let window = try? Window.fromWindowID(windowID) {
60+
return window
61+
}
62+
5763
do {
5864
// If we can find the window at a point using the Accessibility API, return it
5965
if let element = try AXUIElement.systemWide.getElementAtPosition(position),

0 commit comments

Comments
 (0)