@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,285 +0,0 @@
1
- import { reactive, markRaw, computed } from 'vue'
2
- import { ApplicationController } from '../internal/controllers/ApplicationController'
3
- import { normalizeApplicationConfig } from '../utils/utilApp'
4
- import { debugLog } from '../utils/utilDebug'
5
- import * as shellwords from 'shellwords'
6
- import getopts from "getopts"
7
-
8
- const apps = reactive(new Map<string, IApplicationController>())
9
-
10
- /**
11
- * Application Manager Composable (Singleton)
12
- */
13
- export function useApplicationManager() {
14
- /**
15
- * Define new application
16
- *
17
- * @param id
18
- * @param config
19
- */
20
- async function defineApp(id: string, config: ApplicationConfig) {
21
- if (isAppDefined(id)) {
22
- debugLog(`App "${id}" is already defined`)
23
- return getAppById(id)!
24
- }
25
-
26
- const normalizedConfig = normalizeApplicationConfig(config)
27
- const applicationConfig = markRaw(normalizedConfig)
28
-
29
- const applicationController: IApplicationController = new ApplicationController(id, applicationConfig)
30
- await applicationController.initApplication()
31
-
32
- apps.set(id, markRaw(applicationController))
33
-
34
- return applicationController
35
- }
36
-
37
- /**
38
- * Check if app has been defined
39
- *
40
- * @param {string} id
41
- */
42
- function isAppDefined(id: string) {
43
- return getAppById(id)
44
- }
45
-
46
- /**
47
- * Retrieves an app instance by its unique identifier
48
- *
49
- * @param {string} id
50
- */
51
- function getAppById(id: string) {
52
- return apps.get(id)
53
- }
54
-
55
- /**
56
- * Check if app is running
57
- *
58
- * @param {string} id
59
- */
60
- function isAppRunning(id: string) {
61
- if (!isAppDefined(id)) {
62
- throw Error(`App "${id}" is not defined`)
63
- }
64
-
65
- const applicationController = getAppById(id)!
66
- return applicationController.isRunning
67
- }
68
-
69
- /**
70
- * Launch app entry
71
- *
72
- * @param id
73
- * @param entryKey
74
- * @param argument
75
- */
76
- async function launchAppEntry(
77
- id: string,
78
- entryKey: string,
79
- argument: string = ''
80
- ): Promise<IApplicationController | undefined | void> {
81
- if (!isAppDefined(id)) {
82
- throw Error(`App "${id}" is not defined`)
83
- }
84
-
85
- const applicationController = getAppById(id)!
86
-
87
- if (
88
- applicationController.config.entries &&
89
- !applicationController.config.entries.hasOwnProperty(entryKey)
90
- ) {
91
- throw Error(`App entry "${entryKey}" is not defined in ${id} application`)
92
- }
93
-
94
- const entry: ApplicationEntry = applicationController.config.entries[entryKey]!
95
-
96
- if (argument) argument = ` ${argument}`
97
-
98
- await execAppCommand(applicationController.id, entry.command + argument)
99
- }
100
-
101
- /**
102
- * Run app command
103
- *
104
- * @param id
105
- * @param rawCommand
106
- */
107
- async function execAppCommand(
108
- id: string,
109
- rawCommand: string,
110
- ): Promise<CommandOutput> {
111
- if (!isAppDefined(id)) {
112
- throw Error(`App "${id}" is not defined`)
113
- }
114
-
115
- const applicationController = getAppById(id)!
116
-
117
- const args = shellwords.split(rawCommand)
118
- const parsed = getopts(args)
119
- const command: string = parsed._[0]
120
-
121
- if (
122
- applicationController.config.commands &&
123
- !applicationController.config.commands.hasOwnProperty(command)
124
- ) {
125
- throw Error(
126
- `App command "${command}" is not defined in ${id} application`,
127
- )
128
- }
129
-
130
- const commandFn: any = applicationController.config.commands![command]
131
-
132
- const commandOutput = await commandFn(applicationController, parsed)
133
-
134
- applicationController.setRunning(true)
135
-
136
- return commandOutput
137
- }
138
-
139
- /**
140
- * Close application
141
- *
142
- * @param id
143
- */
144
- function closeApp(id: string) {
145
- if (!isAppDefined(id)) {
146
- throw Error(`App "${id}" is not defined`)
147
- }
148
-
149
- const applicationController = getAppById(id)!
150
-
151
- applicationController.closeAllWindows()
152
- applicationController.setRunning(false)
153
- }
154
-
155
- /**
156
- * Array of available menu entries for system bars, docks
157
- */
158
- const appsEntries = computed(() => {
159
- const entries: ApplicationEntryWithInherited[] = []
160
-
161
- for (const applicationController of apps.values()) {
162
- if (!applicationController.config.entries) {
163
- continue
164
- }
165
-
166
- for (const entryKey of Object.keys(applicationController.config.entries)) {
167
- const entry = applicationController.config.entries[entryKey]!
168
-
169
- entries.push({
170
- application: applicationController,
171
- title: entry.title ?? applicationController.config.title,
172
- icon: entry.icon ?? applicationController.config.icon,
173
- category: entry.category ?? applicationController.config.category,
174
- visibility: entry.visibility ?? 'primary',
175
- command: entry.command,
176
- })
177
- }
178
- }
179
-
180
- return entries
181
- })
182
-
183
- /**
184
- * Array of opened windows for system bars, docks
185
- */
186
- const windowsOpened = computed(() => {
187
- const windows = new Map<string, IWindowController>()
188
-
189
- for (const applicationController of apps.values()) {
190
- if (
191
- !applicationController.isRunning &&
192
- applicationController.openWindowCount.value === 0
193
- ) {
194
- continue
195
- }
196
-
197
- for (const [windowId, window] of applicationController.windows) {
198
- windows.set(windowId, window)
199
- }
200
- }
201
-
202
- return windows
203
- })
204
-
205
- /**
206
- * Array of running applications
207
- */
208
- const appsRunning = computed(() => {
209
- const runningApps: IApplicationController[] = []
210
-
211
- for (const applicationController of apps.values()) {
212
- const openCount = applicationController.openWindowCount.value
213
- if (applicationController.isRunning || openCount > 0) {
214
- runningApps.push(applicationController)
215
- }
216
- }
217
-
218
- return runningApps
219
- })
220
-
221
- function getWindowOpenedId(windowId: string) {
222
- for (const window of windowsOpened.value.values()) {
223
- if (window.state.id === windowId) {
224
- return window
225
- }
226
- }
227
- }
228
-
229
- /**
230
- * Gets all unique categories from the installed apps
231
- */
232
- const appCategories = computed(() => {
233
- const categories = new Set<string>()
234
-
235
- for (const applicationController of apps.values()) {
236
- if (applicationController.config.category) {
237
- categories.add(applicationController.config.category)
238
- }
239
- }
240
-
241
- return Array.from(categories).sort()
242
- })
243
-
244
- /**
245
- * Gets the apps ordered by category
246
- */
247
- const appsByCategory = computed(() => {
248
- const categorizedApps: {
249
- [category: string]: IApplicationController[]
250
- } = {}
251
-
252
- for (const applicationController of apps.values()) {
253
- const category = applicationController.config.category || 'other'
254
- if (!categorizedApps[category]) {
255
- categorizedApps[category] = []
256
- }
257
- categorizedApps[category].push(applicationController)
258
- }
259
-
260
- for (const category in categorizedApps) {
261
- categorizedApps[category].sort((a, b) =>
262
- a.config.title.localeCompare(b.config.title),
263
- )
264
- }
265
-
266
- return categorizedApps
267
- })
268
-
269
- return {
270
- defineApp,
271
- isAppDefined,
272
- getAppById,
273
- isAppRunning,
274
- launchAppEntry,
275
- execAppCommand,
276
- closeApp,
277
- getWindowOpenedId,
278
- apps,
279
- appsEntries,
280
- appsRunning,
281
- windowsOpened,
282
- appCategories,
283
- appsByCategory,
284
- }
285
- }
@@ -1,30 +0,0 @@
1
- import { useEventListener } from '@vueuse/core'
2
- import { isDebugMode } from '../utils/utilDebug'
3
-
4
- /**
5
- * Blocks the browser context menu on non-input elements (typical desktop shell behaviour).
6
- * Debug builds skip blocking so DevTools stay usable when {@link isDebugMode} is true.
7
- */
8
- export function useBlockNonInputContextMenu() {
9
- useEventListener(
10
- document,
11
- 'contextmenu',
12
- (event: MouseEvent) => {
13
- if (isDebugMode()) return
14
-
15
- const target = event.target as HTMLElement | null
16
- if (!target) return
17
-
18
- const tag = target.tagName?.toLowerCase()
19
- const isInput =
20
- tag === 'input' ||
21
- tag === 'textarea' ||
22
- Boolean(target.isContentEditable)
23
-
24
- if (!isInput) {
25
- event.preventDefault()
26
- }
27
- },
28
- { passive: false },
29
- )
30
- }
@@ -1,8 +0,0 @@
1
- import { useRuntimeConfig } from 'nuxt/app'
2
- import { computed } from 'vue'
3
-
4
- /** Reactive view of `runtimeConfig.public.desktop` (full desktop.config merge + coreVersion). */
5
- export function useDesktopConfig() {
6
- const runtimeConfig = useRuntimeConfig()
7
- return computed(() => runtimeConfig.public.desktop)
8
- }
@@ -1,16 +0,0 @@
1
- import { inject } from 'vue'
2
- import { DESKTOP_DIALOG_PROVIDER_KEY } from '../constants/desktopShellKeys'
3
- import {
4
- createBrowserFallbackDialogProvider,
5
- type DesktopDialogProvider,
6
- } from '../dialogs/desktopDialogProvider'
7
-
8
- /**
9
- * Returns the active desktop dialog provider (theme) or a browser fallback.
10
- */
11
- export function useDesktopDialogs(): DesktopDialogProvider {
12
- return (
13
- inject(DESKTOP_DIALOG_PROVIDER_KEY, null) ??
14
- createBrowserFallbackDialogProvider()
15
- )
16
- }
@@ -1,8 +0,0 @@
1
- import { computed } from 'vue'
2
- import { useDesktopConfig } from './useDesktopConfig'
3
-
4
- /** Readonly slice for an extension namespace (`fs`, `terminal`, or custom `configKey`). */
5
- export function useDesktopExtension<K extends string>(key: K) {
6
- const desktop = useDesktopConfig()
7
- return computed(() => desktop.value?.[key as keyof typeof desktop.value])
8
- }
@@ -1,51 +0,0 @@
1
- import { computed } from 'vue'
2
- import { useAppConfig } from 'nuxt/app'
3
- import { defu } from 'defu'
4
- import { useDesktopStore } from '../stores/storeDesktop'
5
- import { useDesktopDefaultAppsStore } from '../stores/storeDesktopDefaultApps'
6
-
7
- /**
8
- * Desktop Manager composable (singleton pattern via Pinia + app config).
9
- * Agnostic of any theme: merges runtime shell config and exposes default-app routing.
10
- */
11
- export function useDesktopManager() {
12
- const appConfig = useAppConfig()
13
- const desktopStore = useDesktopStore()
14
- const defaultAppsStore = useDesktopDefaultAppsStore()
15
-
16
- /**
17
- * Merges and sets the desktop config at runtime (shell geometry, feature flags, etc.).
18
- */
19
- function setConfig(newConfig: DesktopConfig) {
20
- if (!appConfig) return
21
-
22
- appConfig.desktop = defu(
23
- newConfig,
24
- (appConfig.desktop ?? {}) as DesktopConfig,
25
- ) as DesktopConfig
26
- }
27
-
28
- /** Map of feature name → default app handler (e.g. terminal, browser). */
29
- const defaultApps = computed(
30
- () => desktopStore.state.defaultApps,
31
- )
32
-
33
- function getDefaultApp(feature: string) {
34
- return defaultAppsStore.getDefaultApp(feature)
35
- }
36
-
37
- function setDefaultApp(
38
- feature: string,
39
- application: IApplicationController,
40
- entry: string,
41
- ) {
42
- defaultAppsStore.setDefaultApp(feature, application, entry)
43
- }
44
-
45
- return {
46
- setConfig,
47
- defaultApps,
48
- getDefaultApp,
49
- setDefaultApp,
50
- }
51
- }
@@ -1,17 +0,0 @@
1
- import { computed } from 'vue'
2
- import { useDesktopConfig } from './useDesktopConfig'
3
-
4
- export function hasDesktopModule(pkg: string) {
5
- const desktop = useDesktopConfig()
6
- return computed(() => desktop.value?.modules?.includes(pkg) ?? false)
7
- }
8
-
9
- export function hasDesktopApp(pkg: string) {
10
- const desktop = useDesktopConfig()
11
- return computed(() => desktop.value?.apps?.includes(pkg) ?? false)
12
- }
13
-
14
- export function hasDesktopExtension(key: string) {
15
- const desktop = useDesktopConfig()
16
- return computed(() => Boolean(desktop.value?.[key as keyof typeof desktop.value]))
17
- }
@@ -1,27 +0,0 @@
1
- import { useRouter } from 'nuxt/app'
2
- import { ref } from 'vue'
3
-
4
- /**
5
- * Neutral API for “leave the desktop shell” flows (shutdown animation → start route).
6
- * Themes keep their own `/start` / `/boot` pages and styling.
7
- */
8
- const shuttingDown = ref(false)
9
-
10
- export function useDesktopSession() {
11
- const initiateShutdownToStart = () => {
12
- shuttingDown.value = true
13
-
14
- setTimeout(() => {
15
- useRouter()
16
- .push('/start')
17
- .then(() => {
18
- shuttingDown.value = false
19
- })
20
- }, 2000)
21
- }
22
-
23
- return {
24
- shuttingDown,
25
- initiateShutdownToStart,
26
- }
27
- }
@@ -1,99 +0,0 @@
1
- import { computed, ref } from 'vue'
2
- import { useRuntimeConfig } from 'nuxt/app'
3
-
4
- export type ShellIdentity = {
5
- userId: string
6
- displayName: string
7
- avatarUrl: string | null
8
- userHome: string
9
- }
10
-
11
- const GUEST_USER_ID = 'guest'
12
-
13
- const identity = ref<ShellIdentity | null>(null)
14
-
15
- export function sanitizeUserHomeSegment(input: string): string {
16
- const cleaned = input
17
- .trim()
18
- .replace(/^@/, '')
19
- .replace(/[^\w.\-]/g, '_')
20
- .slice(0, 64)
21
- return cleaned || 'user'
22
- }
23
-
24
- /** Build a VFS home path from an auth handle (e.g. Bluesky `@alice.bsky.social`). */
25
- export function userHomeFromHandle(handle: string, base = '/home'): string {
26
- const baseNorm = base.endsWith('/') ? base.slice(0, -1) : base
27
- return `${baseNorm}/${sanitizeUserHomeSegment(handle)}`
28
- }
29
-
30
- function resolveDefaultHome(): string {
31
- try {
32
- const config = useRuntimeConfig()
33
- const desktop = config.public.desktop as {
34
- fs?: { defaultUserHome?: string }
35
- }
36
- const home = desktop.fs?.defaultUserHome?.trim()
37
- if (home) return home.startsWith('/') ? home : `/${home}`
38
- } catch {
39
- /* outside Nuxt setup */
40
- }
41
- return '/home/Guest'
42
- }
43
-
44
- function guestIdentity(defaultHome: string): ShellIdentity {
45
- return {
46
- userId: GUEST_USER_ID,
47
- displayName: 'Guest',
48
- avatarUrl: null,
49
- userHome: defaultHome,
50
- }
51
- }
52
-
53
- /**
54
- * Shell session identity (display + VFS home). Auth modules call {@link setShellIdentity}
55
- * after login; defaults to Guest.
56
- */
57
- export function useDesktopShellIdentity() {
58
- function ensureIdentity(): ShellIdentity {
59
- if (!identity.value) {
60
- identity.value = guestIdentity(resolveDefaultHome())
61
- }
62
- return identity.value
63
- }
64
-
65
- const userId = computed(() => ensureIdentity().userId)
66
- const displayName = computed(() => ensureIdentity().displayName)
67
- const avatarUrl = computed(() => ensureIdentity().avatarUrl)
68
- const userHome = computed(() => ensureIdentity().userHome)
69
- const isGuest = computed(() => userId.value === GUEST_USER_ID)
70
-
71
- function setShellIdentity(partial: Partial<ShellIdentity>) {
72
- const current = ensureIdentity()
73
- identity.value = {
74
- ...current,
75
- ...partial,
76
- userId: partial.userId?.trim() || current.userId,
77
- displayName: partial.displayName?.trim() || current.displayName,
78
- userHome: partial.userHome?.trim()
79
- ? partial.userHome.startsWith('/')
80
- ? partial.userHome
81
- : `/${partial.userHome}`
82
- : current.userHome,
83
- }
84
- }
85
-
86
- function clearShellIdentity() {
87
- identity.value = guestIdentity(resolveDefaultHome())
88
- }
89
-
90
- return {
91
- userId,
92
- displayName,
93
- avatarUrl,
94
- userHome,
95
- isGuest,
96
- setShellIdentity,
97
- clearShellIdentity,
98
- }
99
- }
@@ -1,36 +0,0 @@
1
- import { useAppConfig } from 'nuxt/app'
2
- import { computed } from 'vue'
3
-
4
- /**
5
- * Reads shared desktop shell flags from `appConfig.desktop` (merged from runtime config).
6
- * Themes use this for taskbar/dock visibility without duplicating `useAppConfig` wiring.
7
- */
8
- type DesktopAppShape = {
9
- systemBar?: {
10
- enabled?: boolean
11
- position?: string
12
- startButton?: boolean
13
- }
14
- }
15
-
16
- export function useDesktopShellOptions() {
17
- const appConfig = useAppConfig()
18
-
19
- const desktop = () => appConfig.desktop as DesktopAppShape | undefined
20
-
21
- const systemBarEnabled = computed(
22
- () => desktop()?.systemBar?.enabled !== false,
23
- )
24
-
25
- const systemBarPosition = computed(() => desktop()?.systemBar?.position)
26
-
27
- const startButtonEnabled = computed(
28
- () => desktop()?.systemBar?.startButton !== false,
29
- )
30
-
31
- return {
32
- systemBarEnabled,
33
- systemBarPosition,
34
- startButtonEnabled,
35
- }
36
- }
@@ -1,7 +0,0 @@
1
- import { useNuxtApp } from 'nuxt/app'
2
-
3
- /** True after `desktop-shell-init` has bound Pinia and run kernel workspace bootstrap. */
4
- export function useDesktopShellReady() {
5
- const nuxtApp = useNuxtApp()
6
- return nuxtApp.$desktopShellReady === true
7
- }
@@ -1,93 +0,0 @@
1
- import type { Ref } from 'vue'
2
- import { onScopeDispose, watch } from 'vue'
3
- import {
4
- EMPTY_DESKTOP_WORK_AREA,
5
- useDesktopWindowStore,
6
- } from '@owdproject/core/runtime/stores/storeDesktopWindow'
7
- import { useDesktopWorkspaceStore } from '@owdproject/core/runtime/stores/storeDesktopWorkspace'
8
-
9
- function measureElement(el: HTMLElement) {
10
- const rect = el.getBoundingClientRect()
11
- return {
12
- x: rect.left,
13
- y: rect.top,
14
- width: rect.width,
15
- height: rect.height,
16
- }
17
- }
18
-
19
- /**
20
- * Tracks the desktop shell stage rectangle (area under system bar, above dock).
21
- * Writes measured bounds to {@link useDesktopWindowStore.workArea}.
22
- * Pass the same ref themes use for workspace overview live scale.
23
- */
24
- export function useDesktopWorkArea(
25
- shellStageRef: Ref<HTMLElement | null | undefined>,
26
- ) {
27
- const desktopWindowStore = useDesktopWindowStore()
28
- const desktopWorkspaceStore = useDesktopWorkspaceStore()
29
-
30
- let resizeObserver: ResizeObserver | null = null
31
-
32
- function refreshWorkArea() {
33
- const el = shellStageRef.value
34
- if (!el) {
35
- desktopWindowStore.setWorkArea({ ...EMPTY_DESKTOP_WORK_AREA })
36
- return
37
- }
38
- desktopWindowStore.setWorkArea(measureElement(el))
39
- }
40
-
41
- function disconnectObserver() {
42
- resizeObserver?.disconnect()
43
- resizeObserver = null
44
- }
45
-
46
- function observeStage(el: HTMLElement) {
47
- disconnectObserver()
48
- refreshWorkArea()
49
-
50
- if (typeof ResizeObserver === 'undefined') {
51
- return
52
- }
53
-
54
- resizeObserver = new ResizeObserver(() => refreshWorkArea())
55
- resizeObserver.observe(el)
56
- }
57
-
58
- watch(
59
- shellStageRef,
60
- (el) => {
61
- disconnectObserver()
62
- if (el instanceof HTMLElement) {
63
- observeStage(el)
64
- } else {
65
- desktopWindowStore.setWorkArea({ ...EMPTY_DESKTOP_WORK_AREA })
66
- }
67
- },
68
- { immediate: true },
69
- )
70
-
71
- watch(
72
- () => desktopWorkspaceStore.overview,
73
- (open) => {
74
- if (!open) {
75
- refreshWorkArea()
76
- }
77
- },
78
- )
79
-
80
- if (typeof globalThis !== 'undefined') {
81
- globalThis.addEventListener('resize', refreshWorkArea)
82
- onScopeDispose(() => {
83
- globalThis.removeEventListener('resize', refreshWorkArea)
84
- disconnectObserver()
85
- })
86
- } else {
87
- onScopeDispose(disconnectObserver)
88
- }
89
-
90
- return {
91
- refreshWorkArea,
92
- }
93
- }