11import '../styles/routes/desktop.css' ;
2- import { Wifi , Volume2 , Bell } from 'lucide-react' ;
2+ import { Wifi , Volume2 , Bell , Search } from 'lucide-react' ;
33import AppWindow , { INITIAL_Z , getNextZ } from '../core/WindowManager.jsx' ;
4- import { createRef , useRef , useState , useMemo } from "react" ;
4+ import { createRef , useRef , useState , useMemo , useEffect } from "react" ;
55import { APP_REGISTRY } from "../data/Apps.js" ;
66
77import Draggable from 'react-draggable' ;
88import { motion , AnimatePresence } from "framer-motion" ;
99
1010function Desktop ( ) {
11+ const [ isStartMenuActive , setIsStartMenuActive ] = useState ( false ) ;
12+
13+ const startMenuRef = useRef ( null ) ;
14+
15+ useEffect ( ( ) => {
16+ const handleClickOutside = ( event ) => {
17+ if ( isStartMenuActive && startMenuRef . current && ! startMenuRef . current . contains ( event . target ) ) {
18+ if ( ! event . target . closest ( '#start-menu-icon' ) ) {
19+ setIsStartMenuActive ( false ) ;
20+ }
21+ }
22+ } ;
23+ document . addEventListener ( "mousedown" , handleClickOutside ) ;
24+ return ( ) => document . removeEventListener ( "mousedown" , handleClickOutside ) ;
25+ } , [ isStartMenuActive ] ) ;
26+
1127 const [ iconPositions , setIconPositions ] = useState ( {
1228 explorer : { col : 1 , row : 1 } ,
1329 vscode : { col : 1 , row : 2 } ,
@@ -149,9 +165,30 @@ function Desktop() {
149165 } ) ) ;
150166 }
151167
168+ useEffect ( ( ) => {
169+ const handleKey = ( e ) => {
170+ if ( e . metaKey ) {
171+ e . preventDefault ( ) ;
172+
173+ setIsStartMenuActive ( ! isStartMenuActive ) ;
174+ }
175+ } ;
176+
177+ window . addEventListener ( "keydown" , handleKey ) ;
178+ return ( ) => window . removeEventListener ( "keydown" , handleKey ) ;
179+ } ) ;
180+
152181 return (
153- < div className = "desktop" onMouseDown = { ( ) => setSelectedIcon ( null ) } >
154- < div className = "desktop-grid" style = { { position : 'absolute' , inset : 0 , display : 'grid' , zIndex : 1 } } >
182+ < div className = "desktop" onMouseDown = { ( ) => {
183+ setSelectedIcon ( null ) ;
184+ } } >
185+ < div
186+ className = "desktop-grid"
187+ style = { { position : 'absolute' , inset : 0 , display : 'grid' , zIndex : 1 } }
188+ onClick = { ( ) => {
189+ setIsStartMenuActive ( false ) ;
190+ } }
191+ >
155192 { Object . keys ( iconPositions ) . map ( ( id ) => (
156193 < Draggable
157194 key = { id }
@@ -213,6 +250,16 @@ function Desktop() {
213250 ) : null
214251 ) }
215252
253+ < div
254+ ref = { startMenuRef }
255+ className = { `start-menu ${ isStartMenuActive ? "active" : "" } ` }
256+ >
257+ < div className = { "start-search" } >
258+ < Search className = { "start-search-icon" } />
259+ < input className = { "start-search-bar" } type = { "text" } />
260+ </ div >
261+ </ div >
262+
216263 < div className = { `taskbar ${ isAnyFullScreen ? 'is-fullscreen' : '' } ` } onClick = { ( e ) => e . stopPropagation ( ) } >
217264 < div className = "apps" >
218265 < AnimatePresence mode = "popLayout" >
@@ -223,11 +270,13 @@ function Desktop() {
223270 exit = { { opacity : 0 , width : 0 , scale : 0.5 } }
224271 transition = { { type : "spring" , stiffness : 300 , damping : 30 } }
225272 className = "app-item"
273+ onClick = { ( ) => setIsStartMenuActive ( ! isStartMenuActive ) }
226274 >
227- < div className = "taskbar-app" id = "start-menu" >
275+ < div className = "taskbar-app" id = "start-menu-icon " >
228276 < img className = { "taskbar-app-icon" } src = { "/assets/icons/Windows.svg" } draggable = "false" alt = "icon" />
229277 </ div >
230278 </ motion . div >
279+
231280 { taskbarApps . map ( id => (
232281 < motion . div
233282 key = { id }
0 commit comments