Mission Control Turbo: macOS multitasking turbocharged
at main 93 lines 3.5 kB view raw
1import Foundation 2 3/// Pure geometry helpers for the layout engine. 4enum LayoutGeometry { 5 static let margin: CGFloat = 40 6 static let itemSpacing: CGFloat = 16 7 static let titleHeight: CGFloat = 36 8 static let minThumbnailWidth: CGFloat = 120 9 10 /// Find the optimal column count and thumbnail width for a flat grid of windows. 11 /// Tries each column count and picks the one that produces the largest thumbnails 12 /// while fitting everything on screen. 13 static func optimalGrid( 14 windows: [WindowInfo], 15 availableWidth: CGFloat, 16 availableHeight: CGFloat 17 ) -> (width: CGFloat, columns: Int) { 18 let count = windows.count 19 guard count > 0 else { return (200, 1) } 20 21 let maxCols = max(1, Int((availableWidth + itemSpacing) / (minThumbnailWidth + itemSpacing))) 22 23 var bestWidth: CGFloat = 0 24 var bestCols = 1 25 26 for cols in 1...maxCols { 27 let thumbWidth = (availableWidth - CGFloat(cols - 1) * itemSpacing) / CGFloat(cols) 28 guard thumbWidth >= minThumbnailWidth else { continue } 29 30 let needed = totalHeight(windows: windows, thumbWidth: thumbWidth, cols: cols) 31 if needed <= availableHeight && thumbWidth > bestWidth { 32 bestWidth = thumbWidth 33 bestCols = cols 34 } 35 } 36 37 // Binary search fallback if nothing fit 38 if bestWidth == 0 { 39 var lo: CGFloat = 20 40 var hi = availableWidth 41 42 for _ in 0..<40 { 43 let mid = (lo + hi) / 2 44 let cols = max(1, Int((availableWidth + itemSpacing) / (mid + itemSpacing))) 45 let needed = totalHeight(windows: windows, thumbWidth: mid, cols: cols) 46 47 if needed <= availableHeight { 48 bestWidth = mid 49 bestCols = cols 50 lo = mid 51 } else { 52 hi = mid 53 } 54 } 55 56 if bestWidth == 0 { 57 bestCols = max(1, Int(ceil(sqrt(Double(count))))) 58 bestWidth = max(20, (availableWidth - CGFloat(bestCols - 1) * itemSpacing) / CGFloat(bestCols)) 59 } 60 } 61 62 return (bestWidth, bestCols) 63 } 64 65 /// Compute total height for a flat grid layout. 66 static func totalHeight(windows: [WindowInfo], thumbWidth: CGFloat, cols: Int) -> CGFloat { 67 let rowCount = Int(ceil(Double(windows.count) / Double(cols))) 68 var height: CGFloat = 0 69 70 for row in 0..<rowCount { 71 let start = row * cols 72 let end = min(start + cols, windows.count) 73 var maxRowH: CGFloat = 0 74 for idx in start..<end { 75 let w = windows[idx] 76 let ratio = w.frame.width > 0 ? w.frame.height / w.frame.width : 0.625 77 let cellH = thumbWidth * ratio + titleHeight 78 maxRowH = max(maxRowH, cellH) 79 } 80 height += maxRowH 81 if row < rowCount - 1 { height += itemSpacing } 82 } 83 84 return height 85 } 86 87 /// Fit a source rect into a target rect maintaining aspect ratio. 88 static func aspectFit(source: CGSize, target: CGSize) -> CGSize { 89 guard source.width > 0, source.height > 0 else { return target } 90 let scale = min(target.width / source.width, target.height / source.height) 91 return CGSize(width: source.width * scale, height: source.height * scale) 92 } 93}