Windows, events, and menus
Named window types
Section titled “Named window types”#[Window( name: 'settings', title: 'Settings', page: 'resources/settings.html', width: 760, height: 620,)]final readonly class SettingsWindow extends DesktopWindow{}Register it on the application:
protected function windows(): array{ return [SettingsWindow::class];}Then inject the exact window:
#[Command]public function openSettings(SettingsWindow $settings): void{ $settings->show()->focus();}DesktopWindow collects title, visibility, focus, close, fullscreen, and
maximize effects. It never exposes Winit, Servo, or an operating-system handle.
Typed events
Section titled “Typed events”final readonly class DocumentSaved{ public function __construct( public int $documentId, public int $revision, ) {}}
$events->emit(new DocumentSaved($document->id, $document->revision));The default wire name is document.saved; public properties form the payload.
Implement Event for an explicit stable name or serialized shape.
Frontend events map back to typed methods:
await window.pam.emit( "editor.changed", { documentId: "doc-42" }, { timeout: 5_000, signal: abortController.signal },);#[Listen('editor.changed')]public function editorChanged( string $documentId, WindowHandle $window,): void { $window->title("Editing {$documentId}");}pam.emit(name, payload, options) rejects empty event names and preserves the
same timeout, cancellation, worker-recovery, and typed-error behavior as
pam.invoke(). Use pam.on() for PHP-to-frontend events; it returns an
unsubscribe closure that the owning screen or window must call.
Menus are actions
Section titled “Menus are actions”#[Menu( id: 'application', label: 'My desktop app', close: TrayCloseBehavior::Hide,)]final class ApplicationMenu{ #[MenuItem('Show window', shortcut: 'CmdOrCtrl+Shift+KeyP')] public function show(WindowHandle $window): void { $window->show()->focus(); }
#[MenuSeparator] public function separator(): void {}
#[MenuItem('Background mode', checkbox: true)] public function background(): void {}
#[MenuItem('Quit')] public function quit(ApplicationControl $application): void { $application->quit(); }}protected function menus(): array{ return [ApplicationMenu::class];}The menu item ID defaults to the method’s dotted name. A declared shortcut is validated once and registered as a native global shortcut with the same action. Linux currently supports one tray-backed application menu.