You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Musubi/Packages/MusubiKit/Sources/MusubiCore/DisplayModeSelection.swift

44 lines
1.8 KiB

/// A display mode reduced to what matters for picking one. Mirrors CGDisplayMode.
public struct DisplayModeInfo: Hashable, Sendable {
public var width: Int // points
public var height: Int
public var pixelWidth: Int
public var pixelHeight: Int
public var refreshRate: Double // Hz, 0 for some built-in panels
public init(width: Int, height: Int, pixelWidth: Int, pixelHeight: Int, refreshRate: Double) {
self.width = width
self.height = height
self.pixelWidth = pixelWidth
self.pixelHeight = pixelHeight
self.refreshRate = refreshRate
}
public var isHiDPI: Bool { pixelWidth > width }
}
public enum DisplayModeSelection {
/// Picks the mode with the same size as `current` and a refresh rate within
/// `tolerance` of `targetHz`. Returns nil if `current` already matches or no such mode exists.
public static func mode(
matching targetHz: Double,
current: DisplayModeInfo,
available: [DisplayModeInfo],
tolerance: Double = 0.1
) -> DisplayModeInfo? {
if abs(current.refreshRate - targetHz) <= tolerance { return nil }
return available
.filter {
$0.width == current.width && $0.height == current.height
&& abs($0.refreshRate - targetHz) <= tolerance
}
// Prefer the same backing resolution, then the closest rate.
.min { lhs, rhs in
let lhsSame = lhs.pixelWidth == current.pixelWidth && lhs.pixelHeight == current.pixelHeight
let rhsSame = rhs.pixelWidth == current.pixelWidth && rhs.pixelHeight == current.pixelHeight
if lhsSame != rhsSame { return lhsSame }
return abs(lhs.refreshRate - targetHz) < abs(rhs.refreshRate - targetHz)
}
}
}

Powered by TurnKey Linux.