useWindowManager
useWindowManager() returns the reactive window-manager state plus a set of dispatch functions. Mount it anywhere inside <DesktopProvider>. The library’s own components consume it; consumers use it to build custom UI (alternative docks, a launcher widget, a window-list inspector).
Import
Section titled “Import”import { useWindowManager } from "@react-ui-os/core";Returns
Section titled “Returns”| Property | Type | Description |
|---|---|---|
state | WindowManagerState | Raw state: { windows, focusedId, nextZ, workspaces, activeWorkspaceId }. Rarely needed; the convenience fields cover it. |
windows | OpenWindow[] | All currently-open windows in z-index order. |
focusedWindow | OpenWindow | null | The currently-focused window, or null. |
windowById | (id: string) => OpenWindow | undefined | Look up a window by its stable id. |
openWindow | (payload, initialBounds?) => void | Open or focus a window. Dedups by windowIdOf(payload). |
closeWindow | (id: string) => void | Close a window. Auto-refocuses the next-top. |
focusWindow | (id: string) => void | Bring a window to the top. |
minimizeWindow | (id: string) => void | Flip state to "minimized". Clears focus if the focused window minimized. |
restoreWindow | (id: string) => void | Restore from minimized and focus. |
toggleMaximize | (id: string) => void | Cycle normal ↔ maximized. |
moveWindow | (id, x, y) => void | Update position only. |
resizeWindow | (id, w, h) => void | Update size only. |
setBounds | (id, x, y, w, h) => void | Update position + size in one dispatch. |
switchWorkspace | (workspaceId) => void | Show another workspace; pulls focus there. |
moveWindowToWorkspace | (id, workspaceId) => void | Move a window to another workspace. |
addWorkspace | (workspaceId?) => void | Append a workspace; generates an id when omitted. |
removeWorkspace | (workspaceId) => void | Remove a workspace; refuses the last and migrates its windows to the first remaining. |
WindowPayload
Section titled “WindowPayload”type WindowPayload = | { kind: "app"; appId: string } | { kind: "system"; systemId: string; args?: Record<string, string | number | boolean>; };- App payloads dedup by
appId. Opening the same app twice focuses the existing window. - System payloads dedup by
systemIdplus a stable serialization ofargs. Pass distinctargsto open multiple instances (e.g.{ name: "Window" }and{ name: "Spotlight" }for two component-reference windows).
Stable window ids
Section titled “Stable window ids”import { windowIdOf } from "@react-ui-os/core";
windowIdOf({ kind: "app", appId: "notes" });// → "app:notes"
windowIdOf({ kind: "system", systemId: "component", args: { name: "Window" } });// → "system:component:name=Window"Use this when you need to address a window before it exists (e.g. to read its windowById(id) after a deferred open).
Examples
Section titled “Examples”Open an app from a keyboard shortcut
Section titled “Open an app from a keyboard shortcut”function Launcher() { const { openWindow } = useWindowManager(); useEffect(() => { const onKey = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === "n") { e.preventDefault(); openWindow({ kind: "app", appId: "notes" }); } }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [openWindow]); return null;}Show a window-list inspector
Section titled “Show a window-list inspector”function WindowList() { const { windows, focusedWindow, focusWindow } = useWindowManager(); return ( <ul> {windows.map((w) => ( <li key={w.id}> <button onClick={() => focusWindow(w.id)}> {w.id} {w.id === focusedWindow?.id ? "(focused)" : ""} </button> </li> ))} </ul> );}Sync the focused window’s payload to the URL
Section titled “Sync the focused window’s payload to the URL”const { focusedWindow } = useWindowManager();const router = useRouter();
useEffect(() => { if (focusedWindow?.payload.kind === "app") { router.replace(`/apps/${focusedWindow.payload.appId}`); }}, [focusedWindow, router]);See also
Section titled “See also”- Window: the surface this state drives.
- Themes overview: what tokens are reactive.