/** * Window types and interfaces from the Wayland compositor */ /** * Represents a single window managed by the compositor */ export interface WoWindow { name: string; title?: string; x: number; y: number; width: number; height: number; content_width?: number; content_height?: number; z_order?: number; mapped?: boolean; focused?: boolean; fps?: number; pid?: number; source?: 'electron' | 'wayland' | 'x11'; ssd?: boolean; fullscreen?: boolean; app_id?: string; dialog?: boolean; parent_name?: string; } export interface WoMonitor { id: string; x: number; y: number; width: number; height: number; scale: number; primary: boolean; } /** * Action types for compositor window control */ export type CompositorActionType = | 'focus' | 'minimize' | 'close' | 'resize' | 'move' | 'maximize' | 'fullscreen' | 'pointer_motion' | 'pointer_button' | 'pointer_leave' | 'pointer_scroll' | 'keyboard_key'; /** * Configuration for compositor actions */ export interface CompositorActionConfig { window?: string; x?: number; y?: number; width?: number; height?: number; [key: string]: unknown; } export interface SyscallListApplicationsParams { locale?: string; } export interface SyscallLaunchDesktopParams { desktopId: string; files?: string[]; } export interface SyscallLaunchParams { command: string; [key: string]: any; } export interface SyscallExecParams { command: string; [key: string]: any; } export interface SyscallListDirParams { path?: string; [key: string]: any; } export interface SyscallReadParams { path: string; [key: string]: any; } export interface SyscallWriteParams { path: string; content: string; [key: string]: any; } export interface SyscallShutdownParams { [key: string]: any; } export interface SyscallRestartParams { [key: string]: any; } export interface SyscallLogoutParams { [key: string]: any; } export interface SyscallLockParams { [key: string]: any; } export interface SyscallSleepParams { [key: string]: any; } export interface SyscallNotifyParams { id?: string; title: string; body?: string; icon?: string; timeout?: number; [key: string]: any; } export interface SyscallPortalRespondParams { requestId: string; response?: any; allowed?: boolean; type?: string; windowName?: string | null; [key: string]: any; } export interface SyscallDbusCallParams { service: string; objectPath: string; interface: string; method: string; signature?: string; args?: any[]; bus?: 'user' | 'system'; [key: string]: any; } export interface SyscallDbusGetPropertyParams { service: string; objectPath: string; interface: string; property: string; bus?: 'user' | 'system'; [key: string]: any; } export interface SyscallDbusGetAllPropertiesParams { service: string; objectPath: string; interface: string; bus?: 'user' | 'system'; } export interface SyscallDbusListNamesParams { bus?: 'user' | 'system'; } export interface SyscallLoadLocalFileParams { path: string; [key: string]: any; } export interface SyscallResolveIconParams { name: string; size?: number; theme?: string; } export interface SyscallLaunchResult { ok: boolean; pid?: number; error?: string; } export interface SyscallExecResult { ok: boolean; pid?: number; error?: string; } export interface SyscallListDirResult { ok: boolean; path?: string; entries?: { name: string; type: 'file'|'dir' }[]; error?: string; } export interface SyscallXdgDirectoriesResult { ok: boolean; directories?: XdgDirectories; error?: string; } export interface SyscallReadResult { ok: boolean; content?: string; size?: number; error?: string; } export interface SyscallWriteResult { ok: boolean; bytesWritten?: number; error?: string; } export interface SyscallShutdownResult { ok: boolean; error?: string; } export interface SyscallRestartResult { ok: boolean; error?: string; } export interface SyscallLogoutResult { ok: boolean; error?: string; } export interface SyscallLockResult { ok: boolean; error?: string; } export interface SyscallSleepResult { ok: boolean; error?: string; } export interface SyscallNotifyResult { ok: boolean; error?: string; } export interface SyscallPortalRespondResult { ok: boolean; error?: string; } export interface SyscallDbusCallResult { ok: boolean; stdout?: string; stderr?: string; exitCode?: number; error?: string; } export interface SyscallDbusGetPropertyResult { ok: boolean; stdout?: string; stderr?: string; exitCode?: number; error?: string; } export interface SyscallDbusListNamesResult { ok: boolean; names?: string[]; stdout?: string; stderr?: string; exitCode?: number; error?: string; } export interface SyscallDbusGetAllPropertiesResult { ok: boolean; properties?: Record; stdout?: string; stderr?: string; exitCode?: number; error?: string; } export interface SyscallAudioCaptureParams { sourceId?: string; } export interface SyscallAudioCaptureResult { ok: boolean; source?: WoAudioSource; error?: string; } export interface SyscallLoadLocalFileResult { ok: boolean; error?: string; } export interface PortalRequestEvent { requestId: string; payload: any; kind?: string; } export type WoCapability = | 'window-management' | 'overlay-rendering' | 'desktop-applications' | 'xdg' | 'dbus' | 'portals' | 'filesystem' | 'process-launch' | 'system-control' | 'notifications' | 'audio-capture'; export interface WoPermissionState { requested: readonly WoCapability[]; granted: readonly WoCapability[]; has(capability: WoCapability): boolean; } export interface WoPerformanceStatus { limited: boolean; gpuCompositing: string; webgl: string; sharedDmabuf: boolean | null; reasons: string[]; } export interface WoGlobalAPI { permissions: WoPermissionState; getPerformanceStatus(): Promise; onPerformanceStatus(callback: (status: WoPerformanceStatus) => void): Unsubscribe; windows?: { get(): Promise; on(callback: WindowsCallback): Unsubscribe; action: Compositor['action']; onFocusChange: Compositor['onFocusChange']; onMetadata: Compositor['onWindowMetadata']; monitors: Compositor['onMonitors']; }; overlay?: Pick & { mount(element: HTMLElement, monitorId: string): Unsubscribe; }; desktop?: WoDesktop; xdg?: WoXdg; icons?: WoIcons; dbus?: WoDBus; portals?: WoPortals; audio?: WoAudio; syscall?: Compositor['syscall']; onNotification?: Compositor['onNotification']; } export interface ScreencopyEvent { active: boolean; clientCount: number; } /** * Application information for launching */ export interface ApplicationInfo { name: string; command: string; multi_instance?: boolean; icon?: ApplicationIcon; desktopId?: string; desktopFile?: string; genericName?: string; comment?: string; categories?: string[]; keywords?: string[]; startupWMClass?: string; terminal?: boolean; startupNotify?: boolean; } export interface XdgDirectories { home: string; configHome: string; configDirs: string[]; dataHome: string; dataDirs: string[]; cacheHome: string; stateHome: string; runtimeDir: string | null; desktop: string; documents: string; downloads: string; music: string; pictures: string; publicShare: string; templates: string; videos: string; } export type DBusBus = 'user' | 'system'; export interface DBusCallOptions { service: string; objectPath: string; interface: string; method: string; signature?: string; args?: Array; bus?: DBusBus; } export interface DBusPropertyOptions { service: string; objectPath: string; interface: string; property: string; bus?: DBusBus; } export interface DBusInterfaceOptions { service: string; objectPath: string; interface: string; bus?: DBusBus; } export interface DBusResult { ok: boolean; stdout?: string; stderr?: string; exitCode?: number; error?: string; } export interface WoDBus { call(options: DBusCallOptions): Promise; getProperty(options: DBusPropertyOptions): Promise; getAllProperties(options: DBusInterfaceOptions): Promise; listNames(bus?: DBusBus): Promise; } export interface WoDesktop { applications: { list(options?: SyscallListApplicationsParams): Promise; launch(desktopId: string, files?: string[]): Promise; }; } export interface WoIcons { resolve(name: string, options?: { size?: number; theme?: string }): Promise; } export interface WoXdg { directories(): Promise; } export interface WoAudioSource { id: string; name: string; description: string; monitor: boolean; } export interface WoAudioChunk { format: 's16le'; sampleRate: 48000; channels: 2; data: Uint8Array; timestamp: number; } export interface WoAudio { sources(): Promise<{ ok: boolean; sources: WoAudioSource[]; error?: string }>; startDesktopCapture(): Promise<{ ok: boolean; source?: WoAudioSource; error?: string }>; startCapture(sourceId: string): Promise<{ ok: boolean; source?: WoAudioSource; error?: string }>; stopCapture(): Promise<{ ok: boolean; error?: string }>; onData(callback: (chunk: WoAudioChunk) => void): Unsubscribe; onState(callback: (state: { active: boolean; error?: string }) => void): Unsubscribe; } /** * Icon data for applications - supports multiple formats */ export interface ApplicationIcon { type: 'iconify' | 'base64' | 'url' | 'path'; data: string; mimeType?: string; fallback?: ApplicationIcon; } /** * Focus change callback signature */ export type FocusChangeCallback = (windowName: string, focused: boolean) => void; /** * Window list update callback signature */ export type WindowsCallback = (windows: WoWindow[]) => void; /** * Pixel buffer update callback signature */ export type PixelBufferCallback = (windowName: string, buffer: Uint8Array, width: number, height: number) => void; /** * Unsubscribe function type */ export type Unsubscribe = () => void; /** * Wayland client interface for receiving window updates */ export interface WoClient { permissions?: WoPermissionState; /** * Get the current window list once */ getWindows(): Promise; /** * Subscribe to window list updates */ onWindows(callback: WindowsCallback): Unsubscribe; /** * Subscribe to pixel buffer updates (DMABUF transfers, if supported) */ onPixelBuffer?: (callback: PixelBufferCallback) => Unsubscribe; /** * Send a keybind/management action to the compositor */ sendAction(action: string): void; portals: WoPortals; dbus: WoDBus; desktop: WoDesktop; icons: WoIcons; xdg: WoXdg; audio: WoAudio; } export interface WoPortals { onRequest(callback: (data: PortalRequestEvent) => void): Unsubscribe; /** Open a native desktop context menu through the platform popup path. */ contextMenu(options: WoContextMenuOptions): Promise<{ ok: boolean; selectedId?: string; error?: string }>; respond(requestId: string, response: { allowed: boolean; type?: 'window' | 'monitor' | 'virtual'; windowName?: string | null; [key: string]: unknown; }): Promise; } export interface WoContextMenuOptions { x?: number; y?: number; items: Array<{ id?: string; label?: string; type?: 'normal' | 'separator' | 'checkbox' | 'radio'; enabled?: boolean; checked?: boolean; accelerator?: string; }>; } export type WoClientAPI = WoClient; /** * Compositor interface for controlling windows and the compositor */ export interface Compositor { permissions?: WoPermissionState; /** * Send an action to modify a window */ action(type: CompositorActionType, config: CompositorActionConfig): void; /** * Send an action synchronously */ actionSync(type: string, payload?: Record): void; /** * Execute a syscall (filesystem, process, etc.) with strong typings */ syscall(type: 'list_applications', params?: SyscallListApplicationsParams): Promise; syscall(type: 'launch_desktop', params: SyscallLaunchDesktopParams): Promise; syscall(type: 'xdg_directories', params?: Record): Promise; syscall(type: 'resolve_icon', params: SyscallResolveIconParams): Promise; syscall(type: 'launch', params: SyscallLaunchParams): Promise; syscall(type: 'exec', params: SyscallExecParams): Promise; syscall(type: 'listdir', params?: SyscallListDirParams): Promise; syscall(type: 'read', params: SyscallReadParams): Promise; syscall(type: 'write', params: SyscallWriteParams): Promise; syscall(type: 'shutdown', params?: SyscallShutdownParams): Promise; syscall(type: 'restart', params?: SyscallRestartParams): Promise; syscall(type: 'logout', params?: SyscallLogoutParams): Promise; syscall(type: 'lock', params?: SyscallLockParams): Promise; syscall(type: 'sleep', params?: SyscallSleepParams): Promise; syscall(type: 'notify', params: SyscallNotifyParams): Promise; syscall(type: 'portal_respond', params: SyscallPortalRespondParams): Promise; syscall(type: 'dbus_call', params: SyscallDbusCallParams): Promise; syscall(type: 'dbus_get_property', params: SyscallDbusGetPropertyParams): Promise; syscall(type: 'dbus_get_all_properties', params: SyscallDbusGetAllPropertiesParams): Promise; syscall(type: 'dbus_list_names', params?: SyscallDbusListNamesParams): Promise; syscall(type: 'audio_sources', params?: Record): Promise<{ ok: boolean; sources: WoAudioSource[]; error?: string }>; syscall(type: 'audio_capture_start', params?: SyscallAudioCaptureParams): Promise; syscall(type: 'audio_capture_stop', params?: Record): Promise<{ ok: boolean; error?: string }>; syscall(type: 'load_local_file', params: SyscallLoadLocalFileParams): Promise; syscall(type: string, params?: any): Promise; /** XDG desktop entries, D-Bus and icon helpers. */ dbus: WoDBus; portals: WoPortals; desktop: WoDesktop; icons: WoIcons; xdg: WoXdg; audio: WoAudio; /** * Subscribe to focus changes */ onFocusChange(callback: FocusChangeCallback): Unsubscribe; /** * Subscribe to raw window metadata broadcasts from the compositor */ onWindowMetadata(callback: (metadata: WindowMetadataEvent) => void): Unsubscribe; onMonitors(callback: (monitors: WoMonitor[]) => void): Unsubscribe; /** * Create a damage helper for optimized rendering */ createDamageHelper(options: RendererDamageHelperOptions): RendererDamageHelper; /** * Forward a keyboard event from a canvas window to the compositor. * evdevKey is the Linux evdev keycode; time is milliseconds. */ forwardKeyboard(windowName: string, evdevKey: number, pressed: boolean, time: number): void; forwardPointerMotion(windowName: string, x: number, y: number): void; forwardPointerButton(windowName: string, x: number, y: number, button: number, pressed: boolean, time: number): void; forwardPointerScroll(windowName: string, x: number, y: number, dx: number, dy: number, time: number): void; forwardPointerLeave(windowName: string): void; /** * Quit the compositor */ quit(): void; /** * Reload the UI */ reload(): void; /** * Toggle Electron DevTools */ toggleDevTools(): void; /** * Submit a damaged frame from the renderer */ submitDamageFrame(payload: DamageFramePayload): Promise<{ ok: boolean }>; /** * Subscribe to Wayland surface pixel buffer updates from the compositor. * The compositor captures each Wayland window's content offscreen and sends * raw ARGB8888 pixel data for the client to render. */ onSurfaceBuffer(callback: (data: SurfaceBufferData) => void): Unsubscribe; /** * Subscribe to notification events from the compositor */ onNotification(callback: (data: NotificationData) => void): Unsubscribe; /** * Forward relative mouse motion from the web UI to the compositor. */ forwardRelativePointer(windowName: string, dx: number, dy: number): void; /** * Subscribe to pointer lock requests from the compositor. */ onPointerLockRequest(callback: (data: { window: string; lock: boolean }) => void): Unsubscribe; /** * Subscribe to environment variable updates from the compositor * (e.g. DISPLAY becoming available after XWayland starts). */ onEnvUpdate(callback: (vars: Record) => void): Unsubscribe; /** * Subscribe to generic portal requests so clients can provide custom UI. */ onPortalRequest(callback: (data: PortalRequestEvent) => void): Unsubscribe; /** * Subscribe to screencopy capture events (active/inactive notifications). * Fires when Wayland clients (e.g. OBS, grim) capture the screen via wlr-screencopy. */ onScreencopyEvent(callback: (data: ScreencopyEvent) => void): Unsubscribe; /** * Receive a SharedArrayBuffer for a given Wayland surface. * Sent once when the SAB is first allocated or reallocated. */ onSurfaceSab(callback: (data: SurfaceSabData) => void): Unsubscribe; /** * Subscribe to lightweight surface update signals (no pixel payload). * After receiving this, read pixels directly from the previously-sent SAB. */ onSurfaceUpdate(callback: (data: SurfaceUpdateData) => void): Unsubscribe; } export type CompositorAPI = Compositor; /** * Pixel data for a captured Wayland surface */ export interface SurfaceBufferData { name: string; width: number; height: number; stride: number; pixels: Uint8Array; damageRects?: DamageRect[]; } /** * SharedArrayBuffer registration for a Wayland surface. * Sent once per window when the SAB is first created or reallocated. */ export interface SurfaceSabData { name: string; width: number; height: number; stride: number; sab: SharedArrayBuffer; } /** * Lightweight surface update signal (no pixel data). * The renderer should read from the previously-received SAB. */ export interface SurfaceUpdateData { name: string; width: number; height: number; stride: number; damageRects?: DamageRect[]; } /** * Notification data from the compositor */ export interface NotificationData { id?: string; title: string; body: string; icon?: string; timeout?: number; timestamp?: number; } declare global { window.woClient = {} as WoClient; window.compositor = {} as Compositor; window.wo = {} as WoGlobalAPI; } /** * Input event types from the compositor */ export interface MouseMoveEvent { type: 'pointer_motion'; x: number; y: number; time: number; } export interface MouseButtonEvent { type: 'pointer_button'; button: number; pressed: boolean; time: number; } export interface PointerLeaveEvent { type: 'pointer_leave'; time: number; } export interface ScrollEvent { type: 'pointer_scroll'; vertical: number; horizontal: number; time: number; } export interface KeyboardEvent { type: 'keyboard_key'; key: number; pressed: boolean; time: number; } export type InputEvent = MouseMoveEvent | MouseButtonEvent | PointerLeaveEvent | ScrollEvent | KeyboardEvent; export interface WindowMetadataEvent { type: 'windowMetadata'; metadata: string; } export interface FocusChangeEvent { window: string; focused: boolean; } export interface RendererDamageHelperOptions { name: string; width: number; height: number; maxRects?: number; fullFrameThreshold?: number; } export interface RendererDamageHelper { resize(width: number, height: number): void; markDirty(rect: DamageRect): void; updateFullFrame(rgba: Uint8Array, stride?: number): void; updatePatch(rect: DamageRect, rgba: Uint8Array, stride?: number): void; captureFromCanvas(canvas: any, rects?: DamageRect[]): void; flush(): Promise<{ ok: boolean; seq?: string; reason?: string; skipped?: boolean }>; } export interface DamageRect { x: number; y: number; width: number; height: number; } export interface DamagePatch { rect: DamageRect; rgba: Uint8Array; stride: number; } export interface DamageFramePayload { width: number; height: number; fullFrame?: Uint8Array; fullStride?: number; patches?: DamagePatch[]; }