Mission Control Turbo: macOS multitasking turbocharged
at main 59 lines 1.9 kB view raw
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}