@owdproject/core 3.4.0 → 4.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +112 -13
  2. package/dist/dom/index.d.mts +65 -0
  3. package/dist/dom/index.d.ts +65 -0
  4. package/dist/dom/index.mjs +224 -0
  5. package/dist/events/index.d.mts +70 -0
  6. package/dist/events/index.d.ts +70 -0
  7. package/dist/events/index.mjs +3 -0
  8. package/dist/index.d.mts +73 -0
  9. package/dist/index.d.ts +73 -0
  10. package/dist/index.mjs +115 -0
  11. package/dist/layout/index.d.mts +41 -0
  12. package/dist/layout/index.d.ts +41 -0
  13. package/dist/layout/index.mjs +64 -0
  14. package/dist/machines/index.d.mts +31 -0
  15. package/dist/machines/index.d.ts +31 -0
  16. package/dist/machines/index.mjs +2 -0
  17. package/dist/managers/index.d.mts +118 -0
  18. package/dist/managers/index.d.ts +118 -0
  19. package/dist/managers/index.mjs +6 -0
  20. package/dist/session/index.d.mts +57 -0
  21. package/dist/session/index.d.ts +57 -0
  22. package/dist/session/index.mjs +65 -0
  23. package/dist/shared/core.B1XxB289.mjs +239 -0
  24. package/dist/shared/core.B3mp7ztE.mjs +237 -0
  25. package/dist/shared/core.BOvFdEVQ.d.ts +114 -0
  26. package/dist/shared/core.CsDFgGnX.mjs +40 -0
  27. package/dist/shared/core.Di1eFcr_.d.mts +114 -0
  28. package/dist/shared/core.Pd_Ogt4g.mjs +101 -0
  29. package/dist/shared/core.b3Xldzyu.mjs +29 -0
  30. package/dist/shared/core.d_A3q1kZ.mjs +869 -0
  31. package/dist/types/index.d.mts +266 -0
  32. package/dist/types/index.d.ts +266 -0
  33. package/dist/types/index.mjs +1 -0
  34. package/package.json +56 -112
  35. package/CHANGELOG.md +0 -98
  36. package/DESKTOP_KERNEL.md +0 -232
  37. package/MIGRATION_3.3.2.md +0 -23
  38. package/MIGRATION_3.4.md +0 -126
  39. package/PLAYGROUND.md +0 -91
  40. package/dist/module.d.mts +0 -13
  41. package/dist/module.json +0 -9
  42. package/dist/module.mjs +0 -254
  43. package/dist/types.d.mts +0 -7
  44. package/index.ts +0 -8
  45. package/kit/authoring.ts +0 -340
  46. package/kit/defineDesktopApp.ts +0 -56
  47. package/module.ts +0 -203
  48. package/runtime/components/Application/DesktopCoreApplicationRender.vue +0 -20
  49. package/runtime/components/Application/DesktopCoreApplicationWindowsRender.vue +0 -38
  50. package/runtime/components/background/DesktopCoreBackground.vue +0 -16
  51. package/runtime/components/core/DesktopCore.vue +0 -43
  52. package/runtime/components/time/DesktopCoreTime.vue +0 -56
  53. package/runtime/components/window/DesktopCoreWindow.vue +0 -215
  54. package/runtime/components/window/DesktopCoreWindowContent.vue +0 -28
  55. package/runtime/components/window/DesktopCoreWindowNav.vue +0 -66
  56. package/runtime/components/window/DesktopCoreWindowSnapHintsBase.vue +0 -74
  57. package/runtime/components/workspace/DesktopCoreWorkspaceEdgeHintsBase.vue +0 -84
  58. package/runtime/composables/useApplicationEntries.ts +0 -51
  59. package/runtime/composables/useApplicationManager.ts +0 -285
  60. package/runtime/composables/useBlockNonInputContextMenu.ts +0 -30
  61. package/runtime/composables/useDesktopConfig.ts +0 -8
  62. package/runtime/composables/useDesktopDialogs.ts +0 -16
  63. package/runtime/composables/useDesktopExtension.ts +0 -8
  64. package/runtime/composables/useDesktopManager.ts +0 -51
  65. package/runtime/composables/useDesktopManifest.ts +0 -17
  66. package/runtime/composables/useDesktopSession.ts +0 -27
  67. package/runtime/composables/useDesktopShellIdentity.ts +0 -99
  68. package/runtime/composables/useDesktopShellOptions.ts +0 -36
  69. package/runtime/composables/useDesktopShellReady.ts +0 -7
  70. package/runtime/composables/useDesktopWorkArea.ts +0 -93
  71. package/runtime/composables/useTerminalManager.ts +0 -159
  72. package/runtime/composables/useToggleWindowMaximize.ts +0 -35
  73. package/runtime/composables/useWindowDragHandlers.ts +0 -47
  74. package/runtime/composables/useWindowSnapDrop.ts +0 -112
  75. package/runtime/composables/useWorkspaceEdgeDrop.ts +0 -176
  76. package/runtime/composables/useWorkspaceManager.ts +0 -67
  77. package/runtime/composables/useWorkspaceOverviewCapture.ts +0 -92
  78. package/runtime/composables/useWorkspaceOverviewLiveScale.ts +0 -151
  79. package/runtime/constants/desktopShellKeys.ts +0 -12
  80. package/runtime/constants/shellLayout.ts +0 -5
  81. package/runtime/dialogs/desktopDialogProvider.ts +0 -73
  82. package/runtime/internal/controllers/ApplicationController.ts +0 -351
  83. package/runtime/internal/controllers/WindowController.ts +0 -547
  84. package/runtime/plugins/01.desktop-shell-init.client.ts +0 -28
  85. package/runtime/plugins/02.desktop-register-desktop-apps.client.ts +0 -13
  86. package/runtime/plugins/resize.client.ts +0 -6
  87. package/runtime/stores/storeApplicationMeta.ts +0 -60
  88. package/runtime/stores/storeApplicationWindows.ts +0 -21
  89. package/runtime/stores/storeDesktop.ts +0 -71
  90. package/runtime/stores/storeDesktopDefaultApps.ts +0 -54
  91. package/runtime/stores/storeDesktopVolume.ts +0 -19
  92. package/runtime/stores/storeDesktopWindow.ts +0 -38
  93. package/runtime/stores/storeDesktopWorkspace.ts +0 -105
  94. package/runtime/stores/storeIds.ts +0 -35
  95. package/runtime/types/desktopMenu.ts +0 -10
  96. package/runtime/utils/initDesktopShell.ts +0 -80
  97. package/runtime/utils/migratePersistedStoreIds.ts +0 -57
  98. package/runtime/utils/utilApp.ts +0 -25
  99. package/runtime/utils/utilCaptureElementToCanvas.ts +0 -21
  100. package/runtime/utils/utilCommon.ts +0 -26
  101. package/runtime/utils/utilDebug.ts +0 -30
  102. package/runtime/utils/utilDetectSnapZone.ts +0 -57
  103. package/runtime/utils/utilTerminal.ts +0 -6
  104. package/runtime/utils/utilWindowControllerAdapter.ts +0 -15
  105. package/runtime/utils/utilWindowLayout.ts +0 -82
  106. package/runtime/utils/utilWindowMaximizeLayout.ts +0 -44
  107. package/runtime/utils/utilWorkspaceWindows.ts +0 -33
  108. package/types/index.d.ts +0 -531
@@ -1,151 +0,0 @@
1
- import type { CSSProperties, Ref } from 'vue'
2
- import {
3
- nextTick,
4
- onScopeDispose,
5
- readonly,
6
- shallowRef,
7
- watch,
8
- } from 'vue'
9
- import { useDesktopWorkspaceStore } from '@owdproject/core/runtime/stores/storeDesktopWorkspace'
10
-
11
- export type WorkspaceStageSize = {
12
- width: number
13
- height: number
14
- }
15
-
16
- export type WorkspaceOverviewLiveScaleOptions = {
17
- /** Upper bound for scale (default 1). */
18
- maxScale?: number
19
- }
20
-
21
- export type WorkspaceOverviewInnerStyleOptions =
22
- WorkspaceOverviewLiveScaleOptions & {
23
- transformOrigin?: string
24
- }
25
-
26
- /**
27
- * Fit factor to show a 1:1 shell stage inside a panel viewport without clipping.
28
- */
29
- export function computeScaleToFit(
30
- panelWidth: number,
31
- panelHeight: number,
32
- stageWidth: number,
33
- stageHeight: number,
34
- options?: WorkspaceOverviewLiveScaleOptions,
35
- ): number {
36
- if (
37
- panelWidth <= 0 ||
38
- panelHeight <= 0 ||
39
- stageWidth <= 0 ||
40
- stageHeight <= 0
41
- ) {
42
- return 1
43
- }
44
-
45
- const scale = Math.min(panelWidth / stageWidth, panelHeight / stageHeight)
46
- const maxScale = options?.maxScale ?? 1
47
- return Math.min(scale, maxScale)
48
- }
49
-
50
- /**
51
- * Live DOM workspace overview: measure shell stage, scale desktop roots to fit cards.
52
- */
53
- export function useWorkspaceOverviewLiveScale(
54
- shellStageRef: Ref<HTMLElement | null | undefined>,
55
- ) {
56
- const desktopWorkspaceStore = useDesktopWorkspaceStore()
57
- const stageSize = shallowRef<WorkspaceStageSize>({ width: 0, height: 0 })
58
-
59
- let resizeObserver: ResizeObserver | null = null
60
-
61
- function readStageSize() {
62
- const el = shellStageRef.value
63
- if (!el) {
64
- stageSize.value = { width: 0, height: 0 }
65
- return
66
- }
67
- stageSize.value = {
68
- width: el.clientWidth,
69
- height: el.clientHeight,
70
- }
71
- }
72
-
73
- function stopObserving() {
74
- resizeObserver?.disconnect()
75
- resizeObserver = null
76
- }
77
-
78
- function startObserving() {
79
- stopObserving()
80
- const el = shellStageRef.value
81
- if (!el || typeof ResizeObserver === 'undefined') return
82
-
83
- readStageSize()
84
- resizeObserver = new ResizeObserver(() => readStageSize())
85
- resizeObserver.observe(el)
86
- }
87
-
88
- watch(
89
- () => desktopWorkspaceStore.overview,
90
- (open) => {
91
- if (open) {
92
- void nextTick(() => startObserving())
93
- } else {
94
- stopObserving()
95
- stageSize.value = { width: 0, height: 0 }
96
- }
97
- },
98
- )
99
-
100
- watch(shellStageRef, (el) => {
101
- if (desktopWorkspaceStore.overview && el) {
102
- void nextTick(() => startObserving())
103
- }
104
- })
105
-
106
- onScopeDispose(stopObserving)
107
-
108
- function scaleToFit(
109
- panelEl: HTMLElement | null | undefined,
110
- options?: WorkspaceOverviewLiveScaleOptions,
111
- ): number {
112
- if (!panelEl) return 1
113
- const { width: stageWidth, height: stageHeight } = stageSize.value
114
- if (stageWidth <= 0 || stageHeight <= 0) return 1
115
-
116
- return computeScaleToFit(
117
- panelEl.clientWidth,
118
- panelEl.clientHeight,
119
- stageWidth,
120
- stageHeight,
121
- options,
122
- )
123
- }
124
-
125
- function innerOverviewStyle(
126
- panelEl: HTMLElement | null | undefined,
127
- options?: WorkspaceOverviewInnerStyleOptions,
128
- ): CSSProperties | undefined {
129
- if (!desktopWorkspaceStore.overview) return undefined
130
-
131
- const { width: stageWidth, height: stageHeight } = stageSize.value
132
- if (stageWidth <= 0 || stageHeight <= 0) return undefined
133
-
134
- const scale = scaleToFit(panelEl, options)
135
- const transformOrigin = options?.transformOrigin ?? 'top left'
136
-
137
- return {
138
- width: `${stageWidth}px`,
139
- height: `${stageHeight}px`,
140
- transform: `scale(${scale})`,
141
- transformOrigin,
142
- }
143
- }
144
-
145
- return {
146
- stageSize: readonly(stageSize),
147
- scaleToFit,
148
- innerOverviewStyle,
149
- refreshStageSize: readStageSize,
150
- }
151
- }
@@ -1,12 +0,0 @@
1
- import type { InjectionKey } from 'vue'
2
- import type { DesktopDialogProvider } from '../dialogs/desktopDialogProvider'
3
-
4
- export type DesktopToggleWindowMaximizeFn = (
5
- win: IWindowController | undefined,
6
- ) => boolean
7
-
8
- export const DESKTOP_DIALOG_PROVIDER_KEY: InjectionKey<DesktopDialogProvider> =
9
- Symbol('desktop-dialog-provider')
10
-
11
- export const DESKTOP_TOGGLE_WINDOW_MAXIMIZE_KEY: InjectionKey<DesktopToggleWindowMaximizeFn> =
12
- Symbol('desktop-toggle-window-maximize')
@@ -1,5 +0,0 @@
1
- /** Viewport band (px) where a window drag targets the adjacent workspace. */
2
- export const WORKSPACE_EDGE_DROP_PX = 72
3
-
4
- /** Viewport band (px) where a window drag targets a snap zone. */
5
- export const WINDOW_SNAP_EDGE_PX = 14
@@ -1,73 +0,0 @@
1
- /** Options for a yes/no confirmation (theme renders labels and chrome). */
2
- export interface DesktopConfirmDialogOptions {
3
- title?: string
4
- message: string
5
- danger?: boolean
6
- acceptLabel?: string
7
- rejectLabel?: string
8
- /**
9
- * Theme-specific payload (e.g. delete dialog passes `toTrash` for slot templates).
10
- */
11
- extras?: Record<string, unknown>
12
- }
13
-
14
- /**
15
- * Cross-theme dialog API. Themes implement with PrimeVue, native dialogs, etc.
16
- * Callers pass user-facing strings (usually from i18n); implementations only render.
17
- */
18
- export interface DesktopDialogProvider {
19
- confirm(options: DesktopConfirmDialogOptions): Promise<boolean>
20
- alert(message: string, options?: { title?: string }): Promise<void>
21
- prompt(message: string, defaultValue?: string): Promise<string | null>
22
- }
23
-
24
- function browserGlobals(): {
25
- confirm: (message?: string) => boolean
26
- alert: (message?: string) => void
27
- prompt: (message?: string, defaultText?: string) => string | null
28
- } | null {
29
- const g = globalThis as typeof globalThis & {
30
- confirm?: (message?: string) => boolean
31
- alert?: (message?: string) => void
32
- prompt?: (message?: string, defaultText?: string) => string | null
33
- }
34
- if (typeof g.confirm !== 'function') return null
35
- return {
36
- confirm: g.confirm.bind(g),
37
- alert:
38
- typeof g.alert === 'function'
39
- ? g.alert.bind(g)
40
- : (m?: string) => {
41
- void m
42
- },
43
- prompt:
44
- typeof g.prompt === 'function'
45
- ? g.prompt.bind(g)
46
- : () => null,
47
- }
48
- }
49
-
50
- export function createBrowserFallbackDialogProvider(): DesktopDialogProvider {
51
- return {
52
- async confirm(opts) {
53
- if (import.meta.server) return false
54
- const w = browserGlobals()
55
- if (!w) return false
56
- const text = [opts.title, opts.message].filter(Boolean).join('\n\n')
57
- return w.confirm(text)
58
- },
59
- async alert(message, opts) {
60
- if (import.meta.server) return
61
- const w = browserGlobals()
62
- if (!w) return
63
- w.alert([opts?.title, message].filter(Boolean).join('\n\n'))
64
- },
65
- async prompt(message, defaultValue = '') {
66
- if (import.meta.server) return null
67
- const w = browserGlobals()
68
- if (!w) return null
69
- const v = w.prompt(message, defaultValue)
70
- return v === null ? null : v
71
- },
72
- }
73
- }
@@ -1,351 +0,0 @@
1
- import { nanoid } from 'nanoid'
2
- import { WindowController } from './WindowController'
3
- import { useApplicationManager } from '../../composables/useApplicationManager'
4
- import { useApplicationWindowsStore } from '../../stores/storeApplicationWindows'
5
- import { useApplicationMetaStore } from '../../stores/storeApplicationMeta'
6
- import { useTerminalManager } from '../../composables/useTerminalManager'
7
- import { debugLog, debugError } from '../../utils/utilDebug'
8
- import { useDesktopDefaultAppsStore } from '../../stores/storeDesktopDefaultApps'
9
- import { useDesktopWorkspaceStore } from '../../stores/storeDesktopWorkspace'
10
- import { useDesktopWindowStore } from '../../stores/storeDesktopWindow'
11
- import { shallowRef } from 'vue'
12
- import { unref } from 'vue'
13
-
14
- export class ApplicationController implements IApplicationController {
15
- private readonly applicationManager: IApplicationManager
16
- private readonly terminalManager: ITerminalManager
17
-
18
- public readonly id
19
- public readonly config
20
- public readonly storeWindows
21
-
22
- private readonly _windows = shallowRef(new Map<string, IWindowController>())
23
-
24
- /** Reactive window count for Vue (class getters are not tracked). */
25
- public readonly openWindowCount = shallowRef(0)
26
-
27
- get windows(): Map<string, IWindowController> {
28
- return this._windows.value
29
- }
30
-
31
- private replaceWindows(
32
- mutator: (next: Map<string, IWindowController>) => void,
33
- ) {
34
- const next = new Map(this._windows.value)
35
- mutator(next)
36
- this._windows.value = next
37
- this.openWindowCount.value = next.size
38
- }
39
-
40
- public isRunning = false
41
-
42
- constructor(id: string, config: ApplicationConfig) {
43
- this.applicationManager = useApplicationManager()
44
- this.terminalManager = useTerminalManager()
45
-
46
- this.id = id
47
- this.config = config
48
- this.storeWindows = useApplicationWindowsStore(id)
49
- }
50
-
51
- /** Lazy meta store — app modules should register state via `useApplicationMetaStore` before `defineDesktopApp`. */
52
- get storeMeta() {
53
- return useApplicationMetaStore(this.id)()
54
- }
55
-
56
- public async initApplication(): Promise<void> {
57
- const desktopDefaultAppsStore = useDesktopDefaultAppsStore()
58
-
59
- // provides
60
-
61
- // set as default app for specific purposes
62
- // todo improve this and move it in a store
63
- if (this.config.provides) {
64
- const existingDefault = desktopDefaultAppsStore.getDefaultApp(
65
- this.config.provides.name,
66
- )
67
-
68
- if (!existingDefault) {
69
- desktopDefaultAppsStore.setDefaultApp(
70
- this.config.provides.name,
71
- this,
72
- this.config.provides.entry,
73
- )
74
-
75
- debugLog(
76
- `${this.config.title} has been set as predefined app for "${this.config.provides.name}"`,
77
- )
78
- }
79
- }
80
-
81
- // terminal
82
-
83
- if (this.config.commands) {
84
- for (const commandKey of Object.keys(this.config.commands)) {
85
- const meta = this.config.terminal?.[commandKey] ?? {}
86
- this.terminalManager.addCommand({
87
- applicationId: this.id,
88
- name: commandKey,
89
- ...meta,
90
- })
91
- }
92
- }
93
-
94
- // store
95
-
96
- if (this.storeWindows.$persistedState) {
97
- await this.storeWindows.$persistedState.isReady()
98
- }
99
-
100
- if (this.storeMeta.$persistedState) {
101
- await this.storeMeta.$persistedState.isReady()
102
- }
103
-
104
- // set default meta values
105
- // this.storeMeta.meta = this.config.meta ?? {}
106
-
107
- // restore application state
108
- await this.restoreApplication()
109
-
110
- // once app is defined, always run "onReady"
111
- if (typeof this.config.onReady === 'function') {
112
- // todo transform in hook
113
- this.config.onReady(this)
114
- }
115
- }
116
-
117
- /**
118
- * App always tries to restore previous windows
119
- * and returns a boolean if it succeeded
120
- */
121
- public async restoreApplication() {
122
- if (typeof this.config.onRestore === 'function') {
123
- // todo transform in hook
124
- await this.config.onRestore(this)
125
- }
126
-
127
- if (
128
- !this.storeWindows.windows ||
129
- Object.keys(this.storeWindows.windows).length === 0
130
- ) {
131
- return false
132
- }
133
-
134
- this.restoreWindows()
135
-
136
- this.setRunning(true)
137
-
138
- return true
139
- }
140
-
141
- private restoreWindows() {
142
- Object.keys(this.storeWindows.windows).map((windowId) => {
143
- const windowStore: WindowStoredState | undefined =
144
- this.storeWindows.windows[windowId]
145
-
146
- if (windowStore) {
147
- this.openWindow(windowStore.model, windowStore, {
148
- isRestoring: true,
149
- })
150
- }
151
- })
152
-
153
- this.normalizeWindowFocus()
154
-
155
- debugLog('Windows have been restored', this.windows)
156
- }
157
-
158
- /** Ensure a single focused window after restore or stale persisted state. */
159
- private normalizeWindowFocus() {
160
- const allWindows = this.applicationManager?.windowsOpened?.value
161
- ? Array.from(this.applicationManager.windowsOpened.value.values())
162
- : Array.from(this.windows.values())
163
-
164
- if (allWindows.length === 0) {
165
- return
166
- }
167
-
168
- let topWindow: IWindowController | undefined
169
- let topZ = -Infinity
170
-
171
- for (const window of allWindows) {
172
- window.setFocus(false)
173
- const z = window.state.position?.z ?? 0
174
- if (z >= topZ) {
175
- topZ = z
176
- topWindow = window
177
- }
178
- }
179
-
180
- topWindow?.setFocus(true)
181
- }
182
-
183
- public openWindow(
184
- model: string,
185
- windowStoredState: WindowStoredState | undefined,
186
- meta?: any,
187
- ) {
188
- const desktopWorkspaceStore = useDesktopWorkspaceStore()
189
-
190
- if (!this.config.windows || !this.config.windows.hasOwnProperty(model)) {
191
- debugError(`Window model "${model}" not found`)
192
- return
193
- }
194
-
195
- if (!windowStoredState && this.config.singleton) {
196
- const existing = this.getFirstWindowByModel(model)
197
- if (existing) {
198
- if (meta && typeof meta === 'object') {
199
- Object.assign(existing.meta, meta)
200
- }
201
- if (!meta?.isRestoring) {
202
- existing.actions.setActive(true)
203
- existing.actions.bringToFront()
204
- }
205
- return existing
206
- }
207
- }
208
-
209
- let windowId: string
210
-
211
- if (!windowStoredState) {
212
- windowId = `${model}-${nanoid(6)}`
213
-
214
- const windowConfig: WindowConfig = this.config.windows[
215
- model
216
- ] as WindowConfig
217
- const screenHeight = window.innerHeight
218
- const configHeight = windowConfig.size?.height
219
- const layoutHeight =
220
- typeof configHeight === 'number'
221
- ? configHeight
222
- : typeof configHeight === 'string' && /^\d+$/.test(configHeight)
223
- ? Number(configHeight)
224
- : 240
225
- const centerY = (screenHeight - layoutHeight) / 2
226
- const positionY =
227
- windowConfig.position?.y !== undefined
228
- ? window.scrollY + windowConfig.position.y
229
- : window.scrollY + centerY
230
- const cascadeStep = 40
231
- const cascadeOffset = this.getWindowsByModel(model).length * cascadeStep
232
- const baseX = windowConfig.position?.x ?? 100
233
- const desktopWindowStore = useDesktopWindowStore()
234
- const initialZ = desktopWindowStore.incrementPositionZ()
235
-
236
- const nextWindows = {
237
- ...this.storeWindows.windows,
238
- [windowId]: {
239
- model,
240
- state: {
241
- id: windowId,
242
- active: true,
243
- focused: false,
244
- position: {
245
- x: baseX + cascadeOffset,
246
- y: positionY + cascadeOffset,
247
- z: initialZ,
248
- },
249
- createdAt: +new Date(),
250
- workspace: desktopWorkspaceStore.resolveActiveWorkspaceId(),
251
- },
252
- meta,
253
- },
254
- }
255
- this.storeWindows.windows = nextWindows
256
-
257
- windowStoredState = this.storeWindows.windows[windowId]
258
- } else {
259
- // restore previous id if state is defined
260
- windowId =
261
- windowStoredState.state?.id ??
262
- Object.keys(this.storeWindows.windows).find(
263
- (key) => this.storeWindows.windows[key] === windowStoredState,
264
- ) ??
265
- `${model}-restored`
266
- }
267
-
268
- const windowConfig = this.config.windows[model] as WindowConfig
269
-
270
- const windowController = new WindowController(
271
- this,
272
- model,
273
- windowConfig,
274
- windowStoredState!,
275
- )
276
-
277
- if (!meta?.isRestoring) {
278
- windowController.actions.bringToFront()
279
- }
280
-
281
- this.replaceWindows((next) => {
282
- next.set(windowId, windowController)
283
- })
284
-
285
- this.setRunning(true)
286
-
287
- return windowController
288
- }
289
-
290
- public closeWindow(windowId: string) {
291
- if (this.storeWindows.windows[windowId]) {
292
- const nextWindows = { ...this.storeWindows.windows }
293
- delete nextWindows[windowId]
294
- this.storeWindows.windows = nextWindows
295
- }
296
-
297
- this.replaceWindows((next) => {
298
- next.delete(windowId)
299
- })
300
-
301
- if (this.openWindowCount.value === 0) {
302
- this.applicationManager.closeApp(this.id)
303
- }
304
- }
305
-
306
- public closeAllWindows() {
307
- this.storeWindows.windows = {}
308
- this._windows.value = new Map()
309
- this.openWindowCount.value = 0
310
- }
311
-
312
- get windowsOpened() {
313
- return this.windows
314
- }
315
-
316
- public getWindowById(id: string): IWindowController[] {
317
- return this.windows.get(id)
318
- }
319
-
320
- public getWindowsByModel(model: string): IWindowController[] {
321
- return Array.from(this.windows.values()).filter((w) => w.model === model)
322
- }
323
-
324
- public getFirstWindowByModel(model: string): IWindowController | undefined {
325
- return Array.from(this.windows.values()).find((w) => w.model === model)
326
- }
327
-
328
- public setRunning(value: boolean): void {
329
- this.isRunning = value
330
- }
331
-
332
- // meta
333
-
334
- get meta() {
335
- return this.storeMeta.meta
336
- }
337
-
338
- getMeta(key: string) {
339
- return this.meta[key]
340
- }
341
-
342
- setMeta(key: string, value: any) {
343
- this.meta[key] = value
344
- }
345
-
346
- // commands
347
-
348
- async execCommand(command: string): Promise<CommandOutput | void> {
349
- return this.applicationManager.execAppCommand(this.id, command)
350
- }
351
- }