Spaces:
Running
Running
| // Window management | |
| let activeWindow = null; | |
| let windowZIndex = 100; | |
| let minimizedWindows = []; | |
| document.addEventListener('DOMContentLoaded', () => { | |
| initializeDesktop(); | |
| initializeContextMenus(); | |
| initializeKeyboardShortcuts(); | |
| // Initialize windows with proper styles | |
| document.querySelectorAll('app-window').forEach(window => { | |
| const width = window.getAttribute('width'); | |
| const height = window.getAttribute('height'); | |
| const x = window.getAttribute('x'); | |
| const y = window.getAttribute('y'); | |
| if (width) window.style.width = `${width}px`; | |
| if (height) window.style.height = `${height}px`; | |
| if (x) window.style.left = `${x}px`; | |
| if (y) window.style.top = `${y}px`; | |
| }); | |
| }); | |
| function initializeDesktop() { | |
| const desktop = document.getElementById('desktop'); | |
| // Prevent text selection on desktop | |
| desktop.addEventListener('selectstart', (e) => { | |
| if (e.target === desktop || e.target.classList.contains('desktop-icon')) { | |
| e.preventDefault(); | |
| } | |
| }); | |
| } | |
| function initializeContextMenus() { | |
| const contextMenu = document.getElementById('context-menu'); | |
| const desktop = document.getElementById('desktop'); | |
| desktop.addEventListener('contextmenu', (e) => { | |
| e.preventDefault(); | |
| if (!e.target.closest('app-window')) { | |
| contextMenu.style.left = `${e.clientX}px`; | |
| contextMenu.style.top = `${e.clientY}px`; | |
| contextMenu.classList.remove('hidden'); | |
| contextMenu.classList.add('menu-enter'); | |
| // Adjust position if menu goes off screen | |
| setTimeout(() => { | |
| const rect = contextMenu.getBoundingClientRect(); | |
| if (rect.right > window.innerWidth) { | |
| contextMenu.style.left = `${window.innerWidth - rect.width - 5}px`; | |
| } | |
| if (rect.bottom > window.innerHeight) { | |
| contextMenu.style.top = `${window.innerHeight - rect.height - 5}px`; | |
| } | |
| }, 0); | |
| } | |
| }); | |
| document.addEventListener('click', (e) => { | |
| if (!contextMenu.contains(e.target)) { | |
| contextMenu.classList.add('hidden'); | |
| } | |
| }); | |
| } | |
| function initializeKeyboardShortcuts() { | |
| document.addEventListener('keydown', (e) => { | |
| // Alt + F4: Close active window | |
| if (e.altKey && e.key === 'F4' && activeWindow) { | |
| closeWindow(activeWindow.id); | |
| } | |
| // Super (Meta) + D: Show desktop | |
| if (e.metaKey && e.key === 'd') { | |
| toggleDesktop(); | |
| } | |
| // Ctrl + Alt + T: Open terminal | |
| if (e.ctrlKey && e.altKey && e.key === 't') { | |
| createNewWindow('Terminal', 'terminal', 600, 400, getTerminalContent()); | |
| } | |
| }); | |
| } | |
| function toggleDesktop() { | |
| const windows = document.querySelectorAll('app-window'); | |
| windows.forEach(window => { | |
| if (window.style.display !== 'none') { | |
| window.style.display = window.style.display === 'none' ? 'block' : 'none'; | |
| } | |
| }); | |
| } | |
| function getTerminalContent() { | |
| return `<div class="bg-black h-full p-4 font-mono text-sm text-green-400 overflow-auto"> | |
| <div>mate@mate-desktop:~$ _</div> | |
| </div>`; | |
| } | |
| function createNewWindow(title, icon, width, height, content, x = null, y = null) { | |
| const windowId = `window-${Date.now()}`; | |
| const windowX = x || Math.random() * (window.innerWidth - width); | |
| const windowY = y || Math.random() * (window.innerHeight - height - 100); | |
| const windowElement = document.createElement('app-window'); | |
| windowElement.id = windowId; | |
| windowElement.setAttribute('title', title); | |
| windowElement.setAttribute('icon', icon); | |
| windowElement.setAttribute('width', width); | |
| windowElement.setAttribute('height', height); | |
| windowElement.setAttribute('x', windowX); | |
| windowElement.setAttribute('y', windowY); | |
| windowElement.innerHTML = content; | |
| document.getElementById('windows-container').appendChild(windowElement); | |
| // Add to taskbar | |
| const bottomPanel = document.querySelector('bottom-panel'); | |
| if (bottomPanel && bottomPanel.addWindowToTaskbar) { | |
| bottomPanel.addWindowToTaskbar(windowId, title, icon); | |
| } | |
| // Focus new window | |
| setTimeout(() => focusWindow(windowId), 100); | |
| } | |
| function focusWindow(windowId) { | |
| const window = document.getElementById(windowId); | |
| if (!window) return; | |
| // Update z-index | |
| window.style.zIndex = ++windowZIndex; | |
| activeWindow = window; | |
| // Update visual state | |
| document.querySelectorAll('app-window').forEach(w => { | |
| w.classList.remove('active-window'); | |
| }); | |
| window.classList.add('active-window'); | |
| // Update taskbar | |
| updateTaskbarActiveWindow(windowId); | |
| } | |
| function updateTaskbarActiveWindow(windowId) { | |
| document.querySelectorAll('.taskbar-item').forEach(item => { | |
| item.classList.remove('taskbar-active'); | |
| if (item.dataset.windowId === windowId) { | |
| item.classList.add('taskbar-active'); | |
| } | |
| }); | |
| } | |
| function minimizeWindow(windowId) { | |
| const window = document.getElementById(windowId); | |
| if (!window) return; | |
| minimizedWindows.push(windowId); | |
| window.classList.add('window-minimize'); | |
| setTimeout(() => { | |
| window.style.display = 'none'; | |
| window.classList.remove('window-minimize'); | |
| }, 300); | |
| // Update taskbar | |
| const taskbarItem = document.querySelector(`[data-window-id="${windowId}"]`); | |
| if (taskbarItem) { | |
| taskbarItem.classList.remove('taskbar-active'); | |
| } | |
| } | |
| function restoreWindow(windowId) { | |
| const window = document.getElementById(windowId); | |
| if (!window) return; | |
| window.style.display = 'block'; | |
| window.classList.add('window-enter'); | |
| const index = minimizedWindows.indexOf(windowId); | |
| if (index > -1) { | |
| minimizedWindows.splice(index, 1); | |
| } | |
| setTimeout(() => { | |
| window.classList.remove('window-enter'); | |
| focusWindow(windowId); | |
| }, 200); | |
| } | |
| function closeWindow(windowId) { | |
| const window = document.getElementById(windowId); | |
| if (!window) return; | |
| window.classList.add('window-minimize'); | |
| setTimeout(() => { | |
| window.remove(); | |
| // Remove from taskbar | |
| const taskbarItem = document.querySelector(`[data-window-id="${windowId}"]`); | |
| if (taskbarItem) { | |
| taskbarItem.remove(); | |
| } | |
| // Update active window if needed | |
| if (activeWindow === window) { | |
| const windows = document.querySelectorAll('app-window'); | |
| if (windows.length > 0) { | |
| focusWindow(windows[windows.length - 1].id); | |
| } else { | |
| activeWindow = null; | |
| } | |
| } | |
| }, 300); | |
| } | |
| function maximizeWindow(windowId) { | |
| const window = document.getElementById(windowId); | |
| if (!window) return; | |
| const isMaximized = window.classList.contains('window-maximized'); | |
| if (isMaximized) { | |
| window.classList.remove('window-maximized'); | |
| // Restore previous size and position | |
| window.style.width = window.dataset.prevWidth || '600px'; | |
| window.style.height = window.dataset.prevHeight || '400px'; | |
| window.style.top = window.dataset.prevY || '100px'; | |
| window.style.left = window.dataset.prevX || '100px'; | |
| } else { | |
| // Store current size and position | |
| window.dataset.prevWidth = window.style.width; | |
| window.dataset.prevHeight = window.style.height; | |
| window.dataset.prevX = window.style.left; | |
| window.dataset.prevY = window.style.top; | |
| window.classList.add('window-maximized'); | |
| } | |
| } | |
| function updateClock() { | |
| const now = new Date(); | |
| const timeString = now.toLocaleTimeString('pt-BR', { | |
| hour: '2-digit', | |
| minute: '2-digit', | |
| hour12: false | |
| }); | |
| const dateString = now.toLocaleDateString('pt-BR', { | |
| day: '2-digit', | |
| month: 'short', | |
| weekday: 'short' | |
| }); | |
| const clockElement = document.getElementById('clock'); | |
| if (clockElement) { | |
| clockElement.innerHTML = ` | |
| <div class="text-xs">${dateString}</div> | |
| <div class="font-medium">${timeString}</div> | |
| `; | |
| } | |
| } | |
| // Update clock every second | |
| setInterval(updateClock, 1000); | |
| updateClock(); |