@@ -15,6 +15,7 @@ interface AltGrState {
1515const ALTGR_THRESHOLD_MS = 10 ;
1616
1717export const Keyboard = ( ) => {
18+ const os = getOperatingSystem ( ) ;
1819 const isKeyboardEnabled = useAtomValue ( isKeyboardEnableAtom ) ;
1920
2021 const keyboardRef = useRef ( new KeyboardReport ( ) ) ;
@@ -23,7 +24,7 @@ export const Keyboard = () => {
2324 const isComposing = useRef ( false ) ;
2425
2526 useEffect ( ( ) => {
26- if ( getOperatingSystem ( ) === 'Windows' && ! altGrState . current ) {
27+ if ( os === 'Windows' && ! altGrState . current ) {
2728 altGrState . current = { active : false , ctrlLeftTimestamp : 0 } ;
2829 }
2930
@@ -49,8 +50,8 @@ export const Keyboard = () => {
4950 event . preventDefault ( ) ;
5051 event . stopPropagation ( ) ;
5152
52- const code = event . code ;
53- if ( pressedKeys . current . has ( code ) ) {
53+ const code = normalizeKeyCode ( event , os ) ;
54+ if ( ! code || pressedKeys . current . has ( code ) ) {
5455 return ;
5556 }
5657
@@ -81,7 +82,7 @@ export const Keyboard = () => {
8182 event . preventDefault ( ) ;
8283 event . stopPropagation ( ) ;
8384
84- const code = event . code ;
85+ const code = normalizeKeyCode ( event , os ) ;
8586
8687 // Handle AltGr state for Windows
8788 if ( altGrState . current ?. active ) {
@@ -163,6 +164,33 @@ export const Keyboard = () => {
163164 } ;
164165 } , [ isKeyboardEnabled ] ) ;
165166
167+ function normalizeKeyCode ( event : KeyboardEvent , os ?: string ) : string {
168+ if ( event . code ) {
169+ return event . code ;
170+ }
171+
172+ // Fallback: use event.key + event.location to determine the key
173+ // event.location: 1 = left, 2 = right, 0 = standard (non-positional)
174+ if ( event . key === 'Shift' ) {
175+ if ( event . location === 0 && os === 'Windows' ) {
176+ return 'ShiftRight' ;
177+ }
178+ return event . location === 2 ? 'ShiftRight' : 'ShiftLeft' ;
179+ }
180+
181+ if ( event . key === 'Control' ) {
182+ return event . location === 2 ? 'ControlRight' : 'ControlLeft' ;
183+ }
184+ if ( event . key === 'Alt' ) {
185+ return event . location === 2 ? 'AltRight' : 'AltLeft' ;
186+ }
187+ if ( event . key === 'Meta' ) {
188+ return event . location === 2 ? 'MetaRight' : 'MetaLeft' ;
189+ }
190+
191+ return event . code ;
192+ }
193+
166194 // Keyboard handler
167195 async function handleKeyEvent ( event : { type : 'keydown' | 'keyup' ; code : string } ) : Promise < void > {
168196 const kb = keyboardRef . current ;
0 commit comments