mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
fix: compatible with non-standard modifier keys
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -7,6 +7,8 @@ import { isModifier } from '@/lib/keymap';
|
||||
import { client, MessageEvent } from '@/lib/websocket.ts';
|
||||
import { isKeyboardEnableAtom } from '@/jotai/keyboard.ts';
|
||||
|
||||
import { normalizeKeyCode } from './utils.ts';
|
||||
|
||||
interface AltGrState {
|
||||
active: boolean;
|
||||
ctrlLeftTimestamp: number;
|
||||
@@ -23,7 +25,8 @@ export const Keyboard = () => {
|
||||
const isComposing = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (getOperatingSystem() === 'Windows' && !altGrState.current) {
|
||||
const os = getOperatingSystem();
|
||||
if (os === 'Windows' && !altGrState.current) {
|
||||
altGrState.current = { active: false, ctrlLeftTimestamp: 0 };
|
||||
}
|
||||
|
||||
@@ -49,8 +52,10 @@ export const Keyboard = () => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const code = event.code;
|
||||
if (pressedKeys.current.has(code)) return;
|
||||
const code = normalizeKeyCode(event, os);
|
||||
if (!code || pressedKeys.current.has(code)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// When AltGr is pressed, browsers send ControlLeft followed immediately by AltRight
|
||||
if (altGrState.current) {
|
||||
@@ -79,7 +84,10 @@ export const Keyboard = () => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const code = event.code;
|
||||
const code = normalizeKeyCode(event, os);
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle AltGr state for Windows
|
||||
if (altGrState.current?.active) {
|
||||
|
||||
26
web/src/pages/desktop/keyboard/utils.ts
Normal file
26
web/src/pages/desktop/keyboard/utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export 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;
|
||||
}
|
||||
Reference in New Issue
Block a user