From ed07a0ca532d6d68064b8fa6a92996d2ada731ed Mon Sep 17 00:00:00 2001 From: Seki Hiroyasu Date: Sat, 27 Jun 2026 12:03:00 +0900 Subject: [PATCH 1/2] fix: exclude software-dimming overlay windows from screen capture For displays without DDC or gamma support (e.g. DisplayLink / virtual displays), MonitorControl dims via a full-screen black 'shade' NSWindow. Because the shade window's sharingType defaults to .readOnly, it is captured by screenshots and screen recordings, so any capture taken while a display is dimmed comes out darkened (see discussions #1453, #866, #1446). Set sharingType = .none on the shade windows and the gamma activity enforcer so they no longer appear in screen captures. This is display-only chrome; excluding it from capture does not change what the user sees on screen. --- MonitorControl/Support/DisplayManager.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MonitorControl/Support/DisplayManager.swift b/MonitorControl/Support/DisplayManager.swift index 00a4627a..65167f02 100644 --- a/MonitorControl/Support/DisplayManager.swift +++ b/MonitorControl/Support/DisplayManager.swift @@ -21,6 +21,7 @@ class DisplayManager { self.gammaActivityEnforcer.alphaValue = 1 * (DEBUG_GAMMA_ENFORCER ? 0.5 : 0.01) self.gammaActivityEnforcer.ignoresMouseEvents = true self.gammaActivityEnforcer.level = .screenSaver + self.gammaActivityEnforcer.sharingType = .none // exclude helper overlay from screen capture/recording self.gammaActivityEnforcer.orderFrontRegardless() self.gammaActivityEnforcer.collectionBehavior = [.stationary, .canJoinAllSpaces] os_log("Gamma activity enforcer created.", type: .info) @@ -70,6 +71,7 @@ class DisplayManager { shade.backgroundColor = .clear shade.ignoresMouseEvents = true shade.level = NSWindow.Level(rawValue: Int(CGShieldingWindowLevel())) + shade.sharingType = .none // dimming overlay must not appear in screenshots / screen recordings shade.orderFrontRegardless() shade.collectionBehavior = [.stationary, .canJoinAllSpaces, .ignoresCycle] shade.setFrame(screen.frame, display: true) From 4d62fa90e0a7289fafa44ac5726f007b50af503c Mon Sep 17 00:00:00 2001 From: Seki Hiroyasu Date: Sat, 27 Jun 2026 12:40:43 +0900 Subject: [PATCH 2/2] Only exclude shade from capture on non-virtual displays Virtual displays (AirPlay/Sidecar/DisplayLink) are themselves presented to the physical monitor via screen capture. Setting sharingType=.none on their shade would remove the dimming from the actual monitor, not just from screenshots. Guard the opt-out with !isVirtual so DisplayLink etc. keep dimming, while real displays using shade (e.g. Mac mini HDMI) still get screenshot-clean dimming. --- MonitorControl/Support/DisplayManager.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MonitorControl/Support/DisplayManager.swift b/MonitorControl/Support/DisplayManager.swift index 65167f02..64bbb67e 100644 --- a/MonitorControl/Support/DisplayManager.swift +++ b/MonitorControl/Support/DisplayManager.swift @@ -71,7 +71,14 @@ class DisplayManager { shade.backgroundColor = .clear shade.ignoresMouseEvents = true shade.level = NSWindow.Level(rawValue: Int(CGShieldingWindowLevel())) - shade.sharingType = .none // dimming overlay must not appear in screenshots / screen recordings + // Hiding the shade from screen capture is only safe on real displays. On VIRTUAL + // displays (AirPlay / Sidecar / DisplayLink) macOS presents the display itself via + // screen capture, so a non-capturable shade would also disappear from the physical + // monitor and stop dimming it. Only opt these shades out of capture when the display + // is not virtual (e.g. a Mac mini HDMI / blacklisted display using shade dimming). + if !DisplayManager.isVirtual(displayID: displayID) { + shade.sharingType = .none // dimming overlay must not appear in screenshots / screen recordings + } shade.orderFrontRegardless() shade.collectionBehavior = [.stationary, .canJoinAllSpaces, .ignoresCycle] shade.setFrame(screen.frame, display: true)