ADR 0021: Platform application chrome
- Status: Superseded in part by ADR 0025
- Date: 2026-07-26
Context
Electron's default chrome does not satisfy all three desktop conventions used by PI-Desktop. macOS needs a conventional native application menu and inset traffic lights. Frameless Windows and Linux windows need visible application menus plus minimize, maximize/restore, and close controls.
Renderer-owned commands such as New Task and Settings cannot execute directly inside Electron Main. Native editing, zoom, fullscreen, and window operations must not become an arbitrary privileged command bridge.
Decision
- macOS keeps
hiddenInsettraffic lights and installs a native Electron application menu. - Windows and Linux use the shared frameless 46px shell with a renderer menubar and renderer-drawn window controls.
- Renderer-owned menu commands use the fixed
APP_MENU_COMMANDSallowlist. Native menu and window operations use separate fixed allowlists. - The preload exposes only the operating-system identifier and allowlisted IPC channels required by the chrome.
- Native commands wait for a renderer-ready acknowledgement before delivery. Window creation is single-flight, and closing or reloading a window resets the acknowledgement.
- Windows and Linux packaging remains shell-readiness work. This decision does not change the macOS-arm64 first-release scope in D010.
Consequences
- Each platform receives familiar menus and window controls without exposing arbitrary Main-process execution.
- A native menu command can recreate the macOS window without racing renderer subscription setup or creating duplicate windows.
- Windows and Linux require native-runner packaging and visual qualification before release.
- Custom chrome must preserve keyboard, focus, localization, drag-region, and maximize-state behavior across renderer reloads.
Alternatives
Keep Electron's default menu and frame everywhere
Rejected because the existing hidden titlebar design would remain incomplete on Windows and Linux, while macOS would lack product-specific commands.
Implement every menu action in the renderer
Rejected because native editing and window operations belong to Electron Main and must remain behind an explicit capability boundary.
Send commands after a fixed delay
Rejected because renderer subscription timing varies by machine and reload state. An acknowledgement is deterministic.
References
docs/spec/03-runtime/01-ipc-protocol.mddocs/spec/04-ux/08-component-spec.mddocs/spec/04-ux/09-interaction-patterns.mddocs/spec/06-delivery/04-e2e-test-plan.md(E2E-067)docs/spec/08-meta/decisions-log.md(D118)