ywana-core8 0.2.6 → 0.2.8
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.
- package/dist/index.css +452 -54
- package/dist/index.js +267 -89
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +267 -89
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +267 -89
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/desktop/ApplicationMenu.css +153 -54
- package/src/desktop/ApplicationMenu.js +75 -69
- package/src/desktop/Desktop.stories.jsx +87 -12
- package/src/desktop/WindowContext.js +3 -0
- package/src/desktop/WindowManager.js +32 -10
- package/src/desktop/desktop-linux.css +55 -0
- package/src/desktop/desktop-macos.css +57 -0
- package/src/desktop/desktop-windows.css +54 -0
- package/src/desktop/desktop.css +30 -0
- package/src/desktop/desktop.js +100 -66
- package/src/desktop/window.css +98 -0
- package/src/desktop/window.js +163 -2
- package/src/html/button.css +5 -0
- package/src/html/button.js +2 -1
@@ -6,6 +6,7 @@ export class WindowManager {
|
|
6
6
|
this.windows = new Map()
|
7
7
|
this.activeWindowId = null
|
8
8
|
this.nextZIndex = 1000
|
9
|
+
this.maxZIndex = 9999 // Maximum z-index for windows (ApplicationMenu is 10000)
|
9
10
|
this.listeners = new Set()
|
10
11
|
this.desktopSize = desktopSize
|
11
12
|
}
|
@@ -77,7 +78,7 @@ export class WindowManager {
|
|
77
78
|
size: size,
|
78
79
|
minimized: false,
|
79
80
|
maximized: false,
|
80
|
-
zIndex: this.nextZIndex++,
|
81
|
+
zIndex: Math.min(this.nextZIndex++, this.maxZIndex),
|
81
82
|
...config
|
82
83
|
}
|
83
84
|
|
@@ -101,9 +102,9 @@ export class WindowManager {
|
|
101
102
|
let x = baseX + (existingWindows.length * offsetStep)
|
102
103
|
let y = baseY + (existingWindows.length * offsetStep)
|
103
104
|
|
104
|
-
// Check if it goes out of
|
105
|
+
// Check if it goes out of workspace bounds
|
105
106
|
const maxX = this.desktopSize.width - windowSize.width - 20
|
106
|
-
const maxY = this.desktopSize.height - windowSize.height -
|
107
|
+
const maxY = this.desktopSize.height - windowSize.height - 20 // Workspace boundaries
|
107
108
|
|
108
109
|
// If out of bounds, restart cascade
|
109
110
|
if (x > maxX || y > maxY) {
|
@@ -152,8 +153,11 @@ export class WindowManager {
|
|
152
153
|
window.minimized = false
|
153
154
|
}
|
154
155
|
|
155
|
-
// Bring to front
|
156
|
-
|
156
|
+
// Bring to front (but never above ApplicationMenu)
|
157
|
+
if (this.nextZIndex >= this.maxZIndex) {
|
158
|
+
this.resetZIndexes()
|
159
|
+
}
|
160
|
+
window.zIndex = Math.min(this.nextZIndex++, this.maxZIndex)
|
157
161
|
this.activeWindowId = windowId
|
158
162
|
|
159
163
|
this.notifyListeners()
|
@@ -221,7 +225,7 @@ export class WindowManager {
|
|
221
225
|
const minWidth = 200
|
222
226
|
const minHeight = 150
|
223
227
|
const maxWidth = this.desktopSize.width
|
224
|
-
const maxHeight = this.desktopSize.height
|
228
|
+
const maxHeight = this.desktopSize.height // Workspace boundaries
|
225
229
|
|
226
230
|
const constrainedSize = {
|
227
231
|
width: Math.max(minWidth, Math.min(size.width || window.size.width, maxWidth)),
|
@@ -264,7 +268,7 @@ export class WindowManager {
|
|
264
268
|
if (window.maximized) return // Maximized windows don't need repositioning
|
265
269
|
|
266
270
|
const maxX = this.desktopSize.width - window.size.width
|
267
|
-
const maxY = this.desktopSize.height - window.size.height
|
271
|
+
const maxY = this.desktopSize.height - window.size.height // Workspace boundaries
|
268
272
|
|
269
273
|
// Adjust position if out of bounds
|
270
274
|
if (window.position.x > maxX) {
|
@@ -306,7 +310,7 @@ export class WindowManager {
|
|
306
310
|
const cols = Math.ceil(Math.sqrt(visibleWindows.length))
|
307
311
|
const rows = Math.ceil(visibleWindows.length / cols)
|
308
312
|
const windowWidth = Math.floor(this.desktopSize.width / cols)
|
309
|
-
const windowHeight = Math.floor(
|
313
|
+
const windowHeight = Math.floor(this.desktopSize.height / rows) // Workspace boundaries
|
310
314
|
|
311
315
|
visibleWindows.forEach((window, index) => {
|
312
316
|
const col = index % cols
|
@@ -335,7 +339,7 @@ export class WindowManager {
|
|
335
339
|
|
336
340
|
window.position = {
|
337
341
|
x: (this.desktopSize.width - window.size.width) / 2,
|
338
|
-
y: (this.desktopSize.height - window.size.height
|
342
|
+
y: (this.desktopSize.height - window.size.height) / 2 // Workspace center
|
339
343
|
}
|
340
344
|
|
341
345
|
this.notifyListeners()
|
@@ -351,7 +355,7 @@ export class WindowManager {
|
|
351
355
|
|
352
356
|
visibleWindows.forEach((window, index) => {
|
353
357
|
const baseX = (this.desktopSize.width - window.size.width) / 2
|
354
|
-
const baseY = (this.desktopSize.height - window.size.height
|
358
|
+
const baseY = (this.desktopSize.height - window.size.height) / 2
|
355
359
|
|
356
360
|
window.position = {
|
357
361
|
x: baseX + (index * offsetStep),
|
@@ -375,4 +379,22 @@ export class WindowManager {
|
|
375
379
|
desktopSize: this.desktopSize
|
376
380
|
}
|
377
381
|
}
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Reset z-indexes when they reach the maximum
|
385
|
+
*/
|
386
|
+
resetZIndexes() {
|
387
|
+
const windows = Array.from(this.windows.values())
|
388
|
+
// Sort windows by current z-index
|
389
|
+
windows.sort((a, b) => a.zIndex - b.zIndex)
|
390
|
+
|
391
|
+
// Reassign z-indexes starting from 1000
|
392
|
+
this.nextZIndex = 1000
|
393
|
+
windows.forEach((window, index) => {
|
394
|
+
window.zIndex = this.nextZIndex + index
|
395
|
+
})
|
396
|
+
this.nextZIndex = 1000 + windows.length
|
397
|
+
|
398
|
+
this.notifyListeners()
|
399
|
+
}
|
378
400
|
}
|
@@ -114,6 +114,61 @@
|
|
114
114
|
border-color: rgba(53, 132, 228, 0.5);
|
115
115
|
}
|
116
116
|
|
117
|
+
/* Linux Start Button Styling (GNOME Activities) */
|
118
|
+
.desktop--linux .toggle-button {
|
119
|
+
/* Reset selector styles and apply Linux button styling */
|
120
|
+
position: relative;
|
121
|
+
padding: 8px 16px;
|
122
|
+
display: flex;
|
123
|
+
align-items: center;
|
124
|
+
justify-content: center;
|
125
|
+
gap: 8px;
|
126
|
+
overflow: hidden;
|
127
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
128
|
+
outline: none;
|
129
|
+
transition: all 0.3s ease;
|
130
|
+
color: #ffffff;
|
131
|
+
background: linear-gradient(180deg, rgba(53, 132, 228, 0.9) 0%, rgba(26, 95, 180, 0.9) 100%);
|
132
|
+
min-height: 40px;
|
133
|
+
border-radius: 8px;
|
134
|
+
cursor: pointer;
|
135
|
+
font-family: 'Ubuntu', 'Cantarell', sans-serif;
|
136
|
+
font-weight: 500;
|
137
|
+
text-decoration: none;
|
138
|
+
white-space: nowrap;
|
139
|
+
list-style: none;
|
140
|
+
margin: 0;
|
141
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
142
|
+
}
|
143
|
+
|
144
|
+
.desktop--linux .toggle-button:hover:not(.toggle-button--disabled) {
|
145
|
+
background: linear-gradient(180deg, rgba(53, 132, 228, 1) 0%, rgba(26, 95, 180, 1) 100%);
|
146
|
+
border-color: rgba(255, 255, 255, 0.25);
|
147
|
+
transform: translateY(-1px);
|
148
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);
|
149
|
+
}
|
150
|
+
|
151
|
+
.desktop--linux .toggle-button.selected {
|
152
|
+
background: linear-gradient(180deg, rgba(26, 95, 180, 0.9) 0%, rgba(15, 70, 140, 0.9) 100%);
|
153
|
+
color: #ffffff;
|
154
|
+
border-color: rgba(255, 255, 255, 0.3);
|
155
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(53, 132, 228, 0.4);
|
156
|
+
}
|
157
|
+
|
158
|
+
.desktop--linux .toggle-button:focus {
|
159
|
+
outline: 2px solid rgba(53, 132, 228, 0.6);
|
160
|
+
outline-offset: 2px;
|
161
|
+
}
|
162
|
+
|
163
|
+
.desktop--linux .toggle-button--disabled {
|
164
|
+
background: rgba(255, 255, 255, 0.1) !important;
|
165
|
+
color: rgba(255, 255, 255, 0.4) !important;
|
166
|
+
border-color: rgba(255, 255, 255, 0.05) !important;
|
167
|
+
cursor: not-allowed;
|
168
|
+
opacity: 1;
|
169
|
+
box-shadow: none;
|
170
|
+
}
|
171
|
+
|
117
172
|
/* Linux Application Menu (Activities Overview) */
|
118
173
|
.desktop--linux .application-menu {
|
119
174
|
background: rgba(36, 31, 49, 0.95);
|
@@ -137,6 +137,63 @@
|
|
137
137
|
color: #007aff;
|
138
138
|
}
|
139
139
|
|
140
|
+
/* macOS Start Button Styling (Dock-inspired) */
|
141
|
+
.desktop--macos .toggle-button {
|
142
|
+
/* Reset selector styles and apply macOS button styling */
|
143
|
+
position: relative;
|
144
|
+
padding: 8px 16px;
|
145
|
+
display: flex;
|
146
|
+
align-items: center;
|
147
|
+
justify-content: center;
|
148
|
+
gap: 8px;
|
149
|
+
overflow: hidden;
|
150
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
151
|
+
outline: none;
|
152
|
+
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
153
|
+
color: #1d1d1f;
|
154
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 248, 248, 0.9) 100%);
|
155
|
+
min-height: 40px;
|
156
|
+
border-radius: 12px;
|
157
|
+
cursor: pointer;
|
158
|
+
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', sans-serif;
|
159
|
+
font-weight: 500;
|
160
|
+
text-decoration: none;
|
161
|
+
white-space: nowrap;
|
162
|
+
list-style: none;
|
163
|
+
margin: 0;
|
164
|
+
backdrop-filter: blur(20px);
|
165
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
166
|
+
}
|
167
|
+
|
168
|
+
.desktop--macos .toggle-button:hover:not(.toggle-button--disabled) {
|
169
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(245, 245, 245, 0.95) 100%);
|
170
|
+
border-color: rgba(0, 0, 0, 0.15);
|
171
|
+
transform: translateY(-1px);
|
172
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
173
|
+
}
|
174
|
+
|
175
|
+
.desktop--macos .toggle-button.selected {
|
176
|
+
background: linear-gradient(180deg, rgba(0, 122, 255, 0.9) 0%, rgba(0, 100, 210, 0.9) 100%);
|
177
|
+
color: white;
|
178
|
+
border-color: rgba(0, 122, 255, 0.3);
|
179
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 122, 255, 0.3);
|
180
|
+
}
|
181
|
+
|
182
|
+
.desktop--macos .toggle-button:focus {
|
183
|
+
outline: 2px solid rgba(0, 122, 255, 0.5);
|
184
|
+
outline-offset: 2px;
|
185
|
+
}
|
186
|
+
|
187
|
+
.desktop--macos .toggle-button--disabled {
|
188
|
+
background: rgba(248, 248, 248, 0.5) !important;
|
189
|
+
color: rgba(60, 60, 67, 0.3) !important;
|
190
|
+
border-color: rgba(0, 0, 0, 0.05) !important;
|
191
|
+
cursor: not-allowed;
|
192
|
+
opacity: 1;
|
193
|
+
box-shadow: none;
|
194
|
+
backdrop-filter: none;
|
195
|
+
}
|
196
|
+
|
140
197
|
/* macOS Application Menu (Launchpad-inspired) */
|
141
198
|
.desktop--macos .application-menu {
|
142
199
|
background: rgba(255, 255, 255, 0.9);
|
@@ -104,6 +104,60 @@
|
|
104
104
|
border-color: rgba(255, 255, 255, 0.4);
|
105
105
|
}
|
106
106
|
|
107
|
+
/* Windows Start Button Styling */
|
108
|
+
.desktop--windows .toggle-button {
|
109
|
+
/* Reset selector styles and apply Windows button styling */
|
110
|
+
position: relative;
|
111
|
+
padding: 8px 16px;
|
112
|
+
display: flex;
|
113
|
+
align-items: center;
|
114
|
+
justify-content: center;
|
115
|
+
gap: 8px;
|
116
|
+
overflow: hidden;
|
117
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
118
|
+
outline: none;
|
119
|
+
transition: all 0.2s ease;
|
120
|
+
color: white;
|
121
|
+
background: linear-gradient(180deg, #0078d4 0%, #106ebe 100%);
|
122
|
+
min-height: 40px;
|
123
|
+
border-radius: 4px;
|
124
|
+
cursor: pointer;
|
125
|
+
font-family: 'Segoe UI', sans-serif;
|
126
|
+
font-weight: 500;
|
127
|
+
text-decoration: none;
|
128
|
+
white-space: nowrap;
|
129
|
+
list-style: none;
|
130
|
+
margin: 0;
|
131
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
132
|
+
}
|
133
|
+
|
134
|
+
.desktop--windows .toggle-button:hover:not(.toggle-button--disabled) {
|
135
|
+
background: linear-gradient(180deg, #106ebe 0%, #005a9e 100%);
|
136
|
+
border-color: rgba(255, 255, 255, 0.3);
|
137
|
+
transform: none;
|
138
|
+
}
|
139
|
+
|
140
|
+
.desktop--windows .toggle-button.selected {
|
141
|
+
background: linear-gradient(180deg, #005a9e 0%, #004578 100%);
|
142
|
+
color: white;
|
143
|
+
border-color: rgba(255, 255, 255, 0.4);
|
144
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
|
145
|
+
}
|
146
|
+
|
147
|
+
.desktop--windows .toggle-button:focus {
|
148
|
+
outline: 2px solid rgba(255, 255, 255, 0.5);
|
149
|
+
outline-offset: 2px;
|
150
|
+
}
|
151
|
+
|
152
|
+
.desktop--windows .toggle-button--disabled {
|
153
|
+
background: rgba(200, 200, 200, 0.3) !important;
|
154
|
+
color: rgba(100, 100, 100, 0.5) !important;
|
155
|
+
border-color: rgba(255, 255, 255, 0.1) !important;
|
156
|
+
cursor: not-allowed;
|
157
|
+
opacity: 1;
|
158
|
+
box-shadow: none;
|
159
|
+
}
|
160
|
+
|
107
161
|
/* Windows Application Menu */
|
108
162
|
.desktop--windows .application-menu {
|
109
163
|
background: rgba(248, 248, 248, 0.95);
|
package/src/desktop/desktop.css
CHANGED
@@ -24,8 +24,38 @@
|
|
24
24
|
width: 100%;
|
25
25
|
height: 100%;
|
26
26
|
z-index: 1;
|
27
|
+
display: flex;
|
28
|
+
flex-direction: column;
|
27
29
|
}
|
28
30
|
|
31
|
+
/* Workspace container - takes available space above taskbar */
|
32
|
+
.desktop__workspace-container {
|
33
|
+
position: relative;
|
34
|
+
flex: 1;
|
35
|
+
overflow: hidden;
|
36
|
+
z-index: 1;
|
37
|
+
}
|
38
|
+
|
39
|
+
/* Workspace - container for windows with boundaries */
|
40
|
+
.workspace {
|
41
|
+
position: relative;
|
42
|
+
width: 100%;
|
43
|
+
height: 100%;
|
44
|
+
overflow: hidden;
|
45
|
+
}
|
46
|
+
|
47
|
+
.desktop-taskbar {
|
48
|
+
|
49
|
+
& .icon {
|
50
|
+
color: white;
|
51
|
+
& :hover {
|
52
|
+
color: #fff;
|
53
|
+
background-color: rgba(255, 255, 255, 0.1);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
29
59
|
/* Desktop variants */
|
30
60
|
.desktop--dark {
|
31
61
|
color: white;
|
package/src/desktop/desktop.js
CHANGED
@@ -3,6 +3,8 @@ import { WindowProvider, useWindows } from './WindowContext'
|
|
3
3
|
import { Window } from './window'
|
4
4
|
import { ApplicationMenu } from './ApplicationMenu'
|
5
5
|
import { defaultAppManager } from './AppManager'
|
6
|
+
import { ToggleButton } from '../html/selector'
|
7
|
+
import { Icon } from '../html/icon'
|
6
8
|
import './desktop.css'
|
7
9
|
import './desktop-windows.css'
|
8
10
|
import './desktop-linux.css'
|
@@ -57,17 +59,17 @@ export const AppProvider = ({ children, appManager = defaultAppManager }) => {
|
|
57
59
|
/**
|
58
60
|
* Desktop layout component - manages overall desktop structure and sizing
|
59
61
|
*/
|
60
|
-
const DesktopLayout = ({ children, className = '', theme = 'windows', ...props }) => {
|
62
|
+
const DesktopLayout = ({ children, className = '', theme = 'windows', workspaceRef, ...props }) => {
|
61
63
|
const desktopRef = useRef(null)
|
62
64
|
const { windowManager } = useWindows()
|
63
65
|
|
64
|
-
// Measure
|
66
|
+
// Measure workspace size on mount and resize
|
65
67
|
useEffect(() => {
|
66
|
-
let currentSize = { width: 1200, height:
|
68
|
+
let currentSize = { width: 1200, height: 750 } // Default workspace size (desktop - taskbar)
|
67
69
|
|
68
|
-
const
|
69
|
-
if (
|
70
|
-
const rect =
|
70
|
+
const measureWorkspace = () => {
|
71
|
+
if (workspaceRef.current) {
|
72
|
+
const rect = workspaceRef.current.getBoundingClientRect()
|
71
73
|
const newSize = {
|
72
74
|
width: rect.width,
|
73
75
|
height: rect.height
|
@@ -82,12 +84,12 @@ const DesktopLayout = ({ children, className = '', theme = 'windows', ...props }
|
|
82
84
|
}
|
83
85
|
|
84
86
|
// Initial measurement
|
85
|
-
|
87
|
+
measureWorkspace()
|
86
88
|
|
87
89
|
// Listen for resize
|
88
|
-
const resizeObserver = new ResizeObserver(
|
89
|
-
if (
|
90
|
-
resizeObserver.observe(
|
90
|
+
const resizeObserver = new ResizeObserver(measureWorkspace)
|
91
|
+
if (workspaceRef.current) {
|
92
|
+
resizeObserver.observe(workspaceRef.current)
|
91
93
|
}
|
92
94
|
|
93
95
|
return () => {
|
@@ -124,13 +126,13 @@ const DesktopLayout = ({ children, className = '', theme = 'windows', ...props }
|
|
124
126
|
}
|
125
127
|
|
126
128
|
/**
|
127
|
-
* Workspace -
|
129
|
+
* Workspace - container for windows with proper boundaries
|
128
130
|
*/
|
129
131
|
export const Workspace = ({ children }) => {
|
130
132
|
const { windows } = useWindows()
|
131
133
|
|
132
134
|
return (
|
133
|
-
|
135
|
+
<div className="workspace">
|
134
136
|
{children}
|
135
137
|
|
136
138
|
{/* Render windows using Window component */}
|
@@ -148,7 +150,7 @@ export const Workspace = ({ children }) => {
|
|
148
150
|
</div>
|
149
151
|
</Window>
|
150
152
|
))}
|
151
|
-
|
153
|
+
</div>
|
152
154
|
)
|
153
155
|
}
|
154
156
|
|
@@ -156,6 +158,11 @@ export const Workspace = ({ children }) => {
|
|
156
158
|
* DesktopTaskbar - handles window creation and management
|
157
159
|
*/
|
158
160
|
export const DesktopTaskbar = () => {
|
161
|
+
console.log('DesktopTaskbar render')
|
162
|
+
|
163
|
+
const windowsContext = useWindows()
|
164
|
+
console.log('useWindows result:', windowsContext)
|
165
|
+
|
159
166
|
const {
|
160
167
|
createWindow,
|
161
168
|
windows,
|
@@ -163,12 +170,20 @@ export const DesktopTaskbar = () => {
|
|
163
170
|
activeWindowId,
|
164
171
|
focusWindow,
|
165
172
|
minimizeWindow,
|
166
|
-
closeWindow
|
167
|
-
|
173
|
+
closeWindow,
|
174
|
+
cascadeWindows,
|
175
|
+
tileWindows,
|
176
|
+
centerAllWindows,
|
177
|
+
clearAllWindows
|
178
|
+
} = windowsContext
|
168
179
|
|
169
|
-
const {
|
180
|
+
const { isOpen, toggle } = useApplicationMenu()
|
181
|
+
console.log('DesktopTaskbar - isOpen:', isOpen, 'toggle:', toggle)
|
170
182
|
|
171
183
|
const handleCreateWindow = () => {
|
184
|
+
console.log('handleCreateWindow called!')
|
185
|
+
console.log('createWindow function:', createWindow)
|
186
|
+
|
172
187
|
const windowTypes = [
|
173
188
|
{ title: 'File Explorer', icon: '📁', size: { width: 600, height: 400 } },
|
174
189
|
{ title: 'Text Editor', icon: '📝', size: { width: 500, height: 350 } },
|
@@ -178,6 +193,7 @@ export const DesktopTaskbar = () => {
|
|
178
193
|
]
|
179
194
|
|
180
195
|
const randomType = windowTypes[Math.floor(Math.random() * windowTypes.length)]
|
196
|
+
console.log('Creating window:', randomType)
|
181
197
|
|
182
198
|
createWindow({
|
183
199
|
title: randomType.title,
|
@@ -226,11 +242,7 @@ export const DesktopTaskbar = () => {
|
|
226
242
|
}
|
227
243
|
|
228
244
|
return (
|
229
|
-
<div style={{
|
230
|
-
position: 'absolute',
|
231
|
-
bottom: 0,
|
232
|
-
left: 0,
|
233
|
-
right: 0,
|
245
|
+
<div className='desktop-taskbar' style={{
|
234
246
|
height: '50px',
|
235
247
|
background: 'rgba(0,0,0,0.8)',
|
236
248
|
display: 'flex',
|
@@ -239,45 +251,16 @@ export const DesktopTaskbar = () => {
|
|
239
251
|
gap: '8px'
|
240
252
|
}}>
|
241
253
|
{/* Start button */}
|
242
|
-
<
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
color: 'white',
|
248
|
-
border: 'none',
|
249
|
-
borderRadius: '4px',
|
250
|
-
cursor: 'pointer',
|
251
|
-
fontSize: '14px',
|
252
|
-
fontWeight: 'bold',
|
253
|
-
flexShrink: 0,
|
254
|
-
display: 'flex',
|
255
|
-
alignItems: 'center',
|
256
|
-
gap: '6px'
|
254
|
+
<ToggleButton
|
255
|
+
checked={isOpen}
|
256
|
+
onToggle={() => {
|
257
|
+
console.log('Start button toggled, current state:', isOpen)
|
258
|
+
toggle()
|
257
259
|
}}
|
258
|
-
|
260
|
+
icon="start"
|
261
|
+
label="Start"
|
259
262
|
>
|
260
|
-
|
261
|
-
Start
|
262
|
-
</button>
|
263
|
-
|
264
|
-
{/* Create window button (for testing) */}
|
265
|
-
<button
|
266
|
-
onClick={handleCreateWindow}
|
267
|
-
style={{
|
268
|
-
padding: '8px 12px',
|
269
|
-
background: '#666',
|
270
|
-
color: 'white',
|
271
|
-
border: 'none',
|
272
|
-
borderRadius: '4px',
|
273
|
-
cursor: 'pointer',
|
274
|
-
fontSize: '12px',
|
275
|
-
flexShrink: 0
|
276
|
-
}}
|
277
|
-
title="Create random window (for testing)"
|
278
|
-
>
|
279
|
-
+
|
280
|
-
</button>
|
263
|
+
</ToggleButton>
|
281
264
|
|
282
265
|
{/* Separator */}
|
283
266
|
<div style={{
|
@@ -356,6 +339,49 @@ export const DesktopTaskbar = () => {
|
|
356
339
|
))}
|
357
340
|
</div>
|
358
341
|
|
342
|
+
{/* Window Layout Controls */}
|
343
|
+
<div style={{
|
344
|
+
display: 'flex',
|
345
|
+
gap: '4px',
|
346
|
+
alignItems: 'center',
|
347
|
+
marginLeft: 'auto',
|
348
|
+
marginRight: '8px'
|
349
|
+
}}>
|
350
|
+
|
351
|
+
<Icon clickable size="small"
|
352
|
+
action={() => {
|
353
|
+
console.log('Cascade windows clicked!')
|
354
|
+
cascadeWindows()
|
355
|
+
}}
|
356
|
+
icon="view_stream"
|
357
|
+
label="Cascade"
|
358
|
+
/>
|
359
|
+
<Icon clickable size="small"
|
360
|
+
action={() => {
|
361
|
+
console.log('Tile windows clicked!')
|
362
|
+
tileWindows()
|
363
|
+
}}
|
364
|
+
icon="view_module"
|
365
|
+
label="Tile"
|
366
|
+
/>
|
367
|
+
<Icon clickable size="small"
|
368
|
+
action={() => {
|
369
|
+
console.log('Center all windows clicked!')
|
370
|
+
centerAllWindows()
|
371
|
+
}}
|
372
|
+
icon="center_focus_strong"
|
373
|
+
label="Center"
|
374
|
+
/>
|
375
|
+
<Icon clickable size="small"
|
376
|
+
action={() => {
|
377
|
+
console.log('Clear all windows clicked!')
|
378
|
+
clearAllWindows()
|
379
|
+
}}
|
380
|
+
icon="clear_all"
|
381
|
+
label="Clear"
|
382
|
+
/>
|
383
|
+
</div>
|
384
|
+
|
359
385
|
{/* Debug info */}
|
360
386
|
<div style={{
|
361
387
|
color: 'rgba(255,255,255,0.7)',
|
@@ -375,18 +401,26 @@ export const DesktopTaskbar = () => {
|
|
375
401
|
*/
|
376
402
|
const DesktopInternal = ({ desktopSize, children, ...props }) => {
|
377
403
|
const { isOpen, close } = useApplicationMenu()
|
404
|
+
const workspaceRef = useRef(null)
|
378
405
|
|
379
406
|
return (
|
380
407
|
<WindowProvider desktopSize={desktopSize}>
|
381
|
-
<DesktopLayout {...props}>
|
382
|
-
|
383
|
-
|
384
|
-
|
408
|
+
<DesktopLayout workspaceRef={workspaceRef} {...props}>
|
409
|
+
{/* Workspace container - has its own boundaries */}
|
410
|
+
<div ref={workspaceRef} className="desktop__workspace-container">
|
411
|
+
<Workspace>
|
412
|
+
{children}
|
413
|
+
</Workspace>
|
414
|
+
|
415
|
+
{/* ApplicationMenu positioned over workspace */}
|
416
|
+
<ApplicationMenu
|
417
|
+
isOpen={isOpen}
|
418
|
+
onClose={close}
|
419
|
+
/>
|
420
|
+
</div>
|
421
|
+
|
422
|
+
{/* Taskbar at bottom - separate from workspace */}
|
385
423
|
<DesktopTaskbar />
|
386
|
-
<ApplicationMenu
|
387
|
-
isOpen={isOpen}
|
388
|
-
onClose={close}
|
389
|
-
/>
|
390
424
|
</DesktopLayout>
|
391
425
|
</WindowProvider>
|
392
426
|
)
|