Ariver
2026-06-04 ecba8206e4c8cac76dd3e6f8844204abfda03dfd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import CoreGraphics
import Foundation
 
public struct OverlayScreenSpaceState: Equatable, Sendable {
    public static let unknown = OverlayScreenSpaceState(isFullscreenSpace: false, isSplitViewSpace: false)
 
    public let isFullscreenSpace: Bool
    public let isSplitViewSpace: Bool
 
    public init(isFullscreenSpace: Bool = false, isSplitViewSpace: Bool = false) {
        self.isFullscreenSpace = isFullscreenSpace
        self.isSplitViewSpace = isSplitViewSpace
    }
}
 
public struct OverlayScreenRecord: Equatable, Sendable {
    public let displayUUID: String
    public let frame: CGRect
    public let visibleFrame: CGRect
    public let isFullscreenSpace: Bool
    public let isSplitViewSpace: Bool
 
    public init(
        displayUUID: String,
        frame: CGRect,
        visibleFrame: CGRect,
        isFullscreenSpace: Bool = false,
        isSplitViewSpace: Bool = false
    ) {
        self.displayUUID = displayUUID
        self.frame = frame
        self.visibleFrame = visibleFrame
        self.isFullscreenSpace = isFullscreenSpace
        self.isSplitViewSpace = isSplitViewSpace
    }
 
    public init(
        displayUUID: String,
        frame: CGRect,
        visibleFrame: CGRect,
        spaceState: OverlayScreenSpaceState
    ) {
        self.init(
            displayUUID: displayUUID,
            frame: frame,
            visibleFrame: visibleFrame,
            isFullscreenSpace: spaceState.isFullscreenSpace,
            isSplitViewSpace: spaceState.isSplitViewSpace
        )
    }
}
 
public struct OverlayPlacementContext: Equatable, Sendable {
    public let targetDisplayUUID: String?
    public let targetFrame: CGRect?
    public let mouseLocation: CGPoint
    public let coverFullscreenSpace: Bool
    public let isFullscreenSpace: Bool
    public let isSplitViewSpace: Bool
    public let avoidSpaceSwitch: Bool
 
    public init(
        targetDisplayUUID: String?,
        targetFrame: CGRect?,
        mouseLocation: CGPoint,
        coverFullscreenSpace: Bool = true,
        isFullscreenSpace: Bool = false,
        isSplitViewSpace: Bool = false,
        avoidSpaceSwitch: Bool = true
    ) {
        self.targetDisplayUUID = targetDisplayUUID
        self.targetFrame = targetFrame
        self.mouseLocation = mouseLocation
        self.coverFullscreenSpace = coverFullscreenSpace
        self.isFullscreenSpace = isFullscreenSpace
        self.isSplitViewSpace = isSplitViewSpace
        self.avoidSpaceSwitch = avoidSpaceSwitch
    }
 
    public var overlayContext: OverlayContext {
        OverlayContext(
            entryPoint: .quickSwitch,
            spacePolicy: SpacePolicy(isFullscreenSpace: isFullscreenSpace, avoidSpaceSwitch: avoidSpaceSwitch),
            targetDisplayUUID: targetDisplayUUID
        )
    }
}
 
public enum OverlayPlacementPolicy {
    public static func placement(
        forMouseLocation mouseLocation: CGPoint,
        screens: [OverlayScreenRecord]
    ) -> OverlayPlacementContext {
        let targetScreen = screen(containing: mouseLocation, screens: screens) ?? screens.first
 
        return OverlayPlacementContext(
            targetDisplayUUID: targetScreen?.displayUUID,
            targetFrame: targetScreen?.frame,
            mouseLocation: mouseLocation,
            coverFullscreenSpace: true,
            isFullscreenSpace: targetScreen?.isFullscreenSpace ?? false,
            isSplitViewSpace: targetScreen?.isSplitViewSpace ?? false,
            avoidSpaceSwitch: true
        )
    }
 
    private static func screen(
        containing point: CGPoint,
        screens: [OverlayScreenRecord]
    ) -> OverlayScreenRecord? {
        screens.first { screen in
            screen.frame.contains(point)
        }
    }
}