Mission Control Turbo: macOS multitasking turbocharged
1import Foundation
2
3/// Persisted layout positions using normalized (0..1) coordinates.
4/// Survives resolution changes and provides stability across activations.
5struct LayoutPosition: Codable, Equatable {
6 let normalizedX: Double
7 let normalizedY: Double
8 let normalizedWidth: Double
9 let normalizedHeight: Double
10
11 func absoluteRect(in bounds: CGRect) -> CGRect {
12 CGRect(
13 x: bounds.origin.x + normalizedX * bounds.width,
14 y: bounds.origin.y + normalizedY * bounds.height,
15 width: normalizedWidth * bounds.width,
16 height: normalizedHeight * bounds.height
17 )
18 }
19
20 static func from(rect: CGRect, in bounds: CGRect) -> LayoutPosition {
21 LayoutPosition(
22 normalizedX: (rect.origin.x - bounds.origin.x) / bounds.width,
23 normalizedY: (rect.origin.y - bounds.origin.y) / bounds.height,
24 normalizedWidth: rect.width / bounds.width,
25 normalizedHeight: rect.height / bounds.height
26 )
27 }
28}
29
30/// Stores the full layout state for a screen configuration.
31final class LayoutState {
32 /// Maps window fingerprint key to its normalized position.
33 private(set) var positions: [String: LayoutPosition] = [:]
34
35 /// The fingerprint of the last snapshot used for layout.
36 private(set) var lastFingerprint: Set<String> = []
37
38 func store(key: String, position: LayoutPosition) {
39 positions[key] = position
40 }
41
42 func position(for key: String) -> LayoutPosition? {
43 positions[key]
44 }
45
46 func updateFingerprint(_ fingerprint: Set<String>) {
47 lastFingerprint = fingerprint
48 }
49
50 func clear() {
51 positions.removeAll()
52 lastFingerprint.removeAll()
53 }
54
55 /// Remove positions for keys no longer present.
56 func prune(keeping keys: Set<String>) {
57 positions = positions.filter { keys.contains($0.key) }
58 }
59}