Files
alro65 42b2eec2e1 feat: AR Display Manager — multi-monitor floating app switcher
Adds the AR Display Manager daemon (Task #9):

- display_manager/ package with 8 modules:
  - app_registry.py   : static metadata for the 4 bridge apps
  - config.py         : JSON-persisted config + per-screen layout store
  - win32_utils.py    : ctypes wrappers (EnumWindows, SetWindowPos, ShowWindow)
  - process_manager.py: launch + track app processes, HWND lookup
  - floating_button.py: always-on-top 52×52 px AR button per monitor
                        with draggable placement + custom-painted popup
  - display_manager.py: orchestrator (QScreens → buttons → app placement
                        + system tray with Settings/Launch/Quit)
  - settings_dialog.py: modal dialog for exe paths, button position,
                        and Windows autostart toggle
  - autostart.py      : HKCU Run registry read/write helpers
- display_manager_main.py at repo root: launcher script
- Studio Overview tab: "Lanzar Display Manager" button
- pyproject.toml: display-manager optional dependency group (PySide6)

Layout persistence: ~/.ar-autopilot/display_manager/layout.json
Config:            ~/.ar-autopilot/display_manager/config.json
Supports up to 4 monitors (2 HDMI native + 2 USB DisplayLink).
Double-click tray icon to toggle button visibility.

AR_electronics — AR-Autopilot Project
2026-05-24 21:48:27 -04:00

67 lines
2.0 KiB
Python

"""Register / unregister AR Display Manager as a Windows autostart entry."""
from __future__ import annotations
import sys
from pathlib import Path
_REG_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
_APP_NAME = "AR Display Manager"
def _pythonw() -> str:
"""Return the pythonw.exe path (no console window on start)."""
exe = Path(sys.executable)
pw = exe.parent / "pythonw.exe"
return str(pw) if pw.exists() else sys.executable
def enable() -> bool:
"""Add the autostart registry entry. Returns True on success."""
if sys.platform != "win32":
return False
try:
import winreg # type: ignore[import-not-found]
launcher = Path(__file__).resolve().parents[1] / "display_manager_main.py"
cmd = f'"{_pythonw()}" "{launcher}"'
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, _REG_KEY, 0, winreg.KEY_SET_VALUE
) as key:
winreg.SetValueEx(key, _APP_NAME, 0, winreg.REG_SZ, cmd)
return True
except Exception:
return False
def disable() -> bool:
"""Remove the autostart registry entry. Returns True if it existed."""
if sys.platform != "win32":
return False
try:
import winreg # type: ignore[import-not-found]
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, _REG_KEY, 0, winreg.KEY_SET_VALUE
) as key:
winreg.DeleteValue(key, _APP_NAME)
return True
except FileNotFoundError:
return False
except Exception:
return False
def is_enabled() -> bool:
"""Return True if the autostart entry exists."""
if sys.platform != "win32":
return False
try:
import winreg # type: ignore[import-not-found]
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, _REG_KEY, 0, winreg.KEY_READ
) as key:
winreg.QueryValueEx(key, _APP_NAME)
return True
except FileNotFoundError:
return False
except Exception:
return False