Add primary display indicator, custom accent color picker, restart script
- Detect primary monitor via Windows EnumDisplayMonitors API and show badge - Expand accent color picker with 9 presets and custom color input - Auto-generate hover color for custom accent colors - Re-render accent swatches on locale change for proper i18n - Replace restart-server.bat with PowerShell restart-server.ps1 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
"""Display brightness and power control service."""
|
||||
|
||||
import ctypes
|
||||
import ctypes.wintypes
|
||||
import logging
|
||||
import platform
|
||||
import struct
|
||||
@@ -61,6 +63,7 @@ class MonitorInfo:
|
||||
model: str = ""
|
||||
manufacturer: str = ""
|
||||
resolution: str | None = None
|
||||
is_primary: bool = False
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
@@ -72,9 +75,68 @@ class MonitorInfo:
|
||||
"model": self.model,
|
||||
"manufacturer": self.manufacturer,
|
||||
"resolution": self.resolution,
|
||||
"is_primary": self.is_primary,
|
||||
}
|
||||
|
||||
|
||||
def _detect_primary_resolution() -> str | None:
|
||||
"""Detect the primary display resolution via Windows API."""
|
||||
if platform.system() != "Windows":
|
||||
return None
|
||||
try:
|
||||
class MONITORINFO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cbSize", ctypes.wintypes.DWORD),
|
||||
("rcMonitor", ctypes.wintypes.RECT),
|
||||
("rcWork", ctypes.wintypes.RECT),
|
||||
("dwFlags", ctypes.wintypes.DWORD),
|
||||
]
|
||||
|
||||
MONITORINFOF_PRIMARY = 1
|
||||
primary_res = None
|
||||
|
||||
def callback(hmon, hdc, rect, data):
|
||||
nonlocal primary_res
|
||||
mi = MONITORINFO()
|
||||
mi.cbSize = ctypes.sizeof(mi)
|
||||
ctypes.windll.user32.GetMonitorInfoW(hmon, ctypes.byref(mi))
|
||||
if mi.dwFlags & MONITORINFOF_PRIMARY:
|
||||
w = mi.rcMonitor.right - mi.rcMonitor.left
|
||||
h = mi.rcMonitor.bottom - mi.rcMonitor.top
|
||||
primary_res = f"{w}x{h}"
|
||||
return True
|
||||
|
||||
MONITORENUMPROC = ctypes.WINFUNCTYPE(
|
||||
ctypes.c_int,
|
||||
ctypes.wintypes.HMONITOR,
|
||||
ctypes.wintypes.HDC,
|
||||
ctypes.POINTER(ctypes.wintypes.RECT),
|
||||
ctypes.wintypes.LPARAM,
|
||||
)
|
||||
ctypes.windll.user32.EnumDisplayMonitors(
|
||||
None, None, MONITORENUMPROC(callback), 0
|
||||
)
|
||||
return primary_res
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _mark_primary(monitors: list[MonitorInfo]) -> None:
|
||||
"""Mark the primary display in the monitor list."""
|
||||
if not monitors:
|
||||
return
|
||||
|
||||
primary_res = _detect_primary_resolution()
|
||||
if primary_res:
|
||||
for m in monitors:
|
||||
if m.resolution == primary_res:
|
||||
m.is_primary = True
|
||||
return
|
||||
|
||||
# Fallback: mark first monitor as primary
|
||||
monitors[0].is_primary = True
|
||||
|
||||
|
||||
# Cache for monitor list
|
||||
_monitor_cache: list[MonitorInfo] | None = None
|
||||
_cache_time: float = 0
|
||||
@@ -142,6 +204,7 @@ def list_monitors(force_refresh: bool = False) -> list[MonitorInfo]:
|
||||
except Exception as e:
|
||||
logger.error("Failed to enumerate monitors: %s", e)
|
||||
|
||||
_mark_primary(monitors)
|
||||
_monitor_cache = monitors
|
||||
_cache_time = time.time()
|
||||
return monitors
|
||||
|
||||
Reference in New Issue
Block a user