From e4c038a23424b769c60428d6bcee0a43ee2525e8 Mon Sep 17 00:00:00 2001 From: kamaal hassan Date: Thu, 2 Apr 2026 23:51:16 -0400 Subject: [PATCH 1/3] Fix Mission Control visibility, brightness controls, and cursor dimming - Lower window level from .screenSaver (1000) to custom 200 to avoid macOS special-casing during Mission Control that hides the overlay, and to prevent cursor compositing interference that dims the mouse pointer - Add activeSpaceDidChangeNotification observer to reassert overlay after Mission Control or space switches (fixes #8) - Track EDR headroom changes in watchdog (1.5s interval, down from 3s) so keyboard brightness adjustments dynamically clamp the boost level instead of exceeding available headroom - Deactivate gracefully when EDR headroom drops to 1.0 (very low brightness) - Add .ignoresCycle and .animationBehavior = .none to prevent the overlay from appearing in Mission Control window list and animation glitches - Fix kill switch: use pgrep + targeted kill instead of pkill to avoid the --kill process terminating itself - Add screen wake observer with delay for correct EDR reporting - Extract reassertOverlay() and updateBoostMenuState() to reduce duplication Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/main.swift | 168 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 32 deletions(-) diff --git a/Sources/main.swift b/Sources/main.swift index 30ecb6f..debd7d5 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -4,14 +4,24 @@ import Carbon.HIToolbox // MARK: - Kill switch: `xdr-boost --kill` terminates any running instance if CommandLine.arguments.contains("--kill") || CommandLine.arguments.contains("-k") { + let myPID = ProcessInfo.processInfo.processIdentifier let pipe = Pipe() let proc = Process() - proc.executableURL = URL(fileURLWithPath: "/usr/bin/pkill") + proc.executableURL = URL(fileURLWithPath: "/usr/bin/pgrep") proc.arguments = ["-f", "xdr-boost"] proc.standardOutput = pipe - proc.standardError = pipe + proc.standardError = Pipe() try? proc.run() proc.waitUntilExit() + + let data = pipe.fileHandleForReading.readDataToEndOfFile() + if let output = String(data: data, encoding: .utf8) { + for line in output.split(separator: "\n") { + if let pid = Int32(line.trimmingCharacters(in: .whitespaces)), pid != myPID { + kill(pid, SIGTERM) + } + } + } fputs("All xdr-boost instances killed\n", stderr) exit(0) } @@ -32,6 +42,13 @@ class Renderer: NSObject, MTKViewDelegate { } } +// Use a high window level that avoids macOS special-casing of .screenSaver during +// Mission Control, while still sitting above all normal app windows and panels. +// .screenSaver (1000) triggers window hiding/reordering during Mission Control and +// can interfere with cursor compositing. Level 200 is well above .popUpMenu (101) +// but safely below any system-reserved levels. +private let kOverlayWindowLevel = NSWindow.Level(rawValue: 200) + class XDRApp: NSObject, NSApplicationDelegate { var statusItem: NSStatusItem! var overlayWindow: NSWindow? @@ -65,7 +82,7 @@ class XDRApp: NSObject, NSApplicationDelegate { setupStatusBar() registerGlobalHotkey() - observeSleepWake() + observeSystemEvents() fputs("XDR Boost ready — click menu bar icon or press Ctrl+Option+Cmd+V to toggle\n", stderr) fputs("Emergency kill: run `xdr-boost --kill` or press Ctrl+Option+Cmd+V\n", stderr) fputs("Max EDR: \(maxEDR)x\n", stderr) @@ -150,35 +167,116 @@ class XDRApp: NSObject, NSApplicationDelegate { statusItem.menu = menu } - // MARK: - Watchdog & Display Changes + // MARK: - System Event Observers + + func observeSystemEvents() { + let nc = NotificationCenter.default + let wnc = NSWorkspace.shared.notificationCenter - func observeSleepWake() { // Display config changed (resolution, arrangement, external monitors) - NotificationCenter.default.addObserver( - self, selector: #selector(handleDisplayChange), - name: NSApplication.didChangeScreenParametersNotification, object: nil) - - // Watchdog: every 3 seconds, check if XDR should be on but overlay is dead - // This handles sleep/wake, lid close/open, lock/unlock — all of them - watchdogTimer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { [weak self] _ in - guard let self = self, self.shouldBeActive else { return } - - if let window = self.overlayWindow { - // Window exists — just make sure it's visible and in front - if !window.isVisible { - window.orderFrontRegardless() - fputs("Watchdog — window restored\n", stderr) - } - } else { - // Window is gone (nil) — need to fully recreate - self.isActive = false - self.maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 - if self.maxEDR > 1.0 { - self.activate() - fputs("Watchdog — XDR recreated\n", stderr) + nc.addObserver(self, selector: #selector(handleDisplayChange), + name: NSApplication.didChangeScreenParametersNotification, object: nil) + + // Space / Mission Control changes — fires when exiting Mission Control or switching spaces + wnc.addObserver(self, selector: #selector(handleSpaceChange), + name: NSWorkspace.activeSpaceDidChangeNotification, object: nil) + + // Screen sleep/wake — EDR headroom resets after wake + wnc.addObserver(self, selector: #selector(handleScreenWake), + name: NSWorkspace.screensDidWakeNotification, object: nil) + + // Watchdog: every 1.5 seconds, verify overlay health and track EDR headroom changes + // (handles brightness keyboard adjustments, sleep/wake, lid close/open, lock/unlock) + watchdogTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { [weak self] _ in + self?.watchdogCheck() + } + } + + func watchdogCheck() { + // Track EDR headroom changes from keyboard brightness controls + let currentMaxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 + if currentMaxEDR != maxEDR { + let oldMax = maxEDR + maxEDR = currentMaxEDR + fputs("EDR headroom changed: \(oldMax)x → \(maxEDR)x\n", stderr) + + // Clamp boost level if it now exceeds available headroom + if boostLevel > Double(maxEDR) && maxEDR > 1.0 { + boostLevel = Double(maxEDR) + updateBoostMenuState() + if isActive, let view = boostView { + view.clearColor = MTLClearColor(red: boostLevel, green: boostLevel, blue: boostLevel, alpha: 1.0) + fputs("Boost clamped to \(boostLevel)x\n", stderr) } } } + + guard shouldBeActive else { return } + + // EDR no longer available (brightness too low or display changed) + if maxEDR <= 1.0 { + if isActive { + deactivate() + fputs("Watchdog — EDR unavailable, deactivated\n", stderr) + } + return + } + + if let window = overlayWindow { + // Window exists — make sure it's visible and correctly sized + if !window.isVisible { + window.orderFrontRegardless() + fputs("Watchdog — window restored\n", stderr) + } + if let screen = NSScreen.main, window.frame != screen.frame { + window.setFrame(screen.frame, display: true) + fputs("Watchdog — resized to match screen\n", stderr) + } + } else { + // Window is gone — need to fully recreate + isActive = false + if maxEDR > 1.0 { + activate() + fputs("Watchdog — XDR recreated\n", stderr) + } + } + } + + @objc func handleSpaceChange() { + guard shouldBeActive else { return } + // Short delay to let Mission Control / space switch animation finish + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in + self?.reassertOverlay() + } + } + + @objc func handleScreenWake() { + guard shouldBeActive else { return } + // Delay to let the display fully wake and report correct EDR values + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in + guard let self = self else { return } + self.maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 + self.reassertOverlay() + } + } + + /// Re-assert the overlay window after system events (Mission Control, space change, wake). + /// Recreates it if it was destroyed, otherwise ensures it's visible and correctly sized. + func reassertOverlay() { + guard shouldBeActive else { return } + if let window = overlayWindow { + if let screen = NSScreen.main { + window.setFrame(screen.frame, display: false) + } + window.orderFrontRegardless() + } else { + isActive = false + maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 + if maxEDR > 1.0 { + activate() + fputs("Overlay reasserted\n", stderr) + } + } } @objc func handleDisplayChange() { @@ -208,15 +306,20 @@ class XDRApp: NSObject, NSApplicationDelegate { @objc func setBoostLevel(_ sender: NSMenuItem) { boostLevel = Double(sender.tag) / 100.0 - for item in boostItems { - item.state = (item.tag == sender.tag) ? .on : .off - } + updateBoostMenuState() if isActive, let view = boostView { // Update in-place — no teardown, no flash view.clearColor = MTLClearColor(red: boostLevel, green: boostLevel, blue: boostLevel, alpha: 1.0) } } + func updateBoostMenuState() { + let currentTag = Int(boostLevel * 100) + for item in boostItems { + item.state = (item.tag == currentTag) ? .on : .off + } + } + // MARK: - XDR Overlay func activate() { @@ -224,14 +327,15 @@ class XDRApp: NSObject, NSApplicationDelegate { let frame = screen.frame let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false) - window.level = .screenSaver + window.level = kOverlayWindowLevel window.backgroundColor = .clear window.isOpaque = false window.hasShadow = false window.ignoresMouseEvents = true window.hidesOnDeactivate = false window.sharingType = .none // exclude from screenshots and screen recordings - window.collectionBehavior = [.canJoinAllSpaces, .stationary, .fullScreenAuxiliary] + window.animationBehavior = .none // prevent animation glitches during Mission Control + window.collectionBehavior = [.canJoinAllSpaces, .stationary, .fullScreenAuxiliary, .ignoresCycle] // Single MTKView that both triggers EDR and provides the boost let boostView = MTKView(frame: frame, device: device) From 18cdf1ba3b06c34fc37166b81ef2e1c156c2038f Mon Sep 17 00:00:00 2001 From: kamaal hassan Date: Thu, 2 Apr 2026 23:52:59 -0400 Subject: [PATCH 2/3] Fix quit not staying quit: only restart on crash, not intentional exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KeepAlive was set to unconditional true, so launchd restarted xdr-boost every time it exited — including user-initiated Quit and --kill. Changed to SuccessfulExit: false so launchd only restarts on crashes (non-zero exit code), not on clean exits (exit 0). Co-Authored-By: Claude Opus 4.6 (1M context) --- com.xdr-boost.agent.plist | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com.xdr-boost.agent.plist b/com.xdr-boost.agent.plist index 72d126c..9f47852 100644 --- a/com.xdr-boost.agent.plist +++ b/com.xdr-boost.agent.plist @@ -11,7 +11,10 @@ RunAtLoad KeepAlive - + + SuccessfulExit + + ProcessType Interactive From 0621694f7f2f5cd8dbecbbfecc97d6e4b67994d6 Mon Sep 17 00:00:00 2001 From: kamaal hassan Date: Fri, 3 Apr 2026 00:04:01 -0400 Subject: [PATCH 3/3] Fix flickering, restore Mission Control handling, polish brightness integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root causes of flicker: - handleDisplayChange did a full deactivate/reactivate cycle, causing a visible flash every time brightness keys were pressed - Watchdog at 1.5s was comparing frames with display:true, forcing redraws - Exact float comparison on maxEDR fired on tiny jitter - Multiple event handlers could overlap with no debouncing Fixes: - handleDisplayChange now updates overlay IN-PLACE (resize frame, update clear color) instead of destroy/recreate — no more flash - Restore .screenSaver window level (200 was too low and got caught in Mission Control window management) - Separate boostLevel (user's choice) from effectiveBoost (clamped to maxEDR) so the user's preference is preserved when headroom fluctuates - Use epsilon (0.05) for float comparisons to avoid jitter-triggered updates - Add debouncing via DispatchWorkItem for reassert calls - Watchdog back to 3s as a safety net — event observers handle time-sensitive recovery (space change, screen wake) - Watchdog no longer touches window frame — only checks visibility - Menu bar shows "☀︎ 2.0x" when active, plain "☀" when off - Menu shows EDR headroom info - Better toggle labels ("Turn On/Off XDR Boost") Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/main.swift | 250 +++++++++++++++++++++++++-------------------- 1 file changed, 142 insertions(+), 108 deletions(-) diff --git a/Sources/main.swift b/Sources/main.swift index debd7d5..079d9f3 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -42,13 +42,6 @@ class Renderer: NSObject, MTKViewDelegate { } } -// Use a high window level that avoids macOS special-casing of .screenSaver during -// Mission Control, while still sitting above all normal app windows and panels. -// .screenSaver (1000) triggers window hiding/reordering during Mission Control and -// can interfere with cursor compositing. Level 200 is well above .popUpMenu (101) -// but safely below any system-reserved levels. -private let kOverlayWindowLevel = NSWindow.Level(rawValue: 200) - class XDRApp: NSObject, NSApplicationDelegate { var statusItem: NSStatusItem! var overlayWindow: NSWindow? @@ -57,7 +50,8 @@ class XDRApp: NSObject, NSApplicationDelegate { var boostRenderer: Renderer? var isActive = false var shouldBeActive = false // tracks user intent across sleep/lock cycles - var boostLevel: Double = 2.0 + var boostLevel: Double = 2.0 // user's chosen level — never mutated by clamping + var effectiveBoost: Double = 2.0 // actual level after clamping to maxEDR var maxEDR: CGFloat = 1.0 var hotkeyRef: EventHotKeyRef? var watchdogTimer: Timer? @@ -65,6 +59,10 @@ class XDRApp: NSObject, NSApplicationDelegate { var toggleItem: NSMenuItem! var shortcutItem: NSMenuItem! var boostItems: [NSMenuItem] = [] + var edrInfoItem: NSMenuItem! + + // Debouncing to prevent overlapping reassert calls + var pendingReassert: DispatchWorkItem? func applicationDidFinishLaunching(_ notification: Notification) { guard let dev = MTLCreateSystemDefaultDevice() else { @@ -79,6 +77,7 @@ class XDRApp: NSObject, NSApplicationDelegate { if CommandLine.arguments.count > 1, let v = Double(CommandLine.arguments[1]) { boostLevel = min(max(v, 1.0), Double(maxEDR)) } + effectiveBoost = min(boostLevel, Double(maxEDR)) setupStatusBar() registerGlobalHotkey() @@ -106,7 +105,6 @@ class XDRApp: NSObject, NSApplicationDelegate { if status == noErr { hotkeyRef = ref - // Install Carbon event handler for hotkey var eventType = EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)) InstallEventHandler(GetApplicationEventTarget(), { (_, event, userData) -> OSStatus in let app = Unmanaged.fromOpaque(userData!).takeUnretainedValue() @@ -122,22 +120,24 @@ class XDRApp: NSObject, NSApplicationDelegate { func setupStatusBar() { statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) - if let button = statusItem.button { - button.title = "☀" - } + updateStatusBarIcon() let menu = NSMenu() - toggleItem = NSMenuItem(title: "Turn On", action: #selector(toggleXDR), keyEquivalent: "b") + toggleItem = NSMenuItem(title: "Turn On XDR Boost", action: #selector(toggleXDR), keyEquivalent: "b") toggleItem.target = self menu.addItem(toggleItem) - shortcutItem = NSMenuItem(title: "Shortcut: Ctrl+Option+Cmd+V", action: nil, keyEquivalent: "") + shortcutItem = NSMenuItem(title: "⌃⌥⌘V", action: nil, keyEquivalent: "") shortcutItem.isEnabled = false menu.addItem(shortcutItem) menu.addItem(NSMenuItem.separator()) + edrInfoItem = NSMenuItem(title: edrInfoText(), action: nil, keyEquivalent: "") + edrInfoItem.isEnabled = false + menu.addItem(edrInfoItem) + let levelHeader = NSMenuItem(title: "Brightness Level", action: nil, keyEquivalent: "") levelHeader.isEnabled = false menu.addItem(levelHeader) @@ -167,6 +167,20 @@ class XDRApp: NSObject, NSApplicationDelegate { statusItem.menu = menu } + func edrInfoText() -> String { + return "EDR Headroom: \(String(format: "%.1f", maxEDR))x" + } + + func updateStatusBarIcon() { + guard let button = statusItem?.button else { return } + if isActive { + let levelStr = String(format: "%.1f", effectiveBoost) + button.title = "☀︎ \(levelStr)x" + } else { + button.title = "☀" + } + } + // MARK: - System Event Observers func observeSystemEvents() { @@ -177,43 +191,28 @@ class XDRApp: NSObject, NSApplicationDelegate { nc.addObserver(self, selector: #selector(handleDisplayChange), name: NSApplication.didChangeScreenParametersNotification, object: nil) - // Space / Mission Control changes — fires when exiting Mission Control or switching spaces + // Space / Mission Control — fires when exiting Mission Control or switching spaces wnc.addObserver(self, selector: #selector(handleSpaceChange), name: NSWorkspace.activeSpaceDidChangeNotification, object: nil) - // Screen sleep/wake — EDR headroom resets after wake + // Screen wake — EDR headroom resets after wake wnc.addObserver(self, selector: #selector(handleScreenWake), name: NSWorkspace.screensDidWakeNotification, object: nil) - // Watchdog: every 1.5 seconds, verify overlay health and track EDR headroom changes - // (handles brightness keyboard adjustments, sleep/wake, lid close/open, lock/unlock) - watchdogTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { [weak self] _ in + // Watchdog: every 3 seconds, check overlay health and track EDR headroom. + // Kept at 3s to avoid contributing to flicker — event observers handle the + // time-sensitive stuff, the watchdog is purely a safety net. + watchdogTimer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { [weak self] _ in self?.watchdogCheck() } } func watchdogCheck() { - // Track EDR headroom changes from keyboard brightness controls - let currentMaxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 - if currentMaxEDR != maxEDR { - let oldMax = maxEDR - maxEDR = currentMaxEDR - fputs("EDR headroom changed: \(oldMax)x → \(maxEDR)x\n", stderr) - - // Clamp boost level if it now exceeds available headroom - if boostLevel > Double(maxEDR) && maxEDR > 1.0 { - boostLevel = Double(maxEDR) - updateBoostMenuState() - if isActive, let view = boostView { - view.clearColor = MTLClearColor(red: boostLevel, green: boostLevel, blue: boostLevel, alpha: 1.0) - fputs("Boost clamped to \(boostLevel)x\n", stderr) - } - } - } + updateEDRHeadroom() guard shouldBeActive else { return } - // EDR no longer available (brightness too low or display changed) + // EDR unavailable (e.g. brightness at minimum) if maxEDR <= 1.0 { if isActive { deactivate() @@ -222,74 +221,114 @@ class XDRApp: NSObject, NSApplicationDelegate { return } - if let window = overlayWindow { - // Window exists — make sure it's visible and correctly sized - if !window.isVisible { - window.orderFrontRegardless() - fputs("Watchdog — window restored\n", stderr) - } - if let screen = NSScreen.main, window.frame != screen.frame { - window.setFrame(screen.frame, display: true) - fputs("Watchdog — resized to match screen\n", stderr) - } - } else { - // Window is gone — need to fully recreate + // shouldBeActive but not isActive — EDR came back after being unavailable + if !isActive { + activate() + fputs("Watchdog — EDR restored, reactivated\n", stderr) + return + } + + // Window exists but got hidden (e.g. after sleep/wake edge case) + if let window = overlayWindow, !window.isVisible { + window.orderFrontRegardless() + fputs("Watchdog — window restored\n", stderr) + } else if overlayWindow == nil { + // Window was destroyed — recreate isActive = false - if maxEDR > 1.0 { - activate() - fputs("Watchdog — XDR recreated\n", stderr) + activate() + fputs("Watchdog — XDR recreated\n", stderr) + } + } + + /// Update maxEDR from current screen and adjust effective boost if needed. + /// Does NOT deactivate/reactivate — just updates the clear color in-place. + func updateEDRHeadroom() { + let currentMaxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 + // Use epsilon to avoid flapping on float jitter + guard abs(currentMaxEDR - maxEDR) > 0.05 else { return } + + let oldMax = maxEDR + maxEDR = currentMaxEDR + edrInfoItem?.title = edrInfoText() + fputs("EDR headroom: \(String(format: "%.1f", oldMax))x → \(String(format: "%.1f", maxEDR))x\n", stderr) + + // Recompute effective boost — user's chosen level stays unchanged + let newEffective = min(boostLevel, max(Double(maxEDR), 1.0)) + if abs(newEffective - effectiveBoost) > 0.05 { + effectiveBoost = newEffective + if isActive, let view = boostView { + view.clearColor = MTLClearColor(red: effectiveBoost, green: effectiveBoost, blue: effectiveBoost, alpha: 1.0) + updateStatusBarIcon() + fputs("Effective boost: \(String(format: "%.1f", effectiveBoost))x\n", stderr) } } } @objc func handleSpaceChange() { - guard shouldBeActive else { return } - // Short delay to let Mission Control / space switch animation finish - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in - self?.reassertOverlay() - } + guard shouldBeActive, isActive else { return } + // Debounced reassert after Mission Control / space switch animation + scheduleReassert(delay: 0.5) } @objc func handleScreenWake() { guard shouldBeActive else { return } - // Delay to let the display fully wake and report correct EDR values - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in - guard let self = self else { return } - self.maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 - self.reassertOverlay() - } + scheduleReassert(delay: 1.5) } - /// Re-assert the overlay window after system events (Mission Control, space change, wake). - /// Recreates it if it was destroyed, otherwise ensures it's visible and correctly sized. - func reassertOverlay() { - guard shouldBeActive else { return } - if let window = overlayWindow { - if let screen = NSScreen.main { + @objc func handleDisplayChange() { + let oldMaxEDR = maxEDR + maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 + edrInfoItem?.title = edrInfoText() + + guard isActive, shouldBeActive else { return } + + // If just the EDR headroom changed (brightness key), update in-place — no flash + if let window = overlayWindow, let screen = NSScreen.main { + let frameChanged = window.frame != screen.frame + let edrChanged = abs(maxEDR - oldMaxEDR) > 0.05 + + if frameChanged { + // Resolution or display arrangement changed — resize overlay window.setFrame(screen.frame, display: false) + if let view = boostView { + view.frame = NSRect(origin: .zero, size: screen.frame.size) + } + fputs("Display changed — overlay resized\n", stderr) } - window.orderFrontRegardless() - } else { - isActive = false - maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 - if maxEDR > 1.0 { - activate() - fputs("Overlay reasserted\n", stderr) + + if edrChanged { + effectiveBoost = min(boostLevel, max(Double(maxEDR), 1.0)) + if let view = boostView { + view.clearColor = MTLClearColor(red: effectiveBoost, green: effectiveBoost, blue: effectiveBoost, alpha: 1.0) + } + updateStatusBarIcon() + } + + // If EDR is gone, deactivate cleanly + if maxEDR <= 1.0 { + deactivate() + fputs("Display changed — EDR lost\n", stderr) } } } - @objc func handleDisplayChange() { - maxEDR = NSScreen.main?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0 - if isActive { - deactivate() - if maxEDR > 1.0 && shouldBeActive { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in - self?.activate() - fputs("Display changed — XDR refreshed\n", stderr) - } + /// Debounced reassert — cancels any pending reassert to prevent overlapping calls. + func scheduleReassert(delay: Double) { + pendingReassert?.cancel() + let work = DispatchWorkItem { [weak self] in + guard let self = self, self.shouldBeActive else { return } + self.updateEDRHeadroom() + + if let window = self.overlayWindow { + window.orderFrontRegardless() + } else if self.maxEDR > 1.0 { + self.isActive = false + self.activate() + fputs("Reasserted overlay\n", stderr) } } + pendingReassert = work + DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: work) } // MARK: - Toggle @@ -306,52 +345,47 @@ class XDRApp: NSObject, NSApplicationDelegate { @objc func setBoostLevel(_ sender: NSMenuItem) { boostLevel = Double(sender.tag) / 100.0 - updateBoostMenuState() - if isActive, let view = boostView { - // Update in-place — no teardown, no flash - view.clearColor = MTLClearColor(red: boostLevel, green: boostLevel, blue: boostLevel, alpha: 1.0) - } - } - - func updateBoostMenuState() { - let currentTag = Int(boostLevel * 100) + effectiveBoost = min(boostLevel, max(Double(maxEDR), 1.0)) for item in boostItems { - item.state = (item.tag == currentTag) ? .on : .off + item.state = (item.tag == sender.tag) ? .on : .off } + if isActive, let view = boostView { + view.clearColor = MTLClearColor(red: effectiveBoost, green: effectiveBoost, blue: effectiveBoost, alpha: 1.0) + } + updateStatusBarIcon() } // MARK: - XDR Overlay func activate() { - guard let screen = NSScreen.main else { return } + guard let screen = NSScreen.main, maxEDR > 1.0 else { return } + + effectiveBoost = min(boostLevel, Double(maxEDR)) let frame = screen.frame let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false) - window.level = kOverlayWindowLevel + window.level = .screenSaver window.backgroundColor = .clear window.isOpaque = false window.hasShadow = false window.ignoresMouseEvents = true window.hidesOnDeactivate = false - window.sharingType = .none // exclude from screenshots and screen recordings - window.animationBehavior = .none // prevent animation glitches during Mission Control + window.sharingType = .none + window.animationBehavior = .none window.collectionBehavior = [.canJoinAllSpaces, .stationary, .fullScreenAuxiliary, .ignoresCycle] - // Single MTKView that both triggers EDR and provides the boost let boostView = MTKView(frame: frame, device: device) boostView.colorPixelFormat = .rgba16Float boostView.colorspace = CGColorSpace(name: CGColorSpace.extendedLinearDisplayP3) boostView.layer?.isOpaque = false boostView.preferredFramesPerSecond = 10 - boostView.clearColor = MTLClearColor(red: boostLevel, green: boostLevel, blue: boostLevel, alpha: 1.0) + boostView.clearColor = MTLClearColor(red: effectiveBoost, green: effectiveBoost, blue: effectiveBoost, alpha: 1.0) if let layer = boostView.layer as? CAMetalLayer { layer.wantsExtendedDynamicRangeContent = true } boostRenderer = Renderer(device: device) boostView.delegate = boostRenderer - // Multiply compositing on the content view layer — composites with - // the desktop content BEHIND the window, not within it boostView.wantsLayer = true window.contentView = boostView window.contentView?.layer?.compositingFilter = "multiply" @@ -360,9 +394,9 @@ class XDRApp: NSObject, NSApplicationDelegate { self.boostView = boostView isActive = true - statusItem.button?.title = "☀︎" - toggleItem.title = "Turn Off" - fputs("XDR ON — \(boostLevel)x\n", stderr) + toggleItem.title = "Turn Off XDR Boost" + updateStatusBarIcon() + fputs("XDR ON — \(String(format: "%.1f", effectiveBoost))x (headroom: \(String(format: "%.1f", maxEDR))x)\n", stderr) } func deactivate() { @@ -372,8 +406,8 @@ class XDRApp: NSObject, NSApplicationDelegate { boostRenderer = nil isActive = false - statusItem.button?.title = "☀" - toggleItem.title = "Turn On" + toggleItem.title = "Turn On XDR Boost" + updateStatusBarIcon() fputs("XDR OFF\n", stderr) }