{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "window-manager", "title": "Window Manager", "description": "A context-scoped multi-window runtime with drag, resize, z-order, window modes, dock, portals, keyboard controls, and opt-in persistence", "dependencies": [ "@base-ui/react", "daisyui", "lucide-react", "mutative@^1.3.0", "re-resizable@^6.11.2", "zustand@^5.0.14", "zustand-mutative@^1.3.1" ], "files": [ { "path": "registry/default/blocks/window-manager/window-manager-types.ts", "content": "export const WINDOW_MANAGER_SNAPSHOT_VERSION = 1;\n\nexport type WindowManagerWindowMode = 'normal' | 'minimized' | 'maximized' | 'fullscreen';\nexport type WindowManagerRestoreMode = Exclude;\nexport type WindowManagerChrome = 'default' | 'none';\nexport type WindowManagerDockPosition = 'bottom' | 'left' | 'right';\nexport type WindowManagerDuplicatePolicy = 'focus-existing' | 'replace' | 'allow';\nexport type WindowManagerPersistencePolicy = 'layout' | 'none';\n\nexport type WindowManagerBounds = {\n\theight: number;\n\twidth: number;\n\tx: number;\n\ty: number;\n};\n\nexport type WindowManagerSizeConstraints = {\n\tmaxHeight?: number;\n\tmaxWidth?: number;\n\tminHeight: number;\n\tminWidth: number;\n};\n\nexport type WindowManagerCapabilities = {\n\tclose: boolean;\n\tfullscreen: boolean;\n\tmaximize: boolean;\n\tminimize: boolean;\n\tmove: boolean;\n\tresize: boolean;\n};\n\nexport type ManagedWindow = {\n\tbounds: WindowManagerBounds;\n\tcapabilities: WindowManagerCapabilities;\n\tchrome: WindowManagerChrome;\n\tdata?: unknown;\n\tfullscreenRestoreMode: Exclude;\n\ticon?: string;\n\tid: string;\n\tkey?: string;\n\tkind: string;\n\tmode: WindowManagerWindowMode;\n\tpersistence: WindowManagerPersistencePolicy;\n\tpinned: boolean;\n\trestoreMode: WindowManagerRestoreMode;\n\tshowInDock: boolean;\n\tsize: WindowManagerSizeConstraints;\n\ttitle: string;\n};\n\nexport type WindowManagerDockState = {\n\tposition: WindowManagerDockPosition;\n\tsize: number;\n\tvisible: boolean;\n};\n\nexport type WindowManagerWorkspaceState = {\n\tdock: WindowManagerDockState;\n\theight: number;\n\twidth: number;\n};\n\nexport type WindowManagerHydrationState = {\n\terror?: string;\n\tstatus: 'idle' | 'hydrating' | 'ready' | 'error';\n};\n\nexport type WindowManagerOpenOptions = {\n\tbounds?: Partial;\n\tcapabilities?: Partial;\n\tchrome?: WindowManagerChrome;\n\tdata?: unknown;\n\tduplicate?: WindowManagerDuplicatePolicy;\n\ticon?: string;\n\tid?: string;\n\tkey?: string;\n\tkind?: string;\n\tmode?: WindowManagerWindowMode;\n\tpersistence?: WindowManagerPersistencePolicy;\n\tpinned?: boolean;\n\tshowInDock?: boolean;\n\tsize?: Partial;\n\ttitle: string;\n};\n\nexport type WindowManagerWindowPatch = {\n\tcapabilities?: Partial;\n\tdata?: unknown;\n\ticon?: string;\n\tkey?: string;\n\tshowInDock?: boolean;\n\ttitle?: string;\n};\n\nexport type WindowManagerEvent =\n\t| { type: 'opened'; id: string; window: ManagedWindow }\n\t| { type: 'closed'; id: string; result?: unknown; window: ManagedWindow }\n\t| { type: 'focused'; id: string }\n\t| { type: 'minimized'; id: string }\n\t| { type: 'maximized'; id: string }\n\t| { type: 'fullscreen'; id: string }\n\t| { type: 'pinned'; id: string; pinned: boolean }\n\t| { type: 'restored'; id: string; mode: WindowManagerRestoreMode }\n\t| { type: 'moved'; id: string; bounds: WindowManagerBounds }\n\t| { type: 'resized'; id: string; bounds: WindowManagerBounds }\n\t| { type: 'updated'; id: string };\n\nexport type WindowManagerEventListener = (event: WindowManagerEvent) => void;\n\nexport type WindowManagerActions = {\n\tcenter: (id: string) => boolean;\n\tclose: (id: string, result?: unknown) => boolean;\n\tcloseAll: () => void;\n\tcycleFocus: (direction?: 1 | -1) => string | undefined;\n\tfocus: (id: string) => boolean;\n\tfullscreen: (id: string) => boolean;\n\thydrateLayout: (snapshot: WindowManagerSnapshot, options?: { restoreMinimized?: boolean }) => boolean;\n\tmaximize: (id: string) => boolean;\n\tminimize: (id: string) => boolean;\n\tminimizeAll: () => void;\n\tmoveBy: (id: string, delta: { x: number; y: number }) => boolean;\n\topen: (options: WindowManagerOpenOptions) => string;\n\tresetLayout: () => void;\n\tresizeBy: (id: string, delta: { height: number; width: number }) => boolean;\n\trestore: (id: string) => boolean;\n\tsetPinned: (id: string, pinned: boolean) => boolean;\n\tsetBounds: (id: string, bounds: Partial, reason?: 'move' | 'resize') => boolean;\n\tsetDock: (dock: Partial) => void;\n\tsetHydration: (hydration: WindowManagerHydrationState) => void;\n\tsetWorkspaceSize: (size: { height: number; width: number }) => void;\n\ttoggle: (options: WindowManagerOpenOptions) => string;\n\ttoggleFullscreen: (id: string) => boolean;\n\ttoggleMaximize: (id: string) => boolean;\n\ttogglePinned: (id: string) => boolean;\n\tupdate: (id: string, patch: WindowManagerWindowPatch) => boolean;\n};\n\nexport type WindowManagerState = {\n\tactions: WindowManagerActions;\n\tactiveId?: string;\n\tdockOrder: string[];\n\thydration: WindowManagerHydrationState;\n\torder: string[];\n\twindows: Record;\n\tworkspace: WindowManagerWorkspaceState;\n};\n\nexport type WindowManagerSnapshotWindow = Omit & {\n\tdata?: unknown;\n\tpinned?: boolean;\n};\n\nexport type WindowManagerSnapshot = {\n\tdock: WindowManagerDockState;\n\tdockOrder?: string[];\n\torder: string[];\n\tsavedAt: number;\n\tversion: number;\n\twindows: WindowManagerSnapshotWindow[];\n};\n\nexport type WindowManagerStorage = {\n\tgetItem: (key: string) => string | null;\n\tremoveItem: (key: string) => void;\n\tsetItem: (key: string, value: string) => void;\n};\n\nexport type WindowManagerCreateOptions = {\n\tactions?: Partial;\n\tcascadeOffset?: number;\n\tdefaultBounds?: Partial;\n\tdefaultCapabilities?: Partial;\n\tidFactory?: () => string;\n\tinitialWindows?: readonly WindowManagerOpenOptions[];\n\tonEvent?: WindowManagerEventListener;\n\tworkspace?: Partial> & { dock?: Partial };\n};\n", "type": "registry:lib", "target": "@components/window-manager/window-manager-types.ts" }, { "path": "registry/default/blocks/window-manager/window-manager-store.ts", "content": "import { createStore } from 'zustand/vanilla';\nimport { mutative } from 'zustand-mutative';\nimport type {\n\tManagedWindow,\n\tWindowManagerActions,\n\tWindowManagerBounds,\n\tWindowManagerCapabilities,\n\tWindowManagerCreateOptions,\n\tWindowManagerDockState,\n\tWindowManagerEvent,\n\tWindowManagerEventListener,\n\tWindowManagerRestoreMode,\n\tWindowManagerSnapshot,\n\tWindowManagerState,\n\tWindowManagerWindowMode,\n\tWindowManagerWorkspaceState,\n} from './window-manager-types';\nimport { WINDOW_MANAGER_SNAPSHOT_VERSION } from './window-manager-types';\n\nconst DEFAULT_BOUNDS: WindowManagerBounds = { x: 64, y: 48, width: 640, height: 420 };\nconst DEFAULT_CAPABILITIES: WindowManagerCapabilities = {\n\tclose: true,\n\tfullscreen: true,\n\tmaximize: true,\n\tminimize: true,\n\tmove: true,\n\tresize: true,\n};\nconst DEFAULT_DOCK: WindowManagerDockState = { visible: true, position: 'bottom', size: 52 };\nconst WINDOW_MANAGER_WINDOW_RECORD = Symbol('WindowManagerWindowRecord');\nconst DEFAULT_WORKSPACE: WindowManagerWorkspaceState = { width: 1280, height: 720, dock: DEFAULT_DOCK };\n\nexport type WindowManagerStore = ReturnType;\n\nexport function createWindowManagerStore(options: WindowManagerCreateOptions = {}) {\n\tlet sequence = 0;\n\tconst listeners = new Set();\n\tif (options.onEvent) listeners.add(options.onEvent);\n\tconst emit = (event: WindowManagerEvent) => {\n\t\tfor (const listener of listeners) listener(event);\n\t};\n\tconst idFactory =\n\t\toptions.idFactory ??\n\t\t(() => {\n\t\t\tsequence += 1;\n\t\t\treturn `window-${sequence}`;\n\t\t});\n\tconst cascadeOffset = Math.max(0, options.cascadeOffset ?? 28);\n\tconst workspace = normalizeWorkspace(options.workspace);\n\tconst defaultBounds = { ...DEFAULT_BOUNDS, ...options.defaultBounds };\n\tconst defaultCapabilities = { ...DEFAULT_CAPABILITIES, ...options.defaultCapabilities };\n\tconst initialWindows = createWindowManagerWindowRecord();\n\tconst initialDockOrder: string[] = [];\n\tconst initialOrder: string[] = [];\n\tfor (const initial of options.initialWindows ?? []) {\n\t\tconst duplicate = initial.duplicate ?? 'focus-existing';\n\t\tconst matches = initial.key ? initialOrder.filter((id) => initialWindows[id]?.key === initial.key) : [];\n\t\tif (matches.length && duplicate === 'focus-existing') {\n\t\t\tconst id = matches.at(-1) as string;\n\t\t\tinitialOrder.splice(initialOrder.indexOf(id), 1);\n\t\t\tinitialOrder.push(id);\n\t\t\tcontinue;\n\t\t}\n\t\tif (matches.length && duplicate === 'replace') {\n\t\t\tconst protectedId = matches.find((id) => !initialWindows[id].capabilities.close);\n\t\t\tif (protectedId) {\n\t\t\t\tinitialOrder.splice(initialOrder.indexOf(protectedId), 1);\n\t\t\t\tinitialOrder.push(protectedId);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const id of matches) {\n\t\t\t\tdelete initialWindows[id];\n\t\t\t\tinitialDockOrder.splice(initialDockOrder.indexOf(id), 1);\n\t\t\t\tinitialOrder.splice(initialOrder.indexOf(id), 1);\n\t\t\t}\n\t\t}\n\t\tconst id = takeUniqueId(initialWindows, initial.id);\n\t\tconst offset = cascadeOffset * (initialOrder.length % 8);\n\t\tconst mode = initial.mode ?? 'normal';\n\t\tconst win = normalizeManagedWindow(\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tkey: initial.key,\n\t\t\t\tkind: initial.kind ?? 'default',\n\t\t\t\ttitle: initial.title,\n\t\t\t\ticon: initial.icon,\n\t\t\t\tdata: initial.data,\n\t\t\t\tbounds: {\n\t\t\t\t\t...defaultBounds,\n\t\t\t\t\tx: (initial.bounds?.x ?? defaultBounds.x ?? DEFAULT_BOUNDS.x) + offset,\n\t\t\t\t\ty: (initial.bounds?.y ?? defaultBounds.y ?? DEFAULT_BOUNDS.y) + offset,\n\t\t\t\t\t...initial.bounds,\n\t\t\t\t},\n\t\t\t\tsize: initial.size,\n\t\t\t\tcapabilities: initial.capabilities,\n\t\t\t\tmode,\n\t\t\t\trestoreMode: mode === 'minimized' ? 'normal' : mode,\n\t\t\t\tfullscreenRestoreMode: 'normal',\n\t\t\t\tchrome: initial.chrome ?? 'default',\n\t\t\t\tshowInDock: initial.showInDock ?? true,\n\t\t\t\tpersistence: initial.persistence ?? 'layout',\n\t\t\t\tpinned: initial.pinned ?? false,\n\t\t\t},\n\t\t\tworkspace,\n\t\t\tdefaultBounds,\n\t\t\tdefaultCapabilities,\n\t\t);\n\t\tinitialWindows[id] = win;\n\t\tinitialDockOrder.push(id);\n\t\tinitialOrder.push(id);\n\t}\n\n\tconst initialFullscreenIds = initialOrder.filter((id) => initialWindows[id]?.mode === 'fullscreen');\n\tfor (const id of initialFullscreenIds.slice(0, -1)) {\n\t\tconst win = initialWindows[id];\n\t\twin.mode = win.fullscreenRestoreMode;\n\t\twin.restoreMode = win.mode;\n\t}\n\tconst initialFullscreenId = initialFullscreenIds.at(-1);\n\tif (initialFullscreenId) {\n\t\tinitialOrder.splice(initialOrder.indexOf(initialFullscreenId), 1);\n\t\tinitialOrder.push(initialFullscreenId);\n\t}\n\tinitialOrder.splice(0, initialOrder.length, ...normalizeWindowManagerOrder(initialOrder, initialWindows));\n\n\tfunction takeUniqueId(existing: Record, preferred?: string) {\n\t\tconst baseId = preferred ?? idFactory();\n\t\tlet id = baseId;\n\t\twhile (existing[id]) {\n\t\t\tsequence += 1;\n\t\t\tid = `${baseId}-${sequence}`;\n\t\t}\n\t\treturn id;\n\t}\n\n\tconst store = createStore(\n\t\tmutative(\n\t\t\t(setState, getState) => {\n\t\t\t\tconst focus = (id: string) => {\n\t\t\t\t\tconst currentState = getState();\n\t\t\t\t\tconst current = currentState.windows[id];\n\t\t\t\t\tif (!current) return false;\n\t\t\t\t\tconst hasOtherFullscreen = Object.values(currentState.windows).some(\n\t\t\t\t\t\t(win) => win.id !== id && win.mode === 'fullscreen',\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!hasOtherFullscreen &&\n\t\t\t\t\t\tcurrent.mode !== 'minimized' &&\n\t\t\t\t\t\tcurrentState.activeId === id &&\n\t\t\t\t\t\tcurrentState.order.at(-1) === id\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tlet restoredMode: WindowManagerRestoreMode | undefined;\n\t\t\t\t\tlet forcedRestores: Array<{ id: string; mode: WindowManagerRestoreMode }> = [];\n\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\tforcedRestores = restoreOtherFullscreenWindows(state, id);\n\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\tif (win.mode === 'minimized') {\n\t\t\t\t\t\t\trestoredMode = win.restoreMode;\n\t\t\t\t\t\t\twin.mode = win.restoreMode;\n\t\t\t\t\t\t}\n\t\t\t\t\t\traiseWindowManagerWindow(state, id);\n\t\t\t\t\t\tstate.activeId = id;\n\t\t\t\t\t});\n\t\t\t\t\tfor (const restored of forcedRestores) emit({ type: 'restored', ...restored });\n\t\t\t\t\tif (restoredMode) emit({ type: 'restored', id, mode: restoredMode });\n\t\t\t\t\temit({ type: 'focused', id });\n\t\t\t\t\treturn true;\n\t\t\t\t};\n\n\t\t\t\tconst actions: WindowManagerActions = {\n\t\t\t\t\tcenter: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current || current.mode !== 'normal' || !current.capabilities.move) return false;\n\t\t\t\t\t\tconst area = getWindowManagerAvailableBounds(getState().workspace);\n\t\t\t\t\t\treturn actions.setBounds(\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: area.x + Math.max(0, (area.width - current.bounds.width) / 2),\n\t\t\t\t\t\t\t\ty: area.y + Math.max(0, (area.height - current.bounds.height) / 2),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'move',\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tclose: (id, result) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current?.capabilities.close) return false;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tdelete state.windows[id];\n\t\t\t\t\t\t\tstate.dockOrder = state.dockOrder.filter((item) => item !== id);\n\t\t\t\t\t\t\tstate.order = state.order.filter((item) => item !== id);\n\t\t\t\t\t\t\tif (state.activeId === id) state.activeId = findTopVisibleId(state);\n\t\t\t\t\t\t});\n\t\t\t\t\t\temit({ type: 'closed', id, result, window: current });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tcloseAll: () => {\n\t\t\t\t\t\tfor (const id of [...getState().order].reverse()) actions.close(id);\n\t\t\t\t\t},\n\t\t\t\t\tcycleFocus: (direction = 1) => {\n\t\t\t\t\t\tconst state = getState();\n\t\t\t\t\t\tconst active = state.activeId ? state.windows[state.activeId] : undefined;\n\t\t\t\t\t\tif (active?.mode === 'fullscreen') return active.id;\n\t\t\t\t\t\tconst visible = state.order.filter((id) => state.windows[id]?.mode !== 'minimized');\n\t\t\t\t\t\tif (!visible.length) return undefined;\n\t\t\t\t\t\tconst currentIndex = state.activeId ? visible.indexOf(state.activeId) : -1;\n\t\t\t\t\t\tconst nextIndex =\n\t\t\t\t\t\t\tcurrentIndex < 0\n\t\t\t\t\t\t\t\t? direction > 0\n\t\t\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t\t\t: visible.length - 1\n\t\t\t\t\t\t\t\t: (currentIndex + direction + visible.length) % visible.length;\n\t\t\t\t\t\tconst id = visible[nextIndex];\n\t\t\t\t\t\tfocus(id);\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t},\n\t\t\t\t\tfocus,\n\t\t\t\t\tfullscreen: (id) => setWindowMode(id, 'fullscreen', 'fullscreen'),\n\t\t\t\t\thydrateLayout: (snapshot, hydrateOptions) => {\n\t\t\t\t\t\tif (!isWindowManagerSnapshot(snapshot)) return false;\n\t\t\t\t\t\tconst currentWorkspace = getState().workspace;\n\t\t\t\t\t\tconst hydratedWorkspace = {\n\t\t\t\t\t\t\t...currentWorkspace,\n\t\t\t\t\t\t\tdock: normalizeDock(snapshot.dock, currentWorkspace),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst nextWindows = createWindowManagerWindowRecord();\n\t\t\t\t\t\tconst nextOrder: string[] = [];\n\t\t\t\t\t\tfor (const item of snapshot.windows) {\n\t\t\t\t\t\t\tif (item.persistence === 'none' || nextWindows[item.id]) continue;\n\t\t\t\t\t\t\tconst mode =\n\t\t\t\t\t\t\t\thydrateOptions?.restoreMinimized === false && item.mode === 'minimized' ? item.restoreMode : item.mode;\n\t\t\t\t\t\t\tnextWindows[item.id] = normalizeManagedWindow(\n\t\t\t\t\t\t\t\t{ ...item, mode, data: item.data },\n\t\t\t\t\t\t\t\thydratedWorkspace,\n\t\t\t\t\t\t\t\tdefaultBounds,\n\t\t\t\t\t\t\t\tdefaultCapabilities,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tnextOrder.push(item.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst ordered = snapshot.order.filter((id) => nextWindows[id]);\n\t\t\t\t\t\tfor (const id of nextOrder) if (!ordered.includes(id)) ordered.push(id);\n\t\t\t\t\t\tconst dockOrdered = (snapshot.dockOrder ?? nextOrder).filter((id) => nextWindows[id]);\n\t\t\t\t\t\tfor (const id of nextOrder) if (!dockOrdered.includes(id)) dockOrdered.push(id);\n\t\t\t\t\t\tconst fullscreenIds = ordered.filter((id) => nextWindows[id]?.mode === 'fullscreen');\n\t\t\t\t\t\tfor (const id of fullscreenIds.slice(0, -1)) {\n\t\t\t\t\t\t\tconst win = nextWindows[id];\n\t\t\t\t\t\t\twin.mode = win.fullscreenRestoreMode;\n\t\t\t\t\t\t\twin.restoreMode = win.mode;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst fullscreenId = fullscreenIds.at(-1);\n\t\t\t\t\t\tif (fullscreenId) {\n\t\t\t\t\t\t\tordered.splice(ordered.indexOf(fullscreenId), 1);\n\t\t\t\t\t\t\tordered.push(fullscreenId);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst rankedOrder = normalizeWindowManagerOrder(ordered, nextWindows);\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tstate.windows = nextWindows;\n\t\t\t\t\t\t\tstate.dockOrder = dockOrdered;\n\t\t\t\t\t\t\tstate.order = rankedOrder;\n\t\t\t\t\t\t\tstate.activeId = findTopVisibleId(state);\n\t\t\t\t\t\t\tstate.workspace.dock = hydratedWorkspace.dock;\n\t\t\t\t\t\t\tstate.hydration = { status: 'ready' };\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tmaximize: (id) => setWindowMode(id, 'maximized', 'maximized'),\n\t\t\t\t\tminimize: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current || current.mode === 'minimized' || !current.capabilities.minimize) return false;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\twin.restoreMode = normalizeRestoreMode(win.mode);\n\t\t\t\t\t\t\twin.mode = 'minimized';\n\t\t\t\t\t\t\tstate.order = normalizeWindowManagerOrder(state.order, state.windows);\n\t\t\t\t\t\t\tif (state.activeId === id) state.activeId = findTopVisibleId(state);\n\t\t\t\t\t\t});\n\t\t\t\t\t\temit({ type: 'minimized', id });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tminimizeAll: () => {\n\t\t\t\t\t\tconst minimized: string[] = [];\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tfor (const id of state.order) {\n\t\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\t\tif (!win || win.mode === 'minimized' || !win.capabilities.minimize) continue;\n\t\t\t\t\t\t\t\twin.restoreMode = normalizeRestoreMode(win.mode);\n\t\t\t\t\t\t\t\twin.mode = 'minimized';\n\t\t\t\t\t\t\t\tminimized.push(id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstate.order = normalizeWindowManagerOrder(state.order, state.windows);\n\t\t\t\t\t\t\tstate.activeId = findTopVisibleId(state);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfor (const id of minimized) emit({ type: 'minimized', id });\n\t\t\t\t\t},\n\t\t\t\t\tmoveBy: (id, delta) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current) return false;\n\t\t\t\t\t\treturn actions.setBounds(id, { x: current.bounds.x + delta.x, y: current.bounds.y + delta.y }, 'move');\n\t\t\t\t\t},\n\t\t\t\t\topen: (openOptions) => {\n\t\t\t\t\t\tconst duplicate = openOptions.duplicate ?? 'focus-existing';\n\t\t\t\t\t\tconst existingWindows = openOptions.key\n\t\t\t\t\t\t\t? [...getState().order]\n\t\t\t\t\t\t\t\t\t.reverse()\n\t\t\t\t\t\t\t\t\t.flatMap((id) => (getState().windows[id]?.key === openOptions.key ? [getState().windows[id]] : []))\n\t\t\t\t\t\t\t: [];\n\t\t\t\t\t\tconst existing = existingWindows[0];\n\t\t\t\t\t\tif (existing && duplicate === 'focus-existing') {\n\t\t\t\t\t\t\tfocus(existing.id);\n\t\t\t\t\t\t\treturn existing.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (duplicate === 'replace') {\n\t\t\t\t\t\t\tconst protectedWindow = existingWindows.find((candidate) => !candidate.capabilities.close);\n\t\t\t\t\t\t\tif (protectedWindow) {\n\t\t\t\t\t\t\t\tfocus(protectedWindow.id);\n\t\t\t\t\t\t\t\treturn protectedWindow.id;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (const candidate of existingWindows) {\n\t\t\t\t\t\t\t\tactions.close(candidate.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst id = takeUniqueId(getState().windows, openOptions.id);\n\t\t\t\t\t\tconst state = getState();\n\t\t\t\t\t\tconst offset = cascadeOffset * (state.order.length % 8);\n\t\t\t\t\t\tconst bounds = {\n\t\t\t\t\t\t\t...defaultBounds,\n\t\t\t\t\t\t\tx: (openOptions.bounds?.x ?? defaultBounds.x ?? DEFAULT_BOUNDS.x) + offset,\n\t\t\t\t\t\t\ty: (openOptions.bounds?.y ?? defaultBounds.y ?? DEFAULT_BOUNDS.y) + offset,\n\t\t\t\t\t\t\t...openOptions.bounds,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst mode = openOptions.mode ?? 'normal';\n\t\t\t\t\t\tconst win = normalizeManagedWindow(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\tkey: openOptions.key,\n\t\t\t\t\t\t\t\tkind: openOptions.kind ?? 'default',\n\t\t\t\t\t\t\t\ttitle: openOptions.title,\n\t\t\t\t\t\t\t\ticon: openOptions.icon,\n\t\t\t\t\t\t\t\tdata: openOptions.data,\n\t\t\t\t\t\t\t\tbounds,\n\t\t\t\t\t\t\t\tsize: openOptions.size,\n\t\t\t\t\t\t\t\tcapabilities: openOptions.capabilities,\n\t\t\t\t\t\t\t\tmode,\n\t\t\t\t\t\t\t\trestoreMode: mode === 'minimized' ? 'normal' : mode,\n\t\t\t\t\t\t\t\tfullscreenRestoreMode: 'normal',\n\t\t\t\t\t\t\t\tchrome: openOptions.chrome ?? 'default',\n\t\t\t\t\t\t\t\tshowInDock: openOptions.showInDock ?? true,\n\t\t\t\t\t\t\t\tpersistence: openOptions.persistence ?? 'layout',\n\t\t\t\t\t\t\t\tpinned: openOptions.pinned ?? false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstate.workspace,\n\t\t\t\t\t\t\tdefaultBounds,\n\t\t\t\t\t\t\tdefaultCapabilities,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlet forcedRestores: Array<{ id: string; mode: WindowManagerRestoreMode }> = [];\n\t\t\t\t\t\tsetState((draft) => {\n\t\t\t\t\t\t\tforcedRestores = restoreOtherFullscreenWindows(draft, id);\n\t\t\t\t\t\t\tdraft.windows[id] = win;\n\t\t\t\t\t\t\tdraft.dockOrder.push(id);\n\t\t\t\t\t\t\tdraft.order.push(id);\n\t\t\t\t\t\t\traiseWindowManagerWindow(draft, id);\n\t\t\t\t\t\t\tdraft.activeId = id;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfor (const restored of forcedRestores) emit({ type: 'restored', ...restored });\n\t\t\t\t\t\temit({ type: 'opened', id, window: win });\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t},\n\t\t\t\t\tresetLayout: () => {\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tstate.dockOrder.forEach((id, index) => {\n\t\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\t\twin.mode = 'normal';\n\t\t\t\t\t\t\t\twin.restoreMode = 'normal';\n\t\t\t\t\t\t\t\twin.fullscreenRestoreMode = 'normal';\n\t\t\t\t\t\t\t\twin.bounds = clampWindowManagerBounds(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...defaultBounds,\n\t\t\t\t\t\t\t\t\t\tx: (defaultBounds.x ?? DEFAULT_BOUNDS.x) + cascadeOffset * (index % 8),\n\t\t\t\t\t\t\t\t\t\ty: (defaultBounds.y ?? DEFAULT_BOUNDS.y) + cascadeOffset * (index % 8),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\twin,\n\t\t\t\t\t\t\t\t\tstate.workspace,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tstate.order = normalizeWindowManagerOrder(state.order, state.windows);\n\t\t\t\t\t\t\tstate.activeId = findTopVisibleId(state);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tresizeBy: (id, delta) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current) return false;\n\t\t\t\t\t\treturn actions.setBounds(\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t{ width: current.bounds.width + delta.width, height: current.bounds.height + delta.height },\n\t\t\t\t\t\t\t'resize',\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\trestore: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current || current.mode === 'normal') return false;\n\t\t\t\t\t\tconst mode =\n\t\t\t\t\t\t\tcurrent.mode === 'minimized'\n\t\t\t\t\t\t\t\t? current.restoreMode\n\t\t\t\t\t\t\t\t: current.mode === 'fullscreen'\n\t\t\t\t\t\t\t\t\t? current.fullscreenRestoreMode\n\t\t\t\t\t\t\t\t\t: 'normal';\n\t\t\t\t\t\tlet forcedRestores: Array<{ id: string; mode: WindowManagerRestoreMode }> = [];\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tforcedRestores = restoreOtherFullscreenWindows(state, id);\n\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\twin.mode = mode;\n\t\t\t\t\t\t\twin.restoreMode = mode;\n\t\t\t\t\t\t\traiseWindowManagerWindow(state, id);\n\t\t\t\t\t\t\tstate.activeId = id;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfor (const restored of forcedRestores) emit({ type: 'restored', ...restored });\n\t\t\t\t\t\temit({ type: 'restored', id, mode });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tsetBounds: (id, patch, reason = 'move') => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current || current.mode !== 'normal') return false;\n\t\t\t\t\t\tif (reason === 'move' && !current.capabilities.move) return false;\n\t\t\t\t\t\tif (reason === 'resize' && !current.capabilities.resize) return false;\n\t\t\t\t\t\tlet next: WindowManagerBounds | undefined;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\tnext = clampWindowManagerBounds({ ...win.bounds, ...patch }, win, state.workspace);\n\t\t\t\t\t\t\twin.bounds = next;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!next) return false;\n\t\t\t\t\t\temit({ type: reason === 'resize' ? 'resized' : 'moved', id, bounds: next });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tsetDock: (dock) => {\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tstate.workspace.dock = normalizeDock({ ...state.workspace.dock, ...dock }, state.workspace);\n\t\t\t\t\t\t\tfor (const win of Object.values(state.windows)) {\n\t\t\t\t\t\t\t\twin.bounds = clampWindowManagerBounds(win.bounds, win, state.workspace);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tsetHydration: (hydration) => setState((state) => void (state.hydration = hydration)),\n\t\t\t\t\tsetPinned: (id, pinned) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\tif (!current) return false;\n\t\t\t\t\t\tif (current.pinned === pinned) return true;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\twin.pinned = pinned;\n\t\t\t\t\t\t\traiseWindowManagerWindow(state, id);\n\t\t\t\t\t\t});\n\t\t\t\t\t\temit({ type: 'pinned', id, pinned });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tsetWorkspaceSize: (size) => {\n\t\t\t\t\t\tconst current = getState().workspace;\n\t\t\t\t\t\tconst width = finitePositive(size.width, current.width);\n\t\t\t\t\t\tconst height = finitePositive(size.height, current.height);\n\t\t\t\t\t\tif (width === current.width && height === current.height) return;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tstate.workspace.width = width;\n\t\t\t\t\t\t\tstate.workspace.height = height;\n\t\t\t\t\t\t\tstate.workspace.dock = normalizeDock(state.workspace.dock, state.workspace);\n\t\t\t\t\t\t\tfor (const win of Object.values(state.windows)) {\n\t\t\t\t\t\t\t\twin.bounds = clampWindowManagerBounds(win.bounds, win, state.workspace);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\ttoggle: (openOptions) => {\n\t\t\t\t\t\tconst existing = openOptions.key\n\t\t\t\t\t\t\t? Object.values(getState().windows).find((win) => win.key === openOptions.key)\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\tif (!existing) return actions.open(openOptions);\n\t\t\t\t\t\tif (existing.mode === 'minimized') actions.restore(existing.id);\n\t\t\t\t\t\telse if (getState().activeId === existing.id && existing.capabilities.minimize)\n\t\t\t\t\t\t\tactions.minimize(existing.id);\n\t\t\t\t\t\telse actions.focus(existing.id);\n\t\t\t\t\t\treturn existing.id;\n\t\t\t\t\t},\n\t\t\t\t\ttoggleFullscreen: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\treturn current?.mode === 'fullscreen' ? actions.restore(id) : actions.fullscreen(id);\n\t\t\t\t\t},\n\t\t\t\t\ttoggleMaximize: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\treturn current?.mode === 'maximized' ? actions.restore(id) : actions.maximize(id);\n\t\t\t\t\t},\n\t\t\t\t\ttogglePinned: (id) => {\n\t\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\t\treturn current ? actions.setPinned(id, !current.pinned) : false;\n\t\t\t\t\t},\n\t\t\t\t\tupdate: (id, patch) => {\n\t\t\t\t\t\tif (!getState().windows[id]) return false;\n\t\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\t\tif (patch.title !== undefined) win.title = patch.title;\n\t\t\t\t\t\t\tif (patch.icon !== undefined) win.icon = patch.icon;\n\t\t\t\t\t\t\tif (patch.key !== undefined) win.key = patch.key;\n\t\t\t\t\t\t\tif (patch.data !== undefined) win.data = patch.data;\n\t\t\t\t\t\t\tif (patch.showInDock !== undefined) win.showInDock = patch.showInDock;\n\t\t\t\t\t\t\tif (patch.capabilities) Object.assign(win.capabilities, patch.capabilities);\n\t\t\t\t\t\t});\n\t\t\t\t\t\temit({ type: 'updated', id });\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tfunction setWindowMode(id: string, mode: 'maximized' | 'fullscreen', eventType: 'maximized' | 'fullscreen') {\n\t\t\t\t\tconst current = getState().windows[id];\n\t\t\t\t\tconst capability = mode === 'maximized' ? current?.capabilities.maximize : current?.capabilities.fullscreen;\n\t\t\t\t\tif (!current || !capability || current.mode === mode) return false;\n\t\t\t\t\tlet forcedRestores: Array<{ id: string; mode: WindowManagerRestoreMode }> = [];\n\t\t\t\t\tsetState((state) => {\n\t\t\t\t\t\tforcedRestores = restoreOtherFullscreenWindows(state, id);\n\t\t\t\t\t\tconst win = state.windows[id];\n\t\t\t\t\t\tif (!win) return;\n\t\t\t\t\t\tif (mode === 'fullscreen') {\n\t\t\t\t\t\t\tconst previousMode = win.mode === 'minimized' ? win.restoreMode : win.mode;\n\t\t\t\t\t\t\twin.fullscreenRestoreMode = previousMode === 'maximized' ? 'maximized' : 'normal';\n\t\t\t\t\t\t}\n\t\t\t\t\t\twin.mode = mode;\n\t\t\t\t\t\twin.restoreMode = mode;\n\t\t\t\t\t\traiseWindowManagerWindow(state, id);\n\t\t\t\t\t\tstate.activeId = id;\n\t\t\t\t\t});\n\t\t\t\t\tfor (const restored of forcedRestores) emit({ type: 'restored', ...restored });\n\t\t\t\t\temit({ type: eventType, id } as WindowManagerEvent);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\twindows: initialWindows,\n\t\t\t\t\tdockOrder: initialDockOrder,\n\t\t\t\t\torder: initialOrder,\n\t\t\t\t\tactiveId: findTopVisibleId({ windows: initialWindows, order: initialOrder }),\n\t\t\t\t\tworkspace,\n\t\t\t\t\thydration: { status: 'idle' },\n\t\t\t\t\tactions: { ...actions, ...options.actions },\n\t\t\t\t};\n\t\t\t},\n\t\t\t{\n\t\t\t\tmark: (value) =>\n\t\t\t\t\tisWindowManagerWindowRecord(value)\n\t\t\t\t\t\t? () => cloneNullPrototypeRecord(value as Record)\n\t\t\t\t\t\t: undefined,\n\t\t\t},\n\t\t),\n\t);\n\n\treturn Object.assign(store, {\n\t\tsubscribeEvents(listener: WindowManagerEventListener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => listeners.delete(listener);\n\t\t},\n\t});\n}\n\nexport function getWindowManagerAvailableBounds(workspace: WindowManagerWorkspaceState): WindowManagerBounds {\n\tlet x = 0;\n\tlet y = 0;\n\tlet width = Math.max(1, workspace.width);\n\tlet height = Math.max(1, workspace.height);\n\tif (!workspace.dock.visible) return { x, y, width, height };\n\tconst size = Math.max(0, workspace.dock.size);\n\tif (workspace.dock.position === 'left') {\n\t\tx = Math.min(size, width - 1);\n\t\twidth = Math.max(1, width - size);\n\t} else if (workspace.dock.position === 'right') {\n\t\twidth = Math.max(1, width - size);\n\t} else {\n\t\theight = Math.max(1, height - size);\n\t}\n\treturn { x, y, width, height };\n}\n\nexport function getWindowManagerRenderBounds(win: ManagedWindow, workspace: WindowManagerWorkspaceState) {\n\tif (win.mode === 'fullscreen') return { x: 0, y: 0, width: workspace.width, height: workspace.height };\n\tif (win.mode === 'maximized') return getWindowManagerAvailableBounds(workspace);\n\treturn win.bounds;\n}\n\nexport function clampWindowManagerBounds(\n\tbounds: WindowManagerBounds,\n\twin: Pick,\n\tworkspace: WindowManagerWorkspaceState,\n) {\n\tconst area = getWindowManagerAvailableBounds(workspace);\n\tconst minWidth = Math.min(Math.max(1, win.size.minWidth), area.width);\n\tconst minHeight = Math.min(Math.max(1, win.size.minHeight), area.height);\n\tconst maxWidth = Math.min(Math.max(minWidth, win.size.maxWidth ?? area.width), area.width);\n\tconst maxHeight = Math.min(Math.max(minHeight, win.size.maxHeight ?? area.height), area.height);\n\tconst width = clamp(finitePositive(bounds.width, minWidth), minWidth, maxWidth);\n\tconst height = clamp(finitePositive(bounds.height, minHeight), minHeight, maxHeight);\n\treturn {\n\t\tx: clamp(finiteNumber(bounds.x, area.x), area.x, area.x + area.width - width),\n\t\ty: clamp(finiteNumber(bounds.y, area.y), area.y, area.y + area.height - height),\n\t\twidth,\n\t\theight,\n\t};\n}\n\nexport function getWindowManagerInvariantErrors(state: WindowManagerState) {\n\tconst errors: string[] = [];\n\tconst ids = Object.keys(state.windows);\n\tif (new Set(state.dockOrder).size !== state.dockOrder.length) errors.push('dockOrder contains duplicate ids');\n\tif (state.dockOrder.some((id) => !state.windows[id])) errors.push('dockOrder references missing windows');\n\tif (ids.some((id) => !state.dockOrder.includes(id))) errors.push('windows contains ids missing from dockOrder');\n\tif (new Set(state.order).size !== state.order.length) errors.push('order contains duplicate ids');\n\tif (state.order.some((id) => !state.windows[id])) errors.push('order references missing windows');\n\tif (ids.some((id) => !state.order.includes(id))) errors.push('windows contains ids missing from order');\n\tif (\n\t\tstate.order.some(\n\t\t\t(id, index) =>\n\t\t\t\tindex > 0 && windowOrderRank(state.windows[state.order[index - 1]]) > windowOrderRank(state.windows[id]),\n\t\t)\n\t) {\n\t\terrors.push('order violates normal, pinned, and fullscreen layers');\n\t}\n\tif (state.activeId && !state.windows[state.activeId]) errors.push('activeId references a missing window');\n\tif (state.activeId && state.windows[state.activeId]?.mode === 'minimized')\n\t\terrors.push('activeId references a minimized window');\n\tconst fullscreenIds = ids.filter((id) => state.windows[id]?.mode === 'fullscreen');\n\tif (fullscreenIds.length > 1) errors.push('multiple fullscreen windows are active');\n\tif (fullscreenIds.length === 1 && state.activeId !== fullscreenIds[0]) {\n\t\terrors.push('fullscreen window is not active');\n\t}\n\tfor (const win of Object.values(state.windows)) {\n\t\tif (!Number.isFinite(win.bounds.x + win.bounds.y + win.bounds.width + win.bounds.height)) {\n\t\t\terrors.push(`${win.id} has non-finite bounds`);\n\t\t}\n\t\tif (win.bounds.width <= 0 || win.bounds.height <= 0) errors.push(`${win.id} has non-positive size`);\n\t}\n\treturn errors;\n}\n\nexport function isWindowManagerSnapshot(value: unknown): value is WindowManagerSnapshot {\n\tif (!isRecord(value) || value.version !== WINDOW_MANAGER_SNAPSHOT_VERSION) return false;\n\tif (!Number.isFinite(value.savedAt) || !Array.isArray(value.windows) || !Array.isArray(value.order)) return false;\n\tif (!isRecord(value.dock)) return false;\n\tif (\n\t\ttypeof value.dock.visible !== 'boolean' ||\n\t\t!['bottom', 'left', 'right'].includes(String(value.dock.position)) ||\n\t\t!isFiniteNonNegative(value.dock.size)\n\t) {\n\t\treturn false;\n\t}\n\tif (!value.order.every((id): id is string => typeof id === 'string')) return false;\n\tif (new Set(value.order).size !== value.order.length) return false;\n\tif (value.dockOrder !== undefined) {\n\t\tif (!Array.isArray(value.dockOrder)) return false;\n\t\tif (!value.dockOrder.every((id): id is string => typeof id === 'string')) return false;\n\t\tif (new Set(value.dockOrder).size !== value.dockOrder.length) return false;\n\t}\n\tconst ids = new Set();\n\tfor (const item of value.windows) {\n\t\tif (!isRecord(item) || typeof item.id !== 'string' || !item.id || ids.has(item.id)) return false;\n\t\tids.add(item.id);\n\t\tif (typeof item.title !== 'string' || typeof item.kind !== 'string') return false;\n\t\tif (item.key !== undefined && typeof item.key !== 'string') return false;\n\t\tif (item.icon !== undefined && typeof item.icon !== 'string') return false;\n\t\tif (!isBounds(item.bounds) || !isRecord(item.size) || !isRecord(item.capabilities)) return false;\n\t\tif (!isFinitePositive(item.size.minWidth) || !isFinitePositive(item.size.minHeight)) return false;\n\t\tif (item.size.maxWidth !== undefined && !isFinitePositive(item.size.maxWidth)) return false;\n\t\tif (item.size.maxHeight !== undefined && !isFinitePositive(item.size.maxHeight)) return false;\n\t\tconst capabilities = item.capabilities;\n\t\tif (\n\t\t\t!['close', 'fullscreen', 'maximize', 'minimize', 'move', 'resize'].every(\n\t\t\t\t(key) => typeof capabilities[key] === 'boolean',\n\t\t\t)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!['normal', 'minimized', 'maximized', 'fullscreen'].includes(String(item.mode))) return false;\n\t\tif (!['normal', 'maximized', 'fullscreen'].includes(String(item.restoreMode))) return false;\n\t\tif (!['normal', 'maximized'].includes(String(item.fullscreenRestoreMode))) return false;\n\t\tif (!['default', 'none'].includes(String(item.chrome))) return false;\n\t\tif (item.pinned !== undefined && typeof item.pinned !== 'boolean') return false;\n\t\tif (typeof item.showInDock !== 'boolean' || item.persistence !== 'layout') return false;\n\t}\n\tif (!value.order.every((id) => ids.has(id)) || ids.size !== value.order.length) return false;\n\treturn (\n\t\tvalue.dockOrder === undefined || (value.dockOrder.every((id) => ids.has(id)) && ids.size === value.dockOrder.length)\n\t);\n}\n\nfunction normalizeWorkspace(input: WindowManagerCreateOptions['workspace']): WindowManagerWorkspaceState {\n\tconst workspace = {\n\t\twidth: finitePositive(input?.width, DEFAULT_WORKSPACE.width),\n\t\theight: finitePositive(input?.height, DEFAULT_WORKSPACE.height),\n\t\tdock: { ...DEFAULT_DOCK, ...input?.dock },\n\t};\n\tworkspace.dock = normalizeDock(workspace.dock, workspace);\n\treturn workspace;\n}\n\nfunction normalizeDock(\n\tinput: Partial,\n\tworkspace: Pick,\n): WindowManagerDockState {\n\tconst position: WindowManagerDockState['position'] =\n\t\tinput.position === 'left' || input.position === 'right' ? input.position : 'bottom';\n\tconst maxSize = Math.max(0, (position === 'bottom' ? workspace.height : workspace.width) - 1);\n\treturn {\n\t\tvisible: input.visible ?? true,\n\t\tposition,\n\t\tsize: clamp(finiteNumber(input.size, DEFAULT_DOCK.size), 0, maxSize),\n\t};\n}\n\nfunction normalizeManagedWindow(\n\tinput: Omit, 'capabilities' | 'size'> &\n\t\tPick & {\n\t\t\tcapabilities?: Partial;\n\t\t\tsize?: Partial;\n\t\t},\n\tworkspace: WindowManagerWorkspaceState,\n\tdefaultBounds: Partial,\n\tdefaultCapabilities: WindowManagerCapabilities,\n): ManagedWindow {\n\tconst size = {\n\t\tminWidth: Math.max(1, input.size?.minWidth ?? 240),\n\t\tminHeight: Math.max(1, input.size?.minHeight ?? 160),\n\t\tmaxWidth: input.size?.maxWidth,\n\t\tmaxHeight: input.size?.maxHeight,\n\t};\n\tconst win: ManagedWindow = {\n\t\tid: input.id,\n\t\tkey: input.key,\n\t\tkind: input.kind ?? 'default',\n\t\ttitle: input.title,\n\t\ticon: input.icon,\n\t\tdata: input.data,\n\t\tbounds: { ...DEFAULT_BOUNDS, ...defaultBounds, ...input.bounds },\n\t\tsize,\n\t\tcapabilities: { ...defaultCapabilities, ...input.capabilities },\n\t\tmode: normalizeMode(input.mode),\n\t\trestoreMode: normalizeRestoreMode(input.restoreMode ?? input.mode),\n\t\tfullscreenRestoreMode: input.fullscreenRestoreMode === 'maximized' ? 'maximized' : 'normal',\n\t\tchrome: input.chrome === 'none' ? 'none' : 'default',\n\t\tshowInDock: input.showInDock ?? true,\n\t\tpersistence: input.persistence === 'none' ? 'none' : 'layout',\n\t\tpinned: input.pinned === true,\n\t};\n\twin.bounds = clampWindowManagerBounds(win.bounds, win, workspace);\n\treturn win;\n}\n\nfunction normalizeMode(mode?: WindowManagerWindowMode): WindowManagerWindowMode {\n\treturn mode === 'minimized' || mode === 'maximized' || mode === 'fullscreen' ? mode : 'normal';\n}\n\nfunction normalizeRestoreMode(mode?: WindowManagerWindowMode): WindowManagerRestoreMode {\n\treturn mode === 'maximized' || mode === 'fullscreen' ? mode : 'normal';\n}\n\nfunction findTopVisibleId(state: Pick) {\n\treturn [...state.order].reverse().find((id) => state.windows[id]?.mode !== 'minimized');\n}\n\nfunction restoreOtherFullscreenWindows(\n\tstate: Pick,\n\ttargetId: string,\n): Array<{ id: string; mode: WindowManagerRestoreMode }> {\n\tconst restored: Array<{ id: string; mode: WindowManagerRestoreMode }> = [];\n\tfor (const win of Object.values(state.windows)) {\n\t\tif (win.id === targetId || win.mode !== 'fullscreen') continue;\n\t\twin.mode = win.fullscreenRestoreMode;\n\t\twin.restoreMode = win.mode;\n\t\trestored.push({ id: win.id, mode: win.mode });\n\t}\n\tstate.order = normalizeWindowManagerOrder(state.order, state.windows);\n\treturn restored;\n}\n\nfunction raiseWindowManagerWindow(state: Pick, id: string) {\n\tconst win = state.windows[id];\n\tif (!win) return;\n\tconst rank = windowOrderRank(win);\n\tconst order = normalizeWindowManagerOrder(\n\t\tstate.order.filter((item) => item !== id),\n\t\tstate.windows,\n\t);\n\tconst higherIndex = order.findIndex((item) => windowOrderRank(state.windows[item]) > rank);\n\tif (higherIndex < 0) order.push(id);\n\telse order.splice(higherIndex, 0, id);\n\tstate.order = order;\n}\n\nfunction normalizeWindowManagerOrder(order: readonly string[], windows: Record) {\n\treturn [...order].sort((left, right) => windowOrderRank(windows[left]) - windowOrderRank(windows[right]));\n}\n\nfunction windowOrderRank(win: ManagedWindow | undefined) {\n\tif (win?.mode === 'fullscreen') return 2;\n\treturn win?.pinned ? 1 : 0;\n}\n\nfunction isRecord(value: unknown): value is Record {\n\treturn Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction cloneNullPrototypeRecord(value: Record) {\n\tconst copy = createWindowManagerWindowRecord() as Record;\n\tfor (const key of Reflect.ownKeys(value)) {\n\t\tif (key === WINDOW_MANAGER_WINDOW_RECORD) continue;\n\t\tconst item = value[key];\n\t\tcopy[key] = isManagedWindowRecordValue(item)\n\t\t\t? {\n\t\t\t\t\t...item,\n\t\t\t\t\tbounds: { ...item.bounds },\n\t\t\t\t\tcapabilities: { ...item.capabilities },\n\t\t\t\t\tsize: { ...item.size },\n\t\t\t\t}\n\t\t\t: item;\n\t}\n\treturn copy;\n}\n\nfunction createWindowManagerWindowRecord() {\n\tconst value = Object.create(null) as Record & { [WINDOW_MANAGER_WINDOW_RECORD]?: true };\n\tObject.defineProperty(value, WINDOW_MANAGER_WINDOW_RECORD, { value: true });\n\treturn value;\n}\n\nfunction isWindowManagerWindowRecord(\n\tvalue: unknown,\n): value is Record & { [WINDOW_MANAGER_WINDOW_RECORD]: true } {\n\treturn Boolean(\n\t\tvalue &&\n\t\t\ttypeof value === 'object' &&\n\t\t\tObject.getPrototypeOf(value) === null &&\n\t\t\tReflect.get(value, WINDOW_MANAGER_WINDOW_RECORD) === true,\n\t);\n}\n\nfunction isManagedWindowRecordValue(value: unknown): value is ManagedWindow {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.id === 'string' &&\n\t\ttypeof value.title === 'string' &&\n\t\tisRecord(value.bounds) &&\n\t\tisRecord(value.capabilities) &&\n\t\tisRecord(value.size)\n\t);\n}\n\nfunction isBounds(value: unknown): value is WindowManagerBounds {\n\treturn (\n\t\tisRecord(value) &&\n\t\tisFiniteNumber(value.x) &&\n\t\tisFiniteNumber(value.y) &&\n\t\tisFinitePositive(value.width) &&\n\t\tisFinitePositive(value.height)\n\t);\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n\treturn typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction isFiniteNonNegative(value: unknown): value is number {\n\treturn isFiniteNumber(value) && value >= 0;\n}\n\nfunction isFinitePositive(value: unknown): value is number {\n\treturn isFiniteNumber(value) && value > 0;\n}\n\nfunction finitePositive(value: number | undefined, fallback: number) {\n\treturn typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nfunction finiteNumber(value: number | undefined, fallback: number) {\n\treturn typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n}\n\nfunction clamp(value: number, min: number, max: number) {\n\treturn Math.min(Math.max(value, min), Math.max(min, max));\n}\n", "type": "registry:lib", "target": "@components/window-manager/window-manager-store.ts" }, { "path": "registry/default/blocks/window-manager/window-manager-context.tsx", "content": "'use client';\n\nimport { createContext, type PropsWithChildren, useContext, useState } from 'react';\nimport { useStore } from 'zustand';\nimport { createWindowManagerStore, type WindowManagerStore } from './window-manager-store';\nimport type {\n\tManagedWindow,\n\tWindowManagerActions,\n\tWindowManagerCreateOptions,\n\tWindowManagerState,\n} from './window-manager-types';\n\nexport const WindowManagerContext = createContext(null);\n\nexport type WindowManagerProviderProps = PropsWithChildren<{\n\toptions?: WindowManagerCreateOptions;\n\tstore?: WindowManagerStore;\n}>;\n\nexport function WindowManagerProvider({ children, options, store }: WindowManagerProviderProps) {\n\tconst [localStore] = useState(() => store ?? createWindowManagerStore(options));\n\treturn {children};\n}\n\nexport function useWindowManagerApi() {\n\tconst store = useContext(WindowManagerContext);\n\tif (!store) throw new Error('useWindowManagerApi must be used within WindowManagerProvider');\n\treturn store;\n}\n\nexport function useWindowManager(selector: (state: WindowManagerState) => T): T {\n\treturn useStore(useWindowManagerApi(), selector);\n}\n\nexport function useWindowManagerActions(): WindowManagerActions {\n\treturn useWindowManager((state) => state.actions);\n}\n\nexport function useManagedWindow(id: string): ManagedWindow | undefined {\n\treturn useWindowManager((state) => state.windows[id]);\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager-context.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager-chrome.tsx", "content": "'use client';\n\nimport { Menu as BaseMenu } from '@base-ui/react/menu';\nimport { Ellipsis, Expand, Maximize2, Minimize2, Minus, Pin, PinOff, Shrink, X } from 'lucide-react';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\nimport { cn } from '@/lib/utils';\nimport type { WindowManagerWindowMode } from './window-manager-types';\n\nexport const WINDOW_MANAGER_DRAG_HANDLE_CLASS = 'window-manager-drag-handle';\n\nexport type WindowManagerFrameProps = ComponentPropsWithRef<'section'> & {\n\tactive?: boolean;\n\tmode?: WindowManagerWindowMode;\n};\n\nexport function WindowManagerFrame({ active, mode = 'normal', className, ...props }: WindowManagerFrameProps) {\n\treturn (\n\t\t\n\t);\n}\n\nexport type WindowManagerTitleBarProps = Omit, 'title'> & {\n\tactions?: ReactNode;\n\tcontrols?: ReactNode;\n\ticon?: ReactNode;\n\tsubtitle?: ReactNode;\n\ttitle?: ReactNode;\n};\n\nexport function WindowManagerTitleBar({\n\tactions,\n\tchildren,\n\tclassName,\n\tcontrols,\n\ticon,\n\tsubtitle,\n\ttitle,\n\t...props\n}: WindowManagerTitleBarProps) {\n\treturn (\n\t\t\n\t\t\t{icon ? {icon} : null}\n\t\t\t
\n\t\t\t\t{title ?
{title}
: null}\n\t\t\t\t{subtitle ?
{subtitle}
: null}\n\t\t\t
\n\t\t\t{children}\n\t\t\t{actions ? (\n\t\t\t\t
\n\t\t\t\t\t{actions}\n\t\t\t\t
\n\t\t\t) : null}\n\t\t\t{controls}\n\t\t\n\t);\n}\n\nexport type WindowManagerControlsProps = ComponentPropsWithRef<'div'> & {\n\tcanClose?: boolean;\n\tcanFullscreen?: boolean;\n\tcanMaximize?: boolean;\n\tcanMinimize?: boolean;\n\tmode?: WindowManagerWindowMode;\n\tmenu?: ReactNode;\n\tonClose?: () => void;\n\tonFullscreen?: () => void;\n\tonMaximize?: () => void;\n\tonMinimize?: () => void;\n};\n\nexport function WindowManagerControls({\n\tcanClose = true,\n\tcanFullscreen = true,\n\tcanMaximize = true,\n\tcanMinimize = true,\n\tclassName,\n\tmenu,\n\tmode = 'normal',\n\tonClose,\n\tonFullscreen,\n\tonMaximize,\n\tonMinimize,\n\t...props\n}: WindowManagerControlsProps) {\n\treturn (\n\t\t
\n\t\t\t{menu}\n\t\t\t}\n\t\t\t/>\n\t\t\t : }\n\t\t\t/>\n\t\t\t : }\n\t\t\t/>\n\t\t\t}\n\t\t\t\tclassName='hover:bg-error hover:text-error-content'\n\t\t\t/>\n\t\t
\n\t);\n}\n\nexport type WindowManagerMenuProps = {\n\tchildren?: ReactNode;\n\tonPinnedChange: (pinned: boolean) => void;\n\tpinned?: boolean;\n\tzIndex?: number;\n};\n\nexport function WindowManagerMenu({\n\tchildren,\n\tonPinnedChange,\n\tpinned = false,\n\tzIndex = 11_000,\n}: WindowManagerMenuProps) {\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t onPinnedChange(!pinned)}>\n\t\t\t\t\t\t\t{pinned ? : }\n\t\t\t\t\t\t\t{pinned ? '取消置顶' : '窗口置顶'}\n\t\t\t\t\t\t\n\t\t\t\t\t\t{children ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n\nexport type WindowManagerMenuItemProps = ComponentPropsWithRef;\n\nexport function WindowManagerMenuItem({ className, ...props }: WindowManagerMenuItemProps) {\n\treturn (\n\t\t\n\t);\n}\n\nexport type WindowManagerMenuSeparatorProps = ComponentPropsWithRef;\n\nexport function WindowManagerMenuSeparator({ className, ...props }: WindowManagerMenuSeparatorProps) {\n\treturn ;\n}\n\nexport type WindowManagerToolbarProps = ComponentPropsWithRef<'div'>;\n\nexport function WindowManagerToolbar({ className, ...props }: WindowManagerToolbarProps) {\n\treturn (\n\t\t\n\t);\n}\n\nexport type WindowManagerContentProps = ComponentPropsWithRef<'div'>;\n\nexport function WindowManagerContent({ className, ...props }: WindowManagerContentProps) {\n\treturn
;\n}\n\nexport type WindowManagerStatusBarProps = ComponentPropsWithRef<'footer'>;\n\nexport function WindowManagerStatusBar({ className, ...props }: WindowManagerStatusBarProps) {\n\treturn (\n\t\t\n\t);\n}\n\nfunction WindowControl({\n\tclassName,\n\tdisabled,\n\ticon,\n\tlabel,\n\tonClick,\n}: {\n\tclassName?: string;\n\tdisabled?: boolean;\n\ticon: ReactNode;\n\tlabel: string;\n\tonClick?: () => void;\n}) {\n\treturn (\n\t\t\n\t\t\t{icon}\n\t\t\n\t);\n}\n\nconst windowControlClassName = cn(\n\t'hover:bg-base-300/80 grid size-8 place-items-center disabled:pointer-events-none disabled:opacity-35',\n\t'focus-visible:ring-primary focus-visible:z-10 focus-visible:ring-2 focus-visible:outline-none',\n);\n", "type": "registry:component", "target": "@components/window-manager/window-manager-chrome.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager-dock.tsx", "content": "'use client';\n\nimport { Menu as BaseMenu } from '@base-ui/react/menu';\nimport {\n\tAppWindow,\n\tFocus,\n\tLockKeyhole,\n\tLogIn,\n\tLogOut,\n\tMinus,\n\tPanelsTopLeft,\n\tUserRound,\n\tUserRoundCog,\n\tX,\n} from 'lucide-react';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\nimport { useShallow } from 'zustand/react/shallow';\nimport { cn } from '@/lib/utils';\nimport { WindowManagerMenuItem, WindowManagerMenuSeparator } from './window-manager-chrome';\nimport { useWindowManager } from './window-manager-context';\nimport type { ManagedWindow, WindowManagerActions, WindowManagerDockPosition } from './window-manager-types';\n\nexport const WINDOW_MANAGER_DOCK_Z_INDEX = 9_000;\n\nexport type WindowManagerDockItemRenderContext = {\n\tactive: boolean;\n\ticon: ReactNode;\n\tminimized: boolean;\n\twin: ManagedWindow;\n};\n\nexport type WindowManagerDockUser = {\n\tavatarUrl?: string;\n\tdisplayName?: string;\n\thasNotification?: boolean;\n\tinitials?: string;\n\tloginName?: string;\n\tonLock?: () => void;\n\tonOpenProfile?: () => void;\n\tonSignIn?: () => void;\n\tonSignOut?: () => void;\n};\n\nexport type WindowManagerDockUserMenuRenderContext = {\n\tuser: WindowManagerDockUser;\n};\n\nexport type WindowManagerDockProps = ComponentPropsWithRef<'nav'> & {\n\tmenuZIndex?: number;\n\tminimizeActiveOnClick?: boolean;\n\trenderIcon?: (win: ManagedWindow) => ReactNode;\n\trenderItem?: (context: WindowManagerDockItemRenderContext) => ReactNode;\n\trenderUserMenuItems?: (context: WindowManagerDockUserMenuRenderContext) => ReactNode;\n\tshowActions?: boolean;\n\tuser?: WindowManagerDockUser;\n};\n\nexport function WindowManagerDock({\n\tclassName,\n\tmenuZIndex = WINDOW_MANAGER_DOCK_Z_INDEX + 1,\n\tminimizeActiveOnClick = true,\n\trenderIcon = defaultWindowIcon,\n\trenderItem,\n\trenderUserMenuItems,\n\tshowActions = true,\n\tstyle,\n\tuser,\n\t...props\n}: WindowManagerDockProps) {\n\tconst { actions, activeId, dock, dockOrder, fullscreen, windowById } = useWindowManager(\n\t\tuseShallow((state) => ({\n\t\t\tactions: state.actions,\n\t\t\tactiveId: state.activeId,\n\t\t\tdock: state.workspace.dock,\n\t\t\tdockOrder: state.dockOrder,\n\t\t\tfullscreen: state.order.some((id) => state.windows[id]?.mode === 'fullscreen'),\n\t\t\twindowById: state.windows,\n\t\t})),\n\t);\n\tif (!dock.visible || fullscreen) return null;\n\tconst windows = dockOrder.flatMap((id) => {\n\t\tconst win = windowById[id];\n\t\treturn win?.showInDock ? [win] : [];\n\t});\n\tconst managedWindows = Object.values(windowById);\n\tconst vertical = dock.position !== 'bottom';\n\tconst dockStyle = vertical ? { width: dock.size } : { height: dock.size };\n\n\treturn (\n\t\t\n\t\t\t{user ? (\n\t\t\t\t\n\t\t\t) : null}\n\t\t\t{showActions ? (\n\t\t\t\t win.capabilities.close)}\n\t\t\t\t\tcanMinimizeAny={managedWindows.some((win) => win.mode !== 'minimized' && win.capabilities.minimize)}\n\t\t\t\t\tcount={managedWindows.length}\n\t\t\t\t\tposition={dock.position}\n\t\t\t\t\tzIndex={menuZIndex}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t\n\t\t\t\t{windows.map((win) => {\n\t\t\t\t\tconst active = activeId === win.id && win.mode !== 'minimized';\n\t\t\t\t\tconst icon = renderIcon(win);\n\t\t\t\t\tconst context = { active, minimized: win.mode === 'minimized', icon, win };\n\t\t\t\t\treturn (\n\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\tif (win.mode === 'minimized') actions.restore(win.id);\n\t\t\t\t\t\t\t\telse if (active && minimizeActiveOnClick) actions.minimize(win.id);\n\t\t\t\t\t\t\t\telse actions.focus(win.id);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{renderItem ? renderItem(context) : icon}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t\t{windows.length === 0 ?
\n\t\t\n\t);\n}\n\ntype WindowManagerDockUserAvatarProps = {\n\tmenuItems?: ReactNode;\n\tposition: WindowManagerDockPosition;\n\tuser: WindowManagerDockUser;\n\tzIndex: number;\n};\n\nfunction WindowManagerDockUserAvatar({ menuItems, position, user, zIndex }: WindowManagerDockUserAvatarProps) {\n\tconst { avatarUrl, displayName, hasNotification, loginName, onLock, onOpenProfile, onSignIn, onSignOut } = user;\n\tconst normalizedAvatarUrl = avatarUrl?.trim();\n\tconst normalizedDisplayName = displayName?.trim();\n\tconst normalizedLoginName = loginName?.trim();\n\tconst normalizedInitials = user.initials?.trim();\n\tconst hasIdentity = Boolean(\n\t\tnormalizedAvatarUrl || normalizedDisplayName || normalizedLoginName || normalizedInitials,\n\t);\n\tif (!hasIdentity) {\n\t\tif (!onSignIn) return null;\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t);\n\t}\n\n\tconst side = getWindowManagerDockMenuSide(position);\n\tconst initials = resolveUserInitials(user);\n\tconst label = normalizedDisplayName || normalizedLoginName || '账户';\n\tconst hasPrimaryActions = Boolean(onOpenProfile || onLock || menuItems);\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t{initials || }\n\t\t\t\t\t{normalizedAvatarUrl ? (\n\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\tevent.currentTarget.hidden = true;\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t\n\t\t\t\t{hasNotification ? (\n\t\t\t\t\t\n\t\t\t\t) : null}\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
{label}
\n\t\t\t\t\t\t\t{normalizedLoginName ? (\n\t\t\t\t\t\t\t\t
@{normalizedLoginName}
\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{hasPrimaryActions || onSignOut ? : null}\n\t\t\t\t\t\t{hasPrimaryActions ? (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{onOpenProfile ? (\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t个人资料\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{onLock ? (\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t锁定\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{menuItems}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{onSignOut ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{hasPrimaryActions ? : null}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t退出登录\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t);\n}\n\ntype WindowManagerDockMenuProps = {\n\tactions: WindowManagerActions;\n\tactive?: ManagedWindow;\n\tcanCloseAny: boolean;\n\tcanMinimizeAny: boolean;\n\tcount: number;\n\tposition: WindowManagerDockPosition;\n\tzIndex: number;\n};\n\nfunction WindowManagerDockMenu({\n\tactions,\n\tactive,\n\tcanCloseAny,\n\tcanMinimizeAny,\n\tcount,\n\tposition,\n\tzIndex,\n}: WindowManagerDockMenuProps) {\n\tconst side = getWindowManagerDockMenuSide(position);\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t当前窗口\n\t\t\t\t\t\t\t active && actions.center(active.id)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t窗口居中\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t active && actions.close(active.id)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t关闭当前窗口\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t窗口管理 ({count})\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t最小化所有窗口\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t关闭所有窗口\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n}\n\nfunction getWindowManagerDockMenuSide(position: WindowManagerDockPosition) {\n\treturn position === 'right' ? 'left' : position === 'left' ? 'right' : 'top';\n}\n\nfunction resolveUserInitials(user: WindowManagerDockUser) {\n\tconst value = user.initials?.trim() || user.displayName?.trim() || user.loginName?.trim() || '';\n\tconst graphemes =\n\t\ttypeof Intl.Segmenter === 'function'\n\t\t\t? Array.from(new Intl.Segmenter(undefined, { granularity: 'grapheme' }).segment(value), ({ segment }) => segment)\n\t\t\t: Array.from(value);\n\treturn graphemes.slice(0, 2).join('').toUpperCase();\n}\n\nfunction defaultWindowIcon(win: ManagedWindow) {\n\treturn win.icon ? (\n\t\t{win.icon}\n\t) : (\n\t\t{win.title.trim().slice(0, 1).toUpperCase() || 'W'}\n\t);\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager-dock.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager-motion.tsx", "content": "'use client';\n\nimport { Resizable, type ResizeDirection } from 're-resizable';\nimport {\n\ttype CSSProperties,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\nexport type WindowManagerMotionBounds = {\n\theight: number;\n\twidth: number;\n\tx: number;\n\ty: number;\n};\n\nexport type WindowManagerMotionSurfaceProps = {\n\tcancel?: string;\n\tchildren: ReactNode;\n\tdisableDragging?: boolean;\n\tdragHandleClassName?: string;\n\tenableResizing?: boolean;\n\tinteractionKey?: string | number;\n\tmaxHeight: number;\n\tmaxWidth: number;\n\tminHeight: number;\n\tminWidth: number;\n\tmovementBounds: WindowManagerMotionBounds;\n\tonMoveStart?: () => void;\n\tonMoveStop?: (position: { x: number; y: number }) => void;\n\tonResizeStart?: () => void;\n\tonResizeStop?: (value: WindowManagerMotionBounds) => void;\n\tposition: { x: number; y: number };\n\tsize: { height: number; width: number };\n\tstyle?: CSSProperties;\n};\n\ntype DragSession = {\n\tmaxX: number;\n\tmaxY: number;\n\tminX: number;\n\tminY: number;\n\toriginX: number;\n\toriginY: number;\n\tpointerId: number;\n\tstartX: number;\n\tstartY: number;\n};\n\nexport function WindowManagerMotionSurface({\n\tcancel,\n\tchildren,\n\tdisableDragging = false,\n\tdragHandleClassName,\n\tenableResizing = true,\n\tinteractionKey = 'default',\n\tmaxHeight,\n\tmaxWidth,\n\tminHeight,\n\tminWidth,\n\tmovementBounds,\n\tonMoveStart,\n\tonMoveStop,\n\tonResizeStart,\n\tonResizeStop,\n\tposition,\n\tsize,\n\tstyle,\n}: WindowManagerMotionSurfaceProps) {\n\tconst nodeRef = useRef(null);\n\tconst activity = useRef<'drag' | 'resize' | undefined>(undefined);\n\tconst dragSession = useRef(undefined);\n\tconst latestPosition = useRef(position);\n\tconst previousInteractionKey = useRef(interactionKey);\n\tconst resizeOrigin = useRef({ ...position, ...size });\n\tconst [visualPosition, setVisualPosition] = useState(position);\n\tconst [visualSize, setVisualSize] = useState(size);\n\n\tuseEffect(() => {\n\t\tif (previousInteractionKey.current === interactionKey) return;\n\t\tpreviousInteractionKey.current = interactionKey;\n\t\tconst pointerId = dragSession.current?.pointerId;\n\t\tdragSession.current = undefined;\n\t\tactivity.current = undefined;\n\t\tif (pointerId !== undefined && nodeRef.current?.hasPointerCapture(pointerId)) {\n\t\t\tnodeRef.current.releasePointerCapture(pointerId);\n\t\t}\n\t\tlatestPosition.current = position;\n\t\tsetVisualPosition(position);\n\t\tsetVisualSize(size);\n\t}, [interactionKey, position, size]);\n\tuseEffect(() => {\n\t\tif (activity.current) return;\n\t\tlatestPosition.current = position;\n\t\tsetVisualPosition(position);\n\t}, [position]);\n\tuseEffect(() => {\n\t\tif (!activity.current) setVisualSize(size);\n\t}, [size]);\n\n\tconst startDrag = (event: ReactPointerEvent) => {\n\t\tif (disableDragging || event.button !== 0 || !nodeRef.current) return;\n\t\tconst target = event.target instanceof Element ? event.target : undefined;\n\t\tif (!target) return;\n\t\tif (dragHandleClassName && !target.closest(`.${dragHandleClassName}`)) return;\n\t\tif (cancel && target.closest(cancel)) return;\n\t\tevent.preventDefault();\n\t\tnodeRef.current.setPointerCapture(event.pointerId);\n\t\tdragSession.current = {\n\t\t\tpointerId: event.pointerId,\n\t\t\tstartX: event.clientX,\n\t\t\tstartY: event.clientY,\n\t\t\toriginX: visualPosition.x,\n\t\t\toriginY: visualPosition.y,\n\t\t\tminX: movementBounds.x,\n\t\t\tminY: movementBounds.y,\n\t\t\tmaxX: Math.max(movementBounds.x, movementBounds.x + movementBounds.width - visualSize.width),\n\t\t\tmaxY: Math.max(movementBounds.y, movementBounds.y + movementBounds.height - visualSize.height),\n\t\t};\n\t\tactivity.current = 'drag';\n\t\tonMoveStart?.();\n\t};\n\n\tconst moveDrag = (event: ReactPointerEvent) => {\n\t\tconst session = dragSession.current;\n\t\tif (!session || session.pointerId !== event.pointerId) return;\n\t\tconst next = getWindowManagerDragPosition(session, { x: event.clientX, y: event.clientY });\n\t\tlatestPosition.current = next;\n\t\tsetVisualPosition(next);\n\t};\n\n\tconst stopDrag = (event: ReactPointerEvent) => {\n\t\tconst session = dragSession.current;\n\t\tif (!session || session.pointerId !== event.pointerId) return;\n\t\tdragSession.current = undefined;\n\t\tactivity.current = undefined;\n\t\tif (nodeRef.current?.hasPointerCapture(event.pointerId)) nodeRef.current.releasePointerCapture(event.pointerId);\n\t\tonMoveStop?.(latestPosition.current);\n\t};\n\n\tconst constrainResize = (direction: ResizeDirection, requested: { height: number; width: number }) =>\n\t\tgetWindowManagerConstrainedResize({\n\t\t\tbounds: movementBounds,\n\t\t\tdirection,\n\t\t\tmaxHeight,\n\t\t\tmaxWidth,\n\t\t\tminHeight,\n\t\t\tminWidth,\n\t\t\torigin: resizeOrigin.current,\n\t\t\trequested,\n\t\t});\n\n\treturn (\n\t\t\n\t\t\t {\n\t\t\t\t\tactivity.current = 'resize';\n\t\t\t\t\tresizeOrigin.current = { ...visualPosition, ...visualSize };\n\t\t\t\t\tonResizeStart?.();\n\t\t\t\t}}\n\t\t\t\tonResize={(_event, direction, element) => {\n\t\t\t\t\tif (activity.current !== 'resize') return;\n\t\t\t\t\tconst next = constrainResize(direction, { width: element.offsetWidth, height: element.offsetHeight });\n\t\t\t\t\tlatestPosition.current = next;\n\t\t\t\t\tsetVisualPosition({ x: next.x, y: next.y });\n\t\t\t\t\tsetVisualSize({ width: next.width, height: next.height });\n\t\t\t\t}}\n\t\t\t\tonResizeStop={(_event, direction, element) => {\n\t\t\t\t\tif (activity.current !== 'resize') return;\n\t\t\t\t\tactivity.current = undefined;\n\t\t\t\t\tconst next = constrainResize(direction, { width: element.offsetWidth, height: element.offsetHeight });\n\t\t\t\t\tlatestPosition.current = next;\n\t\t\t\t\tsetVisualPosition({ x: next.x, y: next.y });\n\t\t\t\t\tsetVisualSize({ width: next.width, height: next.height });\n\t\t\t\t\tonResizeStop?.(next);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\n\t\t\n\t);\n}\n\nexport function getWindowManagerDragPosition(\n\tsession: Pick,\n\tpointer: { x: number; y: number },\n) {\n\treturn {\n\t\tx: clamp(session.originX + pointer.x - session.startX, session.minX, session.maxX),\n\t\ty: clamp(session.originY + pointer.y - session.startY, session.minY, session.maxY),\n\t};\n}\n\nexport function getWindowManagerConstrainedResize({\n\tbounds,\n\tdirection,\n\tmaxHeight,\n\tmaxWidth,\n\tminHeight,\n\tminWidth,\n\torigin,\n\trequested,\n}: {\n\tbounds: WindowManagerMotionBounds;\n\tdirection: ResizeDirection;\n\tmaxHeight: number;\n\tmaxWidth: number;\n\tminHeight: number;\n\tminWidth: number;\n\torigin: WindowManagerMotionBounds;\n\trequested: { height: number; width: number };\n}): WindowManagerMotionBounds {\n\tconst value = direction.toLowerCase();\n\tconst fromLeft = value.includes('left');\n\tconst fromTop = value.includes('top');\n\tconst horizontal = fromLeft || value.includes('right');\n\tconst vertical = fromTop || value.includes('bottom');\n\tconst fixedRight = origin.x + origin.width;\n\tconst fixedBottom = origin.y + origin.height;\n\tconst availableWidth = fromLeft ? fixedRight - bounds.x : bounds.x + bounds.width - origin.x;\n\tconst availableHeight = fromTop ? fixedBottom - bounds.y : bounds.y + bounds.height - origin.y;\n\tconst width = clamp(\n\t\thorizontal ? requested.width : origin.width,\n\t\tMath.min(minWidth, availableWidth),\n\t\tMath.min(maxWidth, availableWidth),\n\t);\n\tconst height = clamp(\n\t\tvertical ? requested.height : origin.height,\n\t\tMath.min(minHeight, availableHeight),\n\t\tMath.min(maxHeight, availableHeight),\n\t);\n\treturn {\n\t\tx: fromLeft ? fixedRight - width : origin.x,\n\t\ty: fromTop ? fixedBottom - height : origin.y,\n\t\twidth,\n\t\theight,\n\t};\n}\n\nexport function getWindowManagerResizePosition(\n\torigin: { x: number; y: number },\n\tdirection: ResizeDirection,\n\tdelta: { height: number; width: number },\n) {\n\treturn {\n\t\tx: origin.x - (direction.toLowerCase().includes('left') ? delta.width : 0),\n\t\ty: origin.y - (direction.toLowerCase().includes('top') ? delta.height : 0),\n\t};\n}\n\nfunction clamp(value: number, min: number, max: number) {\n\treturn Math.min(Math.max(value, min), Math.max(min, max));\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager-motion.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager-host.tsx", "content": "'use client';\n\nimport {\n\ttype ComponentPropsWithRef,\n\ttype KeyboardEvent as ReactKeyboardEvent,\n\ttype ReactNode,\n\ttype Ref,\n\tuseEffect,\n\tuseId,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useShallow } from 'zustand/react/shallow';\nimport { cn } from '@/lib/utils';\nimport {\n\tWINDOW_MANAGER_DRAG_HANDLE_CLASS,\n\tWindowManagerContent,\n\tWindowManagerControls,\n\tWindowManagerFrame,\n\tWindowManagerMenu,\n\tWindowManagerStatusBar,\n\tWindowManagerTitleBar,\n\tWindowManagerToolbar,\n} from './window-manager-chrome';\nimport { useWindowManager } from './window-manager-context';\nimport { WINDOW_MANAGER_DOCK_Z_INDEX, WindowManagerDock, type WindowManagerDockProps } from './window-manager-dock';\nimport { WindowManagerMotionSurface } from './window-manager-motion';\nimport { getWindowManagerAvailableBounds, getWindowManagerRenderBounds } from './window-manager-store';\nimport type { ManagedWindow, WindowManagerActions, WindowManagerWorkspaceState } from './window-manager-types';\n\nexport type WindowManagerFrameRenderContext = {\n\tactions: Pick<\n\t\tWindowManagerActions,\n\t\t| 'close'\n\t\t| 'focus'\n\t\t| 'fullscreen'\n\t\t| 'maximize'\n\t\t| 'minimize'\n\t\t| 'restore'\n\t\t| 'setPinned'\n\t\t| 'toggleFullscreen'\n\t\t| 'toggleMaximize'\n\t\t| 'togglePinned'\n\t>;\n\tactive: boolean;\n\tcontent: ReactNode;\n\tdragCancelProps: { 'data-window-drag-cancel': true };\n\tdragHandleProps: { className: string; 'data-window-drag-handle': true };\n\ticon?: ReactNode;\n\tmenuItems?: ReactNode;\n\toverlayZIndex: number;\n\tstatusBar?: ReactNode;\n\ttitleId: string;\n\ttoolbar?: ReactNode;\n\twin: ManagedWindow;\n};\n\nexport type WindowManagerMenuRenderContext = {\n\tactions: WindowManagerActions;\n\twin: ManagedWindow;\n};\n\nexport type WindowManagerHostProps = ComponentPropsWithRef<'div'> & {\n\tautoFocus?: boolean;\n\tbackground?: ReactNode;\n\tdock?: boolean | ReactNode;\n\tdockProps?: WindowManagerDockProps;\n\tkeyboard?: boolean;\n\trenderContent?: (win: ManagedWindow) => ReactNode;\n\trenderFrame?: (context: WindowManagerFrameRenderContext) => ReactNode;\n\trenderIcon?: (win: ManagedWindow) => ReactNode;\n\trenderMenuItems?: (context: WindowManagerMenuRenderContext) => ReactNode;\n\trenderStatusBar?: (win: ManagedWindow) => ReactNode;\n\trenderToolbar?: (win: ManagedWindow) => ReactNode;\n\tunmountContentOnMinimize?: boolean;\n\tzIndexBase?: number;\n};\n\nexport function WindowManagerHost({\n\tautoFocus = true,\n\tbackground,\n\tchildren,\n\tclassName,\n\tdock = true,\n\tdockProps,\n\tkeyboard = true,\n\tonKeyDownCapture,\n\tref,\n\trenderContent = defaultContent,\n\trenderFrame = defaultFrame,\n\trenderIcon,\n\trenderMenuItems,\n\trenderStatusBar,\n\trenderToolbar,\n\tunmountContentOnMinimize = false,\n\tzIndexBase = 20,\n\t...props\n}: WindowManagerHostProps) {\n\tconst rootRef = useRef(null);\n\tconst { actions, activeId, order, windows, workspace } = useWindowManager(\n\t\tuseShallow((state) => ({\n\t\t\tactions: state.actions,\n\t\t\tactiveId: state.activeId,\n\t\t\torder: state.order,\n\t\t\twindows: state.windows,\n\t\t\tworkspace: state.workspace,\n\t\t})),\n\t);\n\n\tuseEffect(() => {\n\t\tif (typeof dock === 'boolean' && workspace.dock.visible !== dock) actions.setDock({ visible: dock });\n\t}, [actions, dock, workspace.dock.visible]);\n\n\tuseEffect(() => {\n\t\tconst element = rootRef.current;\n\t\tif (!element) return;\n\t\tconst update = () => {\n\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\tif (rect.width > 0 && rect.height > 0) actions.setWorkspaceSize({ width: rect.width, height: rect.height });\n\t\t};\n\t\tupdate();\n\t\tif (typeof ResizeObserver !== 'undefined') {\n\t\t\tconst observer = new ResizeObserver(update);\n\t\t\tobserver.observe(element);\n\t\t\treturn () => observer.disconnect();\n\t\t}\n\t\twindow.addEventListener('resize', update);\n\t\treturn () => window.removeEventListener('resize', update);\n\t}, [actions]);\n\n\tconst handleKeyboard = (event: ReactKeyboardEvent) => {\n\t\tif (!keyboard) return;\n\t\tconst active = activeId ? windows[activeId] : undefined;\n\t\tif (event.ctrlKey && event.key === 'F6') {\n\t\t\tevent.preventDefault();\n\t\t\tactions.cycleFocus(event.shiftKey ? -1 : 1);\n\t\t\treturn;\n\t\t}\n\t\tif (event.altKey && event.key === 'F9' && active) {\n\t\t\tevent.preventDefault();\n\t\t\tactions.minimize(active.id);\n\t\t\treturn;\n\t\t}\n\t\tif (event.altKey && event.key === 'F10' && active) {\n\t\t\tevent.preventDefault();\n\t\t\tactions.toggleMaximize(active.id);\n\t\t\treturn;\n\t\t}\n\t\tif (event.key === 'Escape' && active?.mode === 'fullscreen') {\n\t\t\tevent.preventDefault();\n\t\t\tactions.restore(active.id);\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\t!active ||\n\t\t\t!event.ctrlKey ||\n\t\t\t!event.altKey ||\n\t\t\t!event.key.startsWith('Arrow') ||\n\t\t\tisEditableTarget(event.target)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tconst step = event.shiftKey ? 24 : 10;\n\t\tconst horizontal = event.key === 'ArrowLeft' ? -step : event.key === 'ArrowRight' ? step : 0;\n\t\tconst vertical = event.key === 'ArrowUp' ? -step : event.key === 'ArrowDown' ? step : 0;\n\t\tif (event.shiftKey) actions.resizeBy(active.id, { width: horizontal, height: vertical });\n\t\telse actions.moveBy(active.id, { x: horizontal, y: vertical });\n\t};\n\n\tconst hostWorkspace =\n\t\tdock === false && workspace.dock.visible\n\t\t\t? { ...workspace, dock: { ...workspace.dock, visible: false } }\n\t\t\t: workspace;\n\n\treturn (\n\t\t {\n\t\t\t\trootRef.current = element;\n\t\t\t\tassignRef(ref, element);\n\t\t\t}}\n\t\t\tdata-window-manager-host\n\t\t\tclassName={cn('bg-base-200 relative isolate h-full min-h-80 w-full overflow-hidden', className)}\n\t\t\tonKeyDownCapture={(event) => {\n\t\t\t\tonKeyDownCapture?.(event);\n\t\t\t\tif (!event.defaultPrevented) handleKeyboard(event);\n\t\t\t}}\n\t\t>\n\t\t\t{background}\n\t\t\t{children}\n\t\t\t{order.map((id, index) => {\n\t\t\t\tconst win = windows[id];\n\t\t\t\tif (!win) return null;\n\t\t\t\treturn (\n\t\t\t\t\t\n\t\t\t\t);\n\t\t\t})}\n\t\t\t{dock === true ? (\n\t\t\t\t\n\t\t\t) : (\n\t\t\t\tdock || null\n\t\t\t)}\n\t\t\n\t);\n}\n\nexport type WindowManagerPortalHostProps = Omit & {\n\tcontainer?: Element | (() => Element | null) | null;\n};\n\nexport function WindowManagerPortalHost({ container, className, ...props }: WindowManagerPortalHostProps) {\n\tconst [target, setTarget] = useState(null);\n\tuseEffect(() => {\n\t\tsetTarget(typeof container === 'function' ? container() : (container ?? document.body));\n\t}, [container]);\n\tif (!target) return null;\n\treturn createPortal(, target);\n}\n\ntype ManagedWindowSurfaceProps = {\n\tactions: WindowManagerActions;\n\tactive: boolean;\n\tautoFocus: boolean;\n\tindex: number;\n\toverlayZIndex: number;\n\trenderContent: NonNullable;\n\trenderFrame: NonNullable;\n\trenderIcon?: WindowManagerHostProps['renderIcon'];\n\trenderMenuItems?: WindowManagerHostProps['renderMenuItems'];\n\trenderStatusBar?: WindowManagerHostProps['renderStatusBar'];\n\trenderToolbar?: WindowManagerHostProps['renderToolbar'];\n\tunmountContentOnMinimize: boolean;\n\twin: ManagedWindow;\n\tworkspace: WindowManagerWorkspaceState;\n\tzIndexBase: number;\n};\n\nfunction ManagedWindowSurface({\n\tactions,\n\tactive,\n\tautoFocus,\n\tindex,\n\toverlayZIndex,\n\trenderContent,\n\trenderFrame,\n\trenderIcon,\n\trenderMenuItems,\n\trenderStatusBar,\n\trenderToolbar,\n\tunmountContentOnMinimize,\n\twin,\n\tworkspace,\n\tzIndexBase,\n}: ManagedWindowSurfaceProps) {\n\tconst surfaceRef = useRef(null);\n\tconst titleId = useId();\n\tconst minimized = win.mode === 'minimized';\n\tconst bounds = getWindowManagerRenderBounds(win, workspace);\n\tconst area = getWindowManagerAvailableBounds(workspace);\n\tconst motionArea =\n\t\twin.mode === 'fullscreen' ? { x: 0, y: 0, width: workspace.width, height: workspace.height } : area;\n\tconst movable = win.mode === 'normal' && win.capabilities.move;\n\tconst resizable = win.mode === 'normal' && win.capabilities.resize;\n\tconst content = minimized && unmountContentOnMinimize ? null : renderContent(win);\n\tconst frame = renderFrame({\n\t\twin,\n\t\tactive,\n\t\tcontent,\n\t\tdragCancelProps: { 'data-window-drag-cancel': true },\n\t\tdragHandleProps: {\n\t\t\tclassName: WINDOW_MANAGER_DRAG_HANDLE_CLASS,\n\t\t\t'data-window-drag-handle': true,\n\t\t},\n\t\ticon: renderIcon?.(win),\n\t\tmenuItems: renderMenuItems?.({ actions, win }),\n\t\toverlayZIndex,\n\t\ttoolbar: renderToolbar?.(win),\n\t\tstatusBar: renderStatusBar?.(win),\n\t\ttitleId,\n\t\tactions,\n\t});\n\n\tuseEffect(() => {\n\t\tif (!autoFocus || !active || minimized || !surfaceRef.current) return;\n\t\tif (!surfaceRef.current.contains(document.activeElement)) surfaceRef.current.focus({ preventScroll: true });\n\t}, [active, autoFocus, minimized]);\n\n\treturn (\n\t\t {\n\t\t\t\tactions.focus(win.id);\n\t\t\t}}\n\t\t\tonMoveStop={(position) => {\n\t\t\t\tactions.setBounds(win.id, position, 'move');\n\t\t\t}}\n\t\t\tonResizeStart={() => {\n\t\t\t\tactions.focus(win.id);\n\t\t\t}}\n\t\t\tonResizeStop={(next) => {\n\t\t\t\tactions.setBounds(win.id, next, 'resize');\n\t\t\t}}\n\t\t>\n\t\t\t {\n\t\t\t\t\tif (!active) actions.focus(win.id);\n\t\t\t\t}}\n\t\t\t\tonMouseDownCapture={() => {\n\t\t\t\t\tif (!active) actions.focus(win.id);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{frame}\n\t\t\t\n\t\t\n\t);\n}\n\nfunction defaultFrame({\n\tactions,\n\tactive,\n\tcontent,\n\ticon,\n\tmenuItems,\n\toverlayZIndex,\n\tstatusBar,\n\ttitleId,\n\ttoolbar,\n\twin,\n}: WindowManagerFrameRenderContext) {\n\tif (win.chrome === 'none') {\n\t\treturn (\n\t\t\t
\n\t\t\t\t{content}\n\t\t\t
\n\t\t);\n\t}\n\treturn (\n\t\t\n\t\t\t {\n\t\t\t\t\tif (!win.capabilities.maximize || win.mode === 'fullscreen') return;\n\t\t\t\t\tif (event.target instanceof Element && event.target.closest('[data-window-drag-cancel]')) return;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tactions.toggleMaximize(win.id);\n\t\t\t\t}}\n\t\t\t\tcontrols={\n\t\t\t\t\t actions.setPinned(win.id, pinned)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{menuItems}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmode={win.mode}\n\t\t\t\t\t\tcanClose={win.capabilities.close}\n\t\t\t\t\t\tcanFullscreen={win.capabilities.fullscreen}\n\t\t\t\t\t\tcanMaximize={win.capabilities.maximize}\n\t\t\t\t\t\tcanMinimize={win.capabilities.minimize}\n\t\t\t\t\t\tonClose={() => actions.close(win.id)}\n\t\t\t\t\t\tonFullscreen={() => actions.toggleFullscreen(win.id)}\n\t\t\t\t\t\tonMaximize={() => actions.toggleMaximize(win.id)}\n\t\t\t\t\t\tonMinimize={() => actions.minimize(win.id)}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t{toolbar ? {toolbar} : null}\n\t\t\t{content}\n\t\t\t{statusBar ? {statusBar} : null}\n\t\t\n\t);\n}\n\nfunction defaultContent(win: ManagedWindow) {\n\treturn (\n\t\t
\n\t\t\t
\n\t\t\t\t
{win.title}
\n\t\t\t\t
Register a renderer for “{win.kind}”.
\n\t\t\t
\n\t\t
\n\t);\n}\n\nfunction isEditableTarget(target: EventTarget | null) {\n\treturn (\n\t\ttarget instanceof HTMLElement &&\n\t\t(target.isContentEditable ||\n\t\t\ttarget instanceof HTMLInputElement ||\n\t\t\ttarget instanceof HTMLTextAreaElement ||\n\t\t\ttarget instanceof HTMLSelectElement)\n\t);\n}\n\nfunction assignRef(ref: Ref | undefined, value: T | null) {\n\tif (typeof ref === 'function') ref(value);\n\telse if (ref) ref.current = value;\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager-host.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager-persistence.tsx", "content": "'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useWindowManagerApi } from './window-manager-context';\nimport { isWindowManagerSnapshot } from './window-manager-store';\nimport type {\n\tManagedWindow,\n\tWindowManagerSnapshot,\n\tWindowManagerState,\n\tWindowManagerStorage,\n} from './window-manager-types';\nimport { WINDOW_MANAGER_SNAPSHOT_VERSION } from './window-manager-types';\n\nexport type WindowManagerPersistenceProps = {\n\tdebounceMs?: number;\n\tmigrate?: (value: unknown) => WindowManagerSnapshot | undefined;\n\tonError?: (error: Error) => void;\n\trestoreMinimized?: boolean;\n\tserializeData?: (win: ManagedWindow) => unknown;\n\tstorage?: 'local' | 'session' | WindowManagerStorage;\n\tstorageKey?: string;\n};\n\nexport function WindowManagerPersistence({\n\tdebounceMs = 180,\n\tmigrate,\n\tonError,\n\trestoreMinimized = false,\n\tserializeData,\n\tstorage = 'local',\n\tstorageKey = 'window-manager.layout.v1',\n}: WindowManagerPersistenceProps) {\n\tconst store = useWindowManagerApi();\n\tconst optionsRef = useRef({ debounceMs, migrate, onError, restoreMinimized, serializeData });\n\toptionsRef.current = { debounceMs, migrate, onError, restoreMinimized, serializeData };\n\n\tuseEffect(() => {\n\t\tconst target = resolveStorage(storage);\n\t\tif (!target) {\n\t\t\tstore.getState().actions.setHydration({ status: 'ready' });\n\t\t\treturn;\n\t\t}\n\t\tlet timer: ReturnType | undefined;\n\t\tlet disposed = false;\n\t\tlet writesDisabled = false;\n\t\tconst report = (value: unknown) => {\n\t\t\tconst error = value instanceof Error ? value : new Error('Window layout persistence failed');\n\t\t\tstore.getState().actions.setHydration({ status: 'error', error: error.message });\n\t\t\toptionsRef.current.onError?.(error);\n\t\t};\n\n\t\tstore.getState().actions.setHydration({ status: 'hydrating' });\n\t\ttry {\n\t\t\tconst raw = target.getItem(storageKey);\n\t\t\tif (raw) {\n\t\t\t\tconst value: unknown = JSON.parse(raw);\n\t\t\t\tconst snapshot = isWindowManagerSnapshot(value) ? value : optionsRef.current.migrate?.(value);\n\t\t\t\tif (!snapshot || !isWindowManagerSnapshot(snapshot))\n\t\t\t\t\tthrow new Error('Stored window layout has an unsupported shape');\n\t\t\t\tif (\n\t\t\t\t\t!store.getState().actions.hydrateLayout(snapshot, { restoreMinimized: optionsRef.current.restoreMinimized })\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error('Stored window layout could not be restored');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstore.getState().actions.setHydration({ status: 'ready' });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\treport(error);\n\t\t}\n\n\t\tconst save = () => {\n\t\t\tif (disposed || writesDisabled) return;\n\t\t\ttry {\n\t\t\t\ttarget.setItem(\n\t\t\t\t\tstorageKey,\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\tcreateWindowManagerSnapshot(store.getState(), { serializeData: optionsRef.current.serializeData }),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\twritesDisabled = true;\n\t\t\t\treport(error);\n\t\t\t}\n\t\t};\n\t\tconst unsubscribe = store.subscribe(() => {\n\t\t\tif (writesDisabled) return;\n\t\t\tif (timer) clearTimeout(timer);\n\t\t\ttimer = setTimeout(save, Math.max(0, optionsRef.current.debounceMs));\n\t\t});\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tunsubscribe();\n\t\t\tif (timer) clearTimeout(timer);\n\t\t};\n\t}, [storage, storageKey, store]);\n\n\treturn null;\n}\n\nexport function createWindowManagerSnapshot(\n\tstate: WindowManagerState,\n\toptions: { now?: () => number; serializeData?: (win: ManagedWindow) => unknown } = {},\n): WindowManagerSnapshot {\n\tconst windows = state.dockOrder.flatMap((id) => {\n\t\tconst win = state.windows[id];\n\t\tif (!win || win.persistence === 'none') return [];\n\t\tconst data = options.serializeData?.(win);\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: win.id,\n\t\t\t\tkey: win.key,\n\t\t\t\tkind: win.kind,\n\t\t\t\ttitle: win.title,\n\t\t\t\ticon: win.icon,\n\t\t\t\tbounds: { ...win.bounds },\n\t\t\t\tsize: { ...win.size },\n\t\t\t\tcapabilities: { ...win.capabilities },\n\t\t\t\tmode: win.mode,\n\t\t\t\trestoreMode: win.restoreMode,\n\t\t\t\tfullscreenRestoreMode: win.fullscreenRestoreMode,\n\t\t\t\tchrome: win.chrome,\n\t\t\t\tshowInDock: win.showInDock,\n\t\t\t\tpersistence: win.persistence,\n\t\t\t\tpinned: win.pinned,\n\t\t\t\t...(data === undefined ? {} : { data }),\n\t\t\t},\n\t\t];\n\t});\n\tconst persistentIds = new Set(windows.map((win) => win.id));\n\treturn {\n\t\tversion: WINDOW_MANAGER_SNAPSHOT_VERSION,\n\t\tsavedAt: (options.now ?? Date.now)(),\n\t\tdock: { ...state.workspace.dock },\n\t\tdockOrder: windows.map((win) => win.id),\n\t\torder: state.order.filter((id) => persistentIds.has(id)),\n\t\twindows,\n\t};\n}\n\nfunction resolveStorage(storage: WindowManagerPersistenceProps['storage']): WindowManagerStorage | undefined {\n\tif (typeof storage === 'object') return storage;\n\tif (typeof window === 'undefined') return undefined;\n\treturn storage === 'session' ? window.sessionStorage : window.localStorage;\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager-persistence.tsx" }, { "path": "registry/default/blocks/window-manager/window-manager.tsx", "content": "'use client';\n\nimport { WindowManagerProvider } from './window-manager-context';\nimport { WindowManagerHost, type WindowManagerHostProps } from './window-manager-host';\nimport { WindowManagerPersistence, type WindowManagerPersistenceProps } from './window-manager-persistence';\nimport type { WindowManagerStore } from './window-manager-store';\nimport type { WindowManagerCreateOptions } from './window-manager-types';\n\nexport type WindowManagerRuntimeProps = WindowManagerHostProps & {\n\toptions?: WindowManagerCreateOptions;\n\tpersistence?: false | WindowManagerPersistenceProps;\n\tstore?: WindowManagerStore;\n};\n\nexport function WindowManagerRuntime({ options, persistence = false, store, ...hostProps }: WindowManagerRuntimeProps) {\n\treturn (\n\t\t\n\t\t\t{persistence ? : null}\n\t\t\t\n\t\t\n\t);\n}\n", "type": "registry:component", "target": "@components/window-manager/window-manager.tsx" }, { "path": "registry/default/blocks/window-manager/index.ts", "content": "export * from './window-manager';\nexport * from './window-manager-chrome';\nexport * from './window-manager-context';\nexport * from './window-manager-dock';\nexport * from './window-manager-host';\nexport * from './window-manager-motion';\nexport * from './window-manager-persistence';\nexport * from './window-manager-store';\nexport * from './window-manager-types';\n", "type": "registry:component", "target": "@components/window-manager/index.ts" } ], "type": "registry:block" }