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:
2026-02-27 16:18:18 +03:00
parent adf2d936da
commit 397d38ac12
7 changed files with 198 additions and 33 deletions

View File

@@ -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