| 1 | # virtual_desktop.py DOX |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | - Own the `virtual_desktop.py` helper module. |
| 6 | - This module registers and proxies virtual desktop sessions. |
| 7 | - Keep this file-level DOX profile synchronized with `virtual_desktop.py` because this directory is intentionally flat. |
| 8 | |
| 9 | ## Ownership |
| 10 | |
| 11 | - `virtual_desktop.py` owns the runtime implementation. |
| 12 | - `virtual_desktop.py.dox.md` owns durable notes about responsibilities, contracts, side effects, and verification for that implementation. |
| 13 | - Classes: |
| 14 | - `VirtualDesktopEndpoint` (no explicit base class) |
| 15 | - `VirtualDesktopRegistry` (no explicit base class) |
| 16 | - `register(self, endpoint: VirtualDesktopEndpoint) -> None` |
| 17 | - `unregister(self, token: str) -> None` |
| 18 | - `proxy_for_token(self, token: str) -> VirtualDesktopEndpoint | None` |
| 19 | - `resize(self, token: str, width: int, height: int) -> dict[str, Any]` |
| 20 | - Top-level functions: |
| 21 | - `register_session(token: str, host: str, port: int, owner: str=..., title: str=..., resize: ResizeCallback | None=...) -> None` |
| 22 | - `unregister_session(token: str) -> None` |
| 23 | - `proxy_for_token(token: str) -> VirtualDesktopEndpoint | None` |
| 24 | - `resize_session(token: str, width: int, height: int) -> dict[str, Any]` |
| 25 | - `get_registry() -> VirtualDesktopRegistry` |
| 26 | - `session_url(token: str, title: str=..., encoding: str=..., quality: int=..., speed: int=..., file_transfer: bool=..., printing: bool=...) -> str` |
| 27 | - `collect_status() -> dict[str, Any]` |
| 28 | - `find_xpra_html_root() -> Path | None` |
| 29 | - `_package_installed(package: str) -> bool` |
| 30 | - `normalize_size(width: int | float | str, height: int | float | str, max_width: int=..., max_height: int=..., min_width: int=..., min_height: int=...) -> tuple[int, int]` |
| 31 | - `normalize_desktop_display_size(width: int | float | str, height: int | float | str, max_width: int=..., max_height: int=..., min_width: int=..., min_height: int=..., min_aspect_ratio: float=...) -> tuple[int, int]` |
| 32 | - `resize_display(display: int, width: int, height: int, max_width: int=..., max_height: int=..., window_class: str=..., keys: tuple[str, ...]=..., xauthority: str=..., home: str=..., settle_seconds: float=...) -> dict[str, Any]` |
| 33 | - `_ensure_xrandr_mode(env: dict[str, str], width: int, height: int) -> None` |
| 34 | - `_select_xrandr_mode(env: dict[str, str], width: int, height: int) -> subprocess.CompletedProcess[str]` |
| 35 | - `_xrandr_output_modes(env: dict[str, str]) -> tuple[str, set[str]]` |
| 36 | - `current_display_size(display: int, xauthority: str=..., home: str=...) -> tuple[int, int] | None` |
| 37 | - `fit_window_until(display: int, width: int, height: int, window_class: str=..., keys: tuple[str, ...]=..., settle_seconds: float=..., timeout_seconds: float=..., process: subprocess.Popen[Any] | None=..., xauthority: str=..., home: str=...) -> None` |
| 38 | - `fit_window(display: int, width: int, height: int, window_class: str=..., keys: tuple[str, ...]=..., xauthority: str=..., home: str=...) -> bool` |
| 39 | - `has_window(display: int, window_class: str=..., name: str=..., xauthority: str=..., home: str=...) -> bool` |
| 40 | - `find_window(display: int, window_class: str=..., name: str=..., xauthority: str=..., home: str=...) -> str` |
| 41 | - `close_windows(display: int, names: tuple[str, ...]=..., window_class: str=..., xauthority: str=..., home: str=...) -> int` |
| 42 | - `_find_window(display: int, window_class: str=..., name: str=..., xauthority: str=..., home: str=...) -> str` |
| 43 | - `_display_env(display: int, xauthority: str=..., home: str=...) -> dict[str, str]` |
| 44 | - Notable constants/configuration names: `STATE_DIR`, `DEFAULT_WIDTH`, `DEFAULT_HEIGHT`, `MAX_WIDTH`, `MAX_HEIGHT`, `MIN_WIDTH`, `MIN_HEIGHT`, `MIN_DESKTOP_ASPECT_RATIO`, `SESSION_PATH`, `XPRA_HTML_ROOT_CANDIDATES`. |
| 45 | |
| 46 | ## Runtime Contracts |
| 47 | |
| 48 | - Helper modules own reusable framework APIs and must preserve public callers unless all callers, tests, and docs are updated together. |
| 49 | - Update this file whenever public functions, classes, persistence behavior, path/security assumptions, side effects, or cross-module contracts change. |
| 50 | - Observed side-effect areas: filesystem reads, filesystem writes, network calls, subprocess/runtime control, plugin state, settings/state persistence, secret handling. |
| 51 | - Imported dependency areas include: `__future__`, `dataclasses`, `helpers`, `helpers.localization`, `math`, `os`, `pathlib`, `re`, `shutil`, `subprocess`, `threading`, `time`, `typing`, `urllib.parse`. |
| 52 | |
| 53 | ## Key Concepts |
| 54 | |
| 55 | - Important called helpers/classes observed in the source: `Path`, `files.get_abs_path`, `get_registry.register`, `get_registry.unregister`, `get_registry.proxy_for_token`, `get_registry.resize`, `quote`, `urlencode`, `find_xpra_html_root`, `subprocess.run`, `normalize_size`, `shutil.which`, `_display_env`, `current_display_size`, `_ensure_xrandr_mode`, `_select_xrandr_mode`, `time.sleep`, `strip`, `_xrandr_output_modes`, `result.stdout.splitlines`. |
| 56 | - Keep request/response, tool, or helper semantics documented here at the same time as source changes. |
| 57 | - Session URLs keep Desktop's JPEG, printing, and file-transfer defaults while allowing restricted viewers such as Browser to negotiate encoding and disable unrelated capabilities. |
| 58 | - Display resizing keeps the Desktop settle delay by default; latency-sensitive callers may skip it when they immediately verify the XRandR size. |
| 59 | |
| 60 | ## Work Guidance |
| 61 | |
| 62 | - Preserve public helper APIs used by core code and plugins unless every caller is updated. |
| 63 | - Keep path, auth, secret, persistence, network, and subprocess behavior explicit and bounded. |
| 64 | - Prefer adding cohesive helper functions here only when behavior is reused across modules. |
| 65 | |
| 66 | ## Verification |
| 67 | |
| 68 | - Run targeted tests for changed helper behavior; run security regressions for auth, filesystem, WebSocket, tunnel, upload, or secret-handling helpers. |
| 69 | - Related tests observed by source search: |
| 70 | - `tests/test_office_canvas_setup.py` |
| 71 | - `tests/test_office_desktop_state.py` |
| 72 | - `tests/test_office_document_store.py` |
| 73 | |
| 74 | ## Child DOX Index |
| 75 | |
| 76 | No child DOX files. |