import CoreGraphics import MusubiCore import OSLog /// Switches a display to a target refresh rate for the lifetime of the app and restores it on request. public enum DisplayModeSwitcher { private static let log = Logger(subsystem: "studio.zielke.musubi", category: "display") /// Returns the refresh rate in effect afterwards, and the original mode to restore later (nil if unchanged). @discardableResult public static func setRefreshRate(_ hz: Double, on display: CGDirectDisplayID) -> (refreshRate: Double, original: CGDisplayMode?) { guard let current = CGDisplayCopyDisplayMode(display) else { return (0, nil) } let options = [kCGDisplayShowDuplicateLowResolutionModes: true] as CFDictionary let modes = (CGDisplayCopyAllDisplayModes(display, options) as? [CGDisplayMode]) ?? [] guard let target = DisplayModeSelection.mode(matching: hz, current: info(current), available: modes.map(info)), let mode = modes.first(where: { info($0) == target }) else { if abs(current.refreshRate - hz) > 0.1 { log.notice("Display \(display): no \(hz) Hz mode, staying at \(current.refreshRate) Hz") } return (current.refreshRate, nil) } guard apply(mode, to: display) else { return (current.refreshRate, nil) } log.info("Display \(display): \(current.refreshRate) Hz → \(mode.refreshRate) Hz") return (mode.refreshRate, current) } public static func restore(_ mode: CGDisplayMode, on display: CGDirectDisplayID) { if apply(mode, to: display) { log.info("Display \(display): restored \(mode.refreshRate) Hz") } } public static func currentRefreshRate(of display: CGDirectDisplayID) -> Double { CGDisplayCopyDisplayMode(display)?.refreshRate ?? 0 } private static func apply(_ mode: CGDisplayMode, to display: CGDirectDisplayID) -> Bool { var config: CGDisplayConfigRef? guard CGBeginDisplayConfiguration(&config) == .success else { return false } CGConfigureDisplayWithDisplayMode(config, display, mode, nil) // .forAppOnly: macOS reverts the mode when Musubi quits or crashes. let result = CGCompleteDisplayConfiguration(config, .forAppOnly) if result != .success { log.error("Display \(display): mode change failed (\(result.rawValue))") } return result == .success } private static func info(_ mode: CGDisplayMode) -> DisplayModeInfo { DisplayModeInfo(width: mode.width, height: mode.height, pixelWidth: mode.pixelWidth, pixelHeight: mode.pixelHeight, refreshRate: mode.refreshRate) } }