Keep display awake while running (SetThreadExecutionState) so the monitor does not enter standby and the DDC/CI brightness restore on exit no longer hangs ~30s; bound native DDC calls with a 2s timeout as defense

This commit is contained in:
Hermes Agent committed 2026-09-17 22:33:29 +02:00
1 parent d3437f924b
commit 0725915317
1 file changed
+55 -6
+55 -6
View File
@@ -80,16 +80,52 @@ class BrightnessController:
def _write_native(self, handle, value):
try:
dx = ctypes.windll.dxva2
return bool(dx.SetMonitorBrightness(int(handle), wt.DWORD(int(value))))
res = {}
def _t():
try:
res["v"] = bool(
dx.SetMonitorBrightness(int(handle), wt.DWORD(int(value)))
)
except Exception as e:
res["e"] = e
th = threading.Thread(target=_t, daemon=True)
th.start()
th.join(timeout=2.0)
if th.is_alive():
LOG.warning("native SetMonitorBrightness timed out (monitor in standby?)")
return False
if "e" in res:
LOG.warning("native write failed: %r", res["e"])
return False
return res.get("v", False)
except Exception as e:
LOG.warning("native write failed: %r", e)
LOG.warning("native write error: %r", e)
return False
def _close_native(self, handle):
dx = ctypes.windll.dxva2
arr = (BrightnessController.PHYSICAL_MONITOR * 1)()
arr[0].hPhysicalMonitor = handle
dx.DestroyPhysicalMonitors(1, arr)
try:
dx = ctypes.windll.dxva2
arr = (BrightnessController.PHYSICAL_MONITOR * 1)()
arr[0].hPhysicalMonitor = handle
res = {}
def _t():
try:
res["v"] = dx.DestroyPhysicalMonitors(1, arr)
except Exception as e:
res["e"] = e
th = threading.Thread(target=_t, daemon=True)
th.start()
th.join(timeout=2.0)
if th.is_alive():
return
if "e" in res:
LOG.warning("native close failed: %r", res["e"])
except Exception as e:
LOG.warning("native close error: %r", e)
def _build(self):
self.targets = []
@@ -214,6 +250,9 @@ if sys.platform == "win32":
DT_SINGLELINE = 0x00000020
TRANSPARENT = 1
DEFAULT_GUI_FONT = 17
ES_CONTINUOUS = 0x80000000
ES_SYSTEM_REQUIRED = 0x00000001
ES_DISPLAY_REQUIRED = 0x00000002
LRESULT = ctypes.c_int64
HMONITOR = ctypes.c_void_p
@@ -329,6 +368,8 @@ if sys.platform == "win32":
kernel32.GetModuleHandleW.restype = wt.HINSTANCE
kernel32.GetLastError.argtypes = []
kernel32.GetLastError.restype = wt.DWORD
kernel32.SetThreadExecutionState.argtypes = [wt.DWORD]
kernel32.SetThreadExecutionState.restype = wt.DWORD
# --- native DDC/CI brightness (dxva2) ---
class PHYSICAL_MONITOR(ctypes.Structure):
@@ -485,6 +526,13 @@ if sys.platform == "win32":
if not _hook_id:
LOG.warning("SetWindowsHookExW failed: %d", kernel32.GetLastError())
# keep display awake while running: prevents the monitor from entering
# standby during idle, which would make the DDC/CI brightness restore on
# exit block/hang (often ~30s) waiting for the monitor to wake.
kernel32.SetThreadExecutionState(
ES_CONTINUOUS | ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED
)
msg = wt.MSG()
while user32.GetMessageW(ctypes.byref(msg), 0, 0, 0) > 0:
user32.TranslateMessage(ctypes.byref(msg))
@@ -492,6 +540,7 @@ if sys.platform == "win32":
if _hook_id:
user32.UnhookWindowsHookEx(_hook_id)
kernel32.SetThreadExecutionState(ES_CONTINUOUS) # allow display sleep again
for h in _hwnds:
user32.DestroyWindow(h)
# restore cursor