fix(browser): the Right Shift key was not being recognized on Windows system

This commit is contained in:
wj-xiao
2026-02-25 10:58:25 +08:00
parent d6bf64bbbe
commit cb7c647018
2 changed files with 49 additions and 16 deletions

View File

@@ -15,6 +15,7 @@ interface AltGrState {
const ALTGR_THRESHOLD_MS = 10;
export const Keyboard = () => {
const os = getOperatingSystem();
const isKeyboardEnabled = useAtomValue(isKeyboardEnableAtom);
const keyboardRef = useRef(new KeyboardReport());
@@ -23,7 +24,7 @@ export const Keyboard = () => {
const isComposing = useRef(false);
useEffect(() => {
if (getOperatingSystem() === 'Windows' && !altGrState.current) {
if (os === 'Windows' && !altGrState.current) {
altGrState.current = { active: false, ctrlLeftTimestamp: 0 };
}
@@ -49,8 +50,8 @@ export const Keyboard = () => {
event.preventDefault();
event.stopPropagation();
const code = event.code;
if (pressedKeys.current.has(code)) {
const code = normalizeKeyCode(event, os);
if (!code || pressedKeys.current.has(code)) {
return;
}
@@ -81,7 +82,7 @@ export const Keyboard = () => {
event.preventDefault();
event.stopPropagation();
const code = event.code;
const code = normalizeKeyCode(event, os);
// Handle AltGr state for Windows
if (altGrState.current?.active) {
@@ -163,6 +164,33 @@ export const Keyboard = () => {
};
}, [isKeyboardEnabled]);
function normalizeKeyCode(event: KeyboardEvent, os?: string): string {
if (event.code) {
return event.code;
}
// Fallback: use event.key + event.location to determine the key
// event.location: 1 = left, 2 = right, 0 = standard (non-positional)
if (event.key === 'Shift') {
if (event.location === 0 && os === 'Windows') {
return 'ShiftRight';
}
return event.location === 2 ? 'ShiftRight' : 'ShiftLeft';
}
if (event.key === 'Control') {
return event.location === 2 ? 'ControlRight' : 'ControlLeft';
}
if (event.key === 'Alt') {
return event.location === 2 ? 'AltRight' : 'AltLeft';
}
if (event.key === 'Meta') {
return event.location === 2 ? 'MetaRight' : 'MetaLeft';
}
return event.code;
}
// Keyboard handler
async function handleKeyEvent(event: { type: 'keydown' | 'keyup'; code: string }): Promise<void> {
const kb = keyboardRef.current;

View File

@@ -1,28 +1,33 @@
export type System = 'Windows' | 'macOS' | 'Linux' | 'Unknown';
export interface BrowserInfo {
os: string;
os: System;
isChrome: boolean;
}
export function getOperatingSystem(): string {
export function getOperatingSystem(): System {
if (typeof window === 'undefined') {
return 'Unknown';
}
const platformSource =
if ('userAgentData' in navigator) {
// @ts-expect-error check userAgentData.platform
'userAgentData' in navigator ? navigator.userAgentData.platform : navigator.platform;
if (!platformSource) {
return 'Unknown';
const platform = navigator.userAgentData?.platform?.toLowerCase();
if (platform) {
if (platform === 'windows') return 'Windows';
if (platform === 'macos') return 'macOS';
if (platform === 'linux' || platform === 'android') return 'Linux';
}
}
const platform = platformSource.toLowerCase();
// Fallback to User Agent
const userAgent = navigator.userAgent;
if (platform.startsWith('win')) return 'Windows';
if (platform.startsWith('mac')) return 'macOS';
if (platform.startsWith('linux')) return 'Linux';
if (/Win/i.test(userAgent)) return 'Windows';
if (/Mac|iPhone|iPod|iPad/i.test(userAgent)) return 'macOS';
if (/Linux|Android/i.test(userAgent)) return 'Linux';
return platformSource;
return 'Unknown';
}
export function isChromeBrowser(): boolean {