mirror of https://github.com/jetkvm/kvm.git
Compare commits
3 Commits
681b9c0b6e
...
1a58f1cad0
Author | SHA1 | Date |
---|---|---|
|
1a58f1cad0 | |
|
6cd8a7ae95 | |
|
c961b72966 |
|
@ -30,7 +30,7 @@ export function JigglerSetting({
|
|||
},
|
||||
);
|
||||
|
||||
const { send } = useJsonRpc();
|
||||
const [send] = useJsonRpc();
|
||||
const [timezones, setTimezones] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ChevronDownIcon } from "@heroicons/react/16/solid";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import Keyboard from "react-simple-keyboard";
|
||||
|
||||
import Card from "@components/Card";
|
||||
|
@ -15,7 +15,7 @@ import { cx } from "@/cva.config";
|
|||
import { useHidStore, useUiStore } from "@/hooks/stores";
|
||||
import useKeyboard from "@/hooks/useKeyboard";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import { keys, modifiers, latchingKeys, decodeModifiers } from "@/keyboardMappings";
|
||||
import { keys } from "@/keyboardMappings";
|
||||
|
||||
export const DetachIcon = ({ className }: { className?: string }) => {
|
||||
return <img src={DetachIconRaw} alt="Detach Icon" className={className} />;
|
||||
|
@ -26,9 +26,11 @@ const AttachIcon = ({ className }: { className?: string }) => {
|
|||
};
|
||||
|
||||
function KeyboardWrapper() {
|
||||
const [layoutName] = useState("default");
|
||||
|
||||
const keyboardRef = useRef<HTMLDivElement>(null);
|
||||
const { isAttachedVirtualKeyboardVisible, setAttachedVirtualKeyboardVisibility } = useUiStore();
|
||||
const { keysDownState, /* keyboardLedState,*/ isVirtualKeyboardEnabled, setVirtualKeyboardEnabled } = useHidStore();
|
||||
const { keysDownState, isVirtualKeyboardEnabled, setVirtualKeyboardEnabled } = useHidStore();
|
||||
const { handleKeyPress, executeMacro } = useKeyboard();
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
@ -37,28 +39,19 @@ function KeyboardWrapper() {
|
|||
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
|
||||
//const isCapsLockActive = useMemo(() => {
|
||||
// return (keyboardLedState.caps_lock);
|
||||
//}, [keyboardLedState]);
|
||||
/*
|
||||
// These will be used to display the currently pressed keys and modifiers on the virtual keyboard
|
||||
|
||||
const { isShiftActive, /*isControlActive, isAltActive, isMetaActive, isAltGrActive*/ } = useMemo(() => {
|
||||
return decodeModifiers(keysDownState.modifier);
|
||||
}, [keysDownState]);
|
||||
// used to show the modifier keys that are in the "down state" on the virtual keyboard
|
||||
const keyNamesFromModifierMask = (activeModifiers: number): string[] => {
|
||||
return Object.entries(modifiers).filter(m => (activeModifiers & m[1]) !== 0).map(m => m[0]);
|
||||
}
|
||||
|
||||
const mainLayoutName = useMemo(() => {
|
||||
const layoutName = isShiftActive ? "shift": "default";
|
||||
return layoutName;
|
||||
}, [isShiftActive]);
|
||||
|
||||
const keyNamesForDownKeys = useMemo(() => {
|
||||
const activeModifierMask = keysDownState.modifier || 0;
|
||||
const modifierNames = Object.entries(modifiers).filter(([_, mask]) => (activeModifierMask & mask) !== 0).map(([name, _]) => name);
|
||||
|
||||
const keysDown = keysDownState.keys || [];
|
||||
const keyNames = Object.entries(keys).filter(([_, value]) => keysDown.includes(value)).map(([name, _]) => name);
|
||||
|
||||
return [...modifierNames,...keyNames, ' ']; // we have to have at least one space to avoid keyboard whining
|
||||
}, [keysDownState]);
|
||||
// used to show the regular keys that are in the "down state" on the virtual keyboard
|
||||
const keyNamesFromDownKeys = (downKeys: number[]) => {
|
||||
return Object.entries(keys).filter(([_, code]) => downKeys.includes(code)).map(([name, _]) => name);
|
||||
}
|
||||
*/
|
||||
|
||||
const startDrag = useCallback((e: MouseEvent | TouchEvent) => {
|
||||
if (!keyboardRef.current) return;
|
||||
|
@ -129,18 +122,10 @@ function KeyboardWrapper() {
|
|||
};
|
||||
}, [endDrag, onDrag, startDrag]);
|
||||
|
||||
const onKeyUp = useCallback(
|
||||
async (_: string, e: MouseEvent | undefined) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const onKeyDown = useCallback(
|
||||
async (key: string, e: MouseEvent | undefined) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
async (key: string) => {
|
||||
const latchingKeys = ["CapsLock", "ScrollLock", "NumLock", "Meta", "Compose", "Kana"];
|
||||
const dynamicKeys = ["ShiftLeft", "ShiftRight", "ControlLeft", "ControlRight", "AltLeft", "AltRight", "MetaLeft", "MetaRight"];
|
||||
|
||||
// handle the fake key-macros we have defined for common combinations
|
||||
if (key === "CtrlAltDelete") {
|
||||
|
@ -167,8 +152,8 @@ function KeyboardWrapper() {
|
|||
}
|
||||
|
||||
// if they press any of the dynamic keys, we send a keypress down event but we don't release it until they click it again
|
||||
if (Object.keys(modifiers).includes(key)) {
|
||||
const currentlyDown = keyNamesForDownKeys.includes(key);
|
||||
if (dynamicKeys.includes(key)) {
|
||||
const currentlyDown = keysDownState.keys.includes(keys[key]);
|
||||
console.debug(`Dynamic key pressed: ${key} was currently down: ${currentlyDown}, toggling state`);
|
||||
handleKeyPress(keys[key], !currentlyDown)
|
||||
return;
|
||||
|
@ -180,9 +165,16 @@ function KeyboardWrapper() {
|
|||
handleKeyPress(keys[cleanKey], true);
|
||||
setTimeout(() => handleKeyPress(keys[cleanKey], false), 50);
|
||||
},
|
||||
[executeMacro, handleKeyPress, keyNamesForDownKeys],
|
||||
[executeMacro, handleKeyPress, keysDownState],
|
||||
);
|
||||
|
||||
// TODO handle the display of down keys and the layout change for shift/caps lock
|
||||
// const { isCapsLockActive } = useShallow(useHidStore());
|
||||
// // Handle toggle of layout for shift or caps lock
|
||||
// const toggleLayout = () => {
|
||||
// setLayoutName(prevLayout => (prevLayout === "default" ? "shift" : "default"));
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
className="transition-all duration-500 ease-in-out"
|
||||
|
@ -256,68 +248,37 @@ function KeyboardWrapper() {
|
|||
<div className="flex flex-col bg-blue-50/80 md:flex-row dark:bg-slate-700">
|
||||
<Keyboard
|
||||
baseClass="simple-keyboard-main"
|
||||
layoutName={mainLayoutName}
|
||||
layoutName={layoutName}
|
||||
onKeyPress={onKeyDown}
|
||||
onKeyReleased={onKeyUp}
|
||||
buttonTheme={[
|
||||
{
|
||||
class: "combination-key",
|
||||
buttons: "CtrlAltDelete AltMetaEscape CtrlAltBackspace",
|
||||
},
|
||||
{
|
||||
class: "down-key",
|
||||
buttons: keyNamesForDownKeys.join(" "),
|
||||
},
|
||||
]}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.main}
|
||||
disableButtonHold={true}
|
||||
debug={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
/>
|
||||
|
||||
<div className="controlArrows">
|
||||
<Keyboard
|
||||
baseClass="simple-keyboard-control"
|
||||
theme="simple-keyboard hg-theme-default hg-layout-default"
|
||||
layoutName="default"
|
||||
layoutName={layoutName}
|
||||
onKeyPress={onKeyDown}
|
||||
onKeyReleased={onKeyUp}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.control}
|
||||
debug={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
/>
|
||||
<Keyboard
|
||||
baseClass="simple-keyboard-arrows"
|
||||
theme="simple-keyboard hg-theme-default hg-layout-default"
|
||||
onKeyPress={onKeyDown}
|
||||
onKeyReleased={onKeyUp}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.arrows}
|
||||
debug={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
/>
|
||||
</div>
|
||||
{ /* TODO add optional number pad */ }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { LuCornerDownLeft } from "react-icons/lu";
|
||||
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
|
||||
import { useClose } from "@headlessui/react";
|
||||
|
|
|
@ -136,7 +136,6 @@ export default function useKeyboard() {
|
|||
const handleKeyPress = useCallback(
|
||||
async (key: number, press: boolean) => {
|
||||
if (rpcDataChannel?.readyState !== "open") return;
|
||||
if ((key || 0) === 0) return; // ignore zero key presses (they are bad mappings)
|
||||
|
||||
if (keyPressReportApiAvailable) {
|
||||
// if the keyPress api is available, we can just send the key press event
|
||||
|
|
|
@ -315,11 +315,6 @@ video::-webkit-media-controls {
|
|||
@apply inline-flex h-auto! w-auto! grow-0 py-1 text-xs;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-row .down-key {
|
||||
background: rgb(28, 28, 28);
|
||||
@apply text-white! font-bold!;
|
||||
}
|
||||
|
||||
.hg-theme-default .hg-row .hg-button-container,
|
||||
.hg-theme-default .hg-row .hg-button:not(:last-child) {
|
||||
@apply mr-[2px]! md:mr-[5px]!;
|
||||
|
|
|
@ -10,137 +10,107 @@ const keyHat: KeyCombo = { key: "Backquote" } // accent circonflexe (accent hat)
|
|||
const keyGrave: KeyCombo = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
|
||||
|
||||
const chars = {
|
||||
a: { key: "KeyA" },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"☺": { key: "KeyA", altRight: true }, // white smiling face ☺
|
||||
b: { key: "KeyB" },
|
||||
B: { key: "KeyB", shift: true },
|
||||
"‹": { key: "KeyB", altRight: true }, // single left-pointing angle quotation mark, ‹
|
||||
c: { key: "KeyC" },
|
||||
C: { key: "KeyC", shift: true },
|
||||
"\u202f": { key: "KeyC", altRight: true }, // narrow no-break space
|
||||
d: { key: "KeyD" },
|
||||
D: { key: "KeyD", shift: true },
|
||||
"′": { key: "KeyD", altRight: true }, // prime, mark ′ placed above the letter
|
||||
E: { key: "KeyE", shift: true },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
F: { key: "KeyF", shift: true },
|
||||
G: { key: "KeyG", shift: true },
|
||||
H: { key: "KeyH", shift: true },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
K: { key: "KeyK", shift: true },
|
||||
L: { key: "KeyL", shift: true },
|
||||
M: { key: "KeyM", shift: true },
|
||||
N: { key: "KeyN", shift: true },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
P: { key: "KeyP", shift: true },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
S: { key: "KeyS", shift: true },
|
||||
T: { key: "KeyT", shift: true },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
V: { key: "KeyV", shift: true },
|
||||
W: { key: "KeyW", shift: true },
|
||||
X: { key: "KeyX", shift: true },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
a: { key: "KeyA" },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave},
|
||||
b: { key: "KeyB" },
|
||||
c: { key: "KeyC" },
|
||||
d: { key: "KeyD" },
|
||||
e: { key: "KeyE" },
|
||||
"é": { key: "KeyE", accentKey: keyAcute},
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"€": { key: "KeyE", altRight: true },
|
||||
E: { key: "KeyE", shift: true },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
f: { key: "KeyF" },
|
||||
F: { key: "KeyF", shift: true },
|
||||
"˟": { key: "KeyF", deadKey: true, altRight: true }, // modifier letter cross accent, ˟
|
||||
G: { key: "KeyG", shift: true },
|
||||
g: { key: "KeyG" },
|
||||
"ẞ": { key: "KeyG", altRight: true }, // capital sharp S, ẞ
|
||||
h: { key: "KeyH" },
|
||||
H: { key: "KeyH", shift: true },
|
||||
"ˍ": { key: "KeyH", deadKey: true, altRight: true }, // modifier letter low macron, ˍ
|
||||
i: { key: "KeyI" },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"˜": { key: "KeyI", deadKey: true, altRight: true }, // tilde accent, mark ˜ placed above the letter
|
||||
j: { key: "KeyJ" },
|
||||
J: { key: "KeyJ", shift: true },
|
||||
"¸": { key: "KeyJ", deadKey: true, altRight: true }, // cedilla accent, mark ¸ placed below the letter
|
||||
k: { key: "KeyK" },
|
||||
K: { key: "KeyK", shift: true },
|
||||
l: { key: "KeyL" },
|
||||
L: { key: "KeyL", shift: true },
|
||||
"ˏ": { key: "KeyL", deadKey: true, altRight: true }, // modifier letter reversed comma, ˏ
|
||||
m: { key: "KeyM" },
|
||||
M: { key: "KeyM", shift: true },
|
||||
"µ": { key: "KeyM", altRight: true },
|
||||
n: { key: "KeyN" },
|
||||
N: { key: "KeyN", shift: true },
|
||||
"–": { key: "KeyN", altRight: true }, // en dash, –
|
||||
o: { key: "KeyO" },
|
||||
"ó": { key: "KeyO", accentKey: keyAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"˚": { key: "KeyO", deadKey: true, altRight: true }, // ring above, ˚
|
||||
p: { key: "KeyP" },
|
||||
P: { key: "KeyP", shift: true },
|
||||
"ˀ": { key: "KeyP", deadKey: true, altRight: true }, // modifier letter apostrophe, ʾ
|
||||
q: { key: "KeyQ" },
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
"@": { key: "KeyQ", altRight: true },
|
||||
R: { key: "KeyR", shift: true },
|
||||
r: { key: "KeyR" },
|
||||
"˝": { key: "KeyR", deadKey: true, altRight: true }, // double acute accent, mark ˝ placed above the letter
|
||||
S: { key: "KeyS", shift: true },
|
||||
s: { key: "KeyS" },
|
||||
"″": { key: "KeyS", altRight: true }, // double prime, mark ″ placed above the letter
|
||||
T: { key: "KeyT", shift: true },
|
||||
t: { key: "KeyT" },
|
||||
"ˇ": { key: "KeyT", deadKey: true, altRight: true }, // caron/hacek accent, mark ˇ placed above the letter
|
||||
u: { key: "KeyU" },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"˘": { key: "KeyU", deadKey: true, altRight: true }, // breve accent, ˘ placed above the letter
|
||||
v: { key: "KeyV" },
|
||||
V: { key: "KeyV", shift: true },
|
||||
"«": { key: "KeyV", altRight: true }, // left-pointing double angle quotation mark, «
|
||||
w: { key: "KeyW" },
|
||||
W: { key: "KeyW", shift: true },
|
||||
"¯": { key: "KeyW", deadKey: true, altRight: true }, // macron accent, mark ¯ placed above the letter
|
||||
x: { key: "KeyX" },
|
||||
X: { key: "KeyX", shift: true },
|
||||
"»": { key: "KeyX", altRight: true },
|
||||
// cross key between shift and y (aka OEM 102 key)
|
||||
y: { key: "KeyZ" },
|
||||
Y: { key: "KeyZ", shift: true },
|
||||
"›": { key: "KeyZ", altRight: true }, // single right-pointing angle quotation mark, ›
|
||||
z: { key: "KeyY" },
|
||||
Z: { key: "KeyY", shift: true },
|
||||
"¨": { key: "KeyY", deadKey: true, altRight: true }, // diaeresis accent, mark ¨ placed above the letter
|
||||
"°": { key: "Backquote", shift: true },
|
||||
"^": { key: "Backquote", deadKey: true },
|
||||
"|": { key: "Backquote", altRight: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
"’": { key: "Digit1", altRight: true }, // single quote, mark ’ placed above the letter
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"²": { key: "Digit2", altRight: true },
|
||||
"<": { key: "Digit2", altRight: true }, // non-US < and >
|
||||
3: { key: "Digit3" },
|
||||
"§": { key: "Digit3", shift: true },
|
||||
"³": { key: "Digit3", altRight: true },
|
||||
">": { key: "Digit3", altRight: true }, // non-US < and >
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
"—": { key: "Digit4", altRight: true }, // em dash, —
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
"¡": { key: "Digit5", altRight: true }, // inverted exclamation mark, ¡
|
||||
6: { key: "Digit6" },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
"¿": { key: "Digit6", altRight: true }, // inverted question mark, ¿
|
||||
7: { key: "Digit7" },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
"{": { key: "Digit7", altRight: true },
|
||||
|
@ -156,192 +126,40 @@ const chars = {
|
|||
"ß": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"\\": { key: "Minus", altRight: true },
|
||||
"´": { key: "Equal", deadKey: true }, // accent acute, mark ´ placed above the letter
|
||||
"`": { key: "Equal", shift: true, deadKey: true }, // accent grave, mark ` placed above the letter
|
||||
"˙": { key: "Equal", control: true, altRight: true, deadKey: true }, // acute accent, mark ˙ placed above the letter
|
||||
"´": { key: "Equal", deadKey: true },
|
||||
"`": { key: "Equal", shift: true, deadKey: true },
|
||||
"ü": { key: "BracketLeft" },
|
||||
"Ü": { key: "BracketLeft", shift: true },
|
||||
Escape: { key: "BracketLeft", control: true },
|
||||
"ʼ": { key: "BracketLeft", altRight: true }, // modifier letter apostrophe, ʼ
|
||||
"+": { key: "BracketRight" },
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
Control: { key: "BracketRight", control: true },
|
||||
"~": { key: "BracketRight", altRight: true },
|
||||
"ö": { key: "Semicolon" },
|
||||
"Ö": { key: "Semicolon", shift: true },
|
||||
"ˌ": { key: "Semicolon", deadkey: true, altRight: true }, // modifier letter low vertical line, ˌ
|
||||
"ä": { key: "Quote" },
|
||||
"Ä": { key: "Quote", shift: true },
|
||||
"˗": { key: "Quote", deadKey: true, altRight: true }, // modifier letter minus sign, ˗
|
||||
"#": { key: "Backslash" },
|
||||
"'": { key: "Backslash", shift: true },
|
||||
"−": { key: "Backslash", altRight: true }, // minus sign, −
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
"\u2011": { key: "Comma", altRight: true }, // non-breaking hyphen, ‑
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"·": { key: "Period", altRight: true }, // middle dot, ·
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"\u00ad": { key: "Slash", altRight: true }, // soft hyphen,
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
"|": { key: "IntlBackslash", altRight: true },
|
||||
" ": { key: "Space" },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
||||
|
||||
export const keyDisplayMap: Record<string, string> = {
|
||||
...en_US.keyDisplayMap,
|
||||
// now override the English keyDisplayMap with German specific keys
|
||||
|
||||
// Combination keys
|
||||
CtrlAltDelete: "Strg + Alt + Entf",
|
||||
CtrlAltBackspace: "Strg + Alt + ←",
|
||||
|
||||
// German action keys
|
||||
AltLeft: "Alt",
|
||||
AltRight: "AltGr",
|
||||
Backspace: "Rücktaste",
|
||||
"(Backspace)": "Rücktaste",
|
||||
CapsLock: "Feststelltaste",
|
||||
Clear: "Entf",
|
||||
ControlLeft: "Strg",
|
||||
ControlRight: "Strg",
|
||||
Delete: "Entf",
|
||||
End: "Ende",
|
||||
Enter: "Eingabe",
|
||||
Escape: "Esc",
|
||||
Home: "Pos1",
|
||||
Insert: "Einfg",
|
||||
Menu: "Menü",
|
||||
MetaLeft: "Meta",
|
||||
MetaRight: "Meta",
|
||||
PageDown: "Bild ↓",
|
||||
PageUp: "Bild ↑",
|
||||
ShiftLeft: "Umschalt",
|
||||
ShiftRight: "Umschalt",
|
||||
|
||||
// German umlauts and ß
|
||||
BracketLeft: "ü",
|
||||
"(BracketLeft)": "Ü",
|
||||
Semicolon: "ö",
|
||||
"(Semicolon)": "Ö",
|
||||
Quote: "ä",
|
||||
"(Quote)": "Ä",
|
||||
Minus: "ß",
|
||||
"(Minus)": "?",
|
||||
Equal: "´",
|
||||
"(Equal)": "`",
|
||||
Backslash: "#",
|
||||
"(Backslash)": "'",
|
||||
|
||||
// Shifted Numbers
|
||||
"(Digit2)": "\"",
|
||||
"(Digit3)": "§",
|
||||
"(Digit6)": "&",
|
||||
"(Digit7)": "/",
|
||||
"(Digit8)": "(",
|
||||
"(Digit9)": ")",
|
||||
"(Digit0)": "=",
|
||||
|
||||
// Additional German symbols
|
||||
Backquote: "^",
|
||||
"(Backquote)": "°",
|
||||
Comma: ",",
|
||||
"(Comma)": ";",
|
||||
Period: ".",
|
||||
"(Period)": ":",
|
||||
Slash: "-",
|
||||
"(Slash)": "_",
|
||||
|
||||
// Numpad
|
||||
NumpadDecimal: "Num ,",
|
||||
NumpadEnter: "Num Eingabe",
|
||||
NumpadInsert: "Einfg",
|
||||
NumpadDelete: "Entf",
|
||||
|
||||
// Modals
|
||||
PrintScreen: "Druck",
|
||||
ScrollLock: "Rollen",
|
||||
"(Pause)": "Unterbr",
|
||||
}
|
||||
|
||||
export const modifierDisplayMap: Record<string, string> = {
|
||||
ShiftLeft: "Umschalt (links)",
|
||||
ShiftRight: "Umschalt (rechts)",
|
||||
ControlLeft: "Strg (links)",
|
||||
ControlRight: "Strg (rechts)",
|
||||
AltLeft: "Alt",
|
||||
AltRight: "AltGr",
|
||||
MetaLeft: "Meta (links)",
|
||||
MetaRight: "Meta (rechts)",
|
||||
AltGr: "AltGr",
|
||||
} as Record<string, string>;
|
||||
|
||||
export const virtualKeyboard = {
|
||||
main: {
|
||||
default: [
|
||||
"CtrlAltDelete AltMetaEscape CtrlAltBackspace",
|
||||
"Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12",
|
||||
"Backquote Digit1 Digit2 Digit3 Digit4 Digit5 Digit6 Digit7 Digit8 Digit9 Digit0 Minus Equal Backspace",
|
||||
"Tab KeyQ KeyW KeyE KeyR KeyT KeyY KeyU KeyI KeyO KeyP BracketLeft BracketRight",
|
||||
"CapsLock KeyA KeyS KeyD KeyF KeyG KeyH KeyJ KeyK KeyL Semicolon Quote Backslash Enter",
|
||||
"ShiftLeft KeyZ KeyX KeyC KeyV KeyB KeyN KeyM Comma Period Slash ShiftRight",
|
||||
"ControlLeft MetaLeft AltLeft Space AltGr MetaRight Menu ControlRight",
|
||||
],
|
||||
shift: [
|
||||
"CtrlAltDelete AltMetaEscape CtrlAltBackspace",
|
||||
"Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12",
|
||||
"(Backquote) (Digit1) (Digit2) (Digit3) (Digit4) (Digit5) (Digit6) (Digit7) (Digit8) (Digit9) (Digit0) (Minus) (Equal) (Backspace)",
|
||||
"Tab (KeyQ) (KeyW) (KeyE) (KeyR) (KeyT) (KeyY) (KeyU) (KeyI) (KeyO) (KeyP) (BracketLeft) (BracketRight) (Backslash)",
|
||||
"CapsLock (KeyA) (KeyS) (KeyD) (KeyF) (KeyG) (KeyH) (KeyJ) (KeyK) (KeyL) (Semicolon) (Quote) Enter",
|
||||
"ShiftLeft (KeyZ) (KeyX) (KeyC) (KeyV) (KeyB) (KeyN) (KeyM) (Comma) (Period) (Slash) ShiftRight",
|
||||
"ControlLeft MetaLeft AltLeft Space AltGr MetaRight Menu ControlRight",
|
||||
]
|
||||
},
|
||||
control: {
|
||||
default: [
|
||||
"PrintScreen ScrollLock Pause",
|
||||
"Insert Home PageUp",
|
||||
"Delete End PageDown"
|
||||
],
|
||||
shift: [
|
||||
"(PrintScreen) ScrollLock (Pause)",
|
||||
"Insert Home PageUp",
|
||||
"Delete End PageDown"
|
||||
],
|
||||
},
|
||||
|
||||
arrows: {
|
||||
default: [
|
||||
" ArrowUp ",
|
||||
"ArrowLeft ArrowDown ArrowRight"],
|
||||
},
|
||||
|
||||
numpad: {
|
||||
numlocked: [
|
||||
"NumLock NumpadDivide NumpadMultiply NumpadSubtract",
|
||||
"Numpad7 Numpad8 Numpad9 NumpadAdd",
|
||||
"Numpad4 Numpad5 Numpad6",
|
||||
"Numpad1 Numpad2 Numpad3 NumpadEnter",
|
||||
"Numpad0 NumpadDecimal",
|
||||
],
|
||||
default: [
|
||||
"NumLock NumpadDivide NumpadMultiply NumpadSubtract",
|
||||
"Home ArrowUp PageUp NumpadAdd",
|
||||
"ArrowLeft Clear ArrowRight",
|
||||
"End ArrowDown PageDown NumpadEnter",
|
||||
"NumpadInsert NumpadDelete",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export const de_DE: KeyboardLayout = {
|
||||
isoCode: isoCode,
|
||||
name: name,
|
||||
chars: chars,
|
||||
keyDisplayMap: keyDisplayMap,
|
||||
modifierDisplayMap: modifierDisplayMap,
|
||||
virtualKeyboard: virtualKeyboard
|
||||
// TODO need to localize these maps and layouts
|
||||
keyDisplayMap: en_US.keyDisplayMap,
|
||||
modifierDisplayMap: en_US.modifierDisplayMap,
|
||||
virtualKeyboard: en_US.virtualKeyboard
|
||||
};
|
|
@ -3,14 +3,12 @@ import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
|
|||
const name = "English (US)";
|
||||
const isoCode = "en-US";
|
||||
|
||||
// dead keys for "international" 101 keyboards TODO
|
||||
/*
|
||||
// dead keys
|
||||
const keyAcute = { key: "Quote", control: true, menu: true, mark: "´" } // acute accent
|
||||
const keyCedilla = { key: ".", shift: true, alt: true, mark: "¸" } // cedilla accent
|
||||
const keyComma = { key: "BracketRight", shift: true, altRight: true, mark: "," } // comma accent
|
||||
const keyDiaeresis = { key: "Quote", shift: true, control: true, menu: true, mark: "¨" } // diaeresis accent
|
||||
const keyDegree = { key: "Semicolon", shift: true, control: true, menu: true, mark: "°" } // degree accent
|
||||
*/
|
||||
|
||||
export const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
|
@ -143,7 +141,7 @@ export const keyDisplayMap: Record<string, string> = {
|
|||
CtrlAltDelete: "Ctrl + Alt + Delete",
|
||||
AltMetaEscape: "Alt + Meta + Escape",
|
||||
CtrlAltBackspace: "Ctrl + Alt + Backspace",
|
||||
AltGr: "AltGr",
|
||||
AltGraph: "AltGr",
|
||||
AltLeft: "Alt",
|
||||
AltRight: "Alt",
|
||||
ArrowDown: "↓",
|
||||
|
@ -162,7 +160,6 @@ export const keyDisplayMap: Record<string, string> = {
|
|||
Escape: "Esc",
|
||||
Home: "Home",
|
||||
Insert: "Insert",
|
||||
Menu: "Menu",
|
||||
MetaLeft: "Meta",
|
||||
MetaRight: "Meta",
|
||||
PageDown: "PgDn",
|
||||
|
|
|
@ -36,11 +36,9 @@ const chars = {
|
|||
b: { key: "KeyB" },
|
||||
|
||||
C: { key: "KeyC", shift: true },
|
||||
"Ć": { key: "KeyC", shift: true, accentKey: keyAcute },
|
||||
"Č": { key: "KeyC", shift: true, accentKey: keyHacek },
|
||||
"Ç": { key: "KeyC", shift: true, accentKey: keyCedilla }, // "Ç": { key: "Backslash", shift: true },
|
||||
c: { key: "KeyC" },
|
||||
"ć": { key: "KeyC", shift: false, accentKey: keyAcute },
|
||||
"č": { key: "KeyC", accentKey: keyHacek },
|
||||
"ç": { key: "KeyC", accentKey: keyCedilla }, // "ç": { key: "Backslash" },
|
||||
|
||||
|
@ -58,7 +56,7 @@ const chars = {
|
|||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTylda },
|
||||
e: { key: "KeyE" },
|
||||
"ę": { key: "KeyE", ctrl: true, alt: true, accentKey: keyOgonek },
|
||||
"ę": { key: "KeyE", ctrl: true, meta: true, accentKey: keyOgonek },
|
||||
"ë": { key: "KeyE", accentKey: keyDiaresis },
|
||||
"ě": { key: "KeyE", accentKey: keyHacek },
|
||||
"é": { key: "KeyE", accentKey: keyAcute },
|
||||
|
@ -88,6 +86,7 @@ const chars = {
|
|||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTylda },
|
||||
|
||||
|
||||
J: { key: "KeyJ", shift: true },
|
||||
j: { key: "KeyJ" },
|
||||
|
||||
|
@ -176,7 +175,7 @@ const chars = {
|
|||
Z: { key: "KeyZ", shift: true },
|
||||
"Ž": { key: "KeyZ", shift: true, accentKey: keyHacek },
|
||||
"Ź": { key: "KeyZ", shift: true, ctrl: true, meta: true, accentKey: keyAcute },
|
||||
z: { key: "KeyZ" },
|
||||
z: { key: "KeyZ" }, W: { key: "KeyW", shift: true },
|
||||
"ž": { key: "KeyZ", accentKey: keyHacek },
|
||||
"ź": { key: "KeyX",ctrl: true, meta: true, accentKey: keyAcute }, // not a typo, it's on the X key
|
||||
"ż": { key: "KeyZ", ctrl: true, meta: true, accentKey: keyDotAbove },
|
||||
|
@ -191,29 +190,30 @@ const chars = {
|
|||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
"·": { key: "Digit3", shift: true },
|
||||
"#": { key: "Digit3", altRight: true },
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"^": { key: "Digit6", shift: true },
|
||||
"&": { key: "Digit6", shift: true },
|
||||
"¬": { key: "Digit6", altRight: true },
|
||||
7: { key: "Digit7" },
|
||||
"&": { key: "Digit7", shift: true },
|
||||
"/": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"*": { key: "Digit8", shift: true },
|
||||
"(": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
"(": { key: "Digit9", shift: true },
|
||||
")": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
")": { key: "Digit0", shift: true },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"'": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"¡": { key: "Equal", deadKey: true },
|
||||
"¿": { key: "Equal", shift: true },
|
||||
"[": { key: "BracketLeft", altRight: true },
|
||||
"+": { key: "BracketRight" },
|
||||
//"*": { key: "BracketRight", shift: true },
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
"]": { key: "BracketRight", altRight: true },
|
||||
"ñ": { key: "Semicolon" },
|
||||
"Ñ": { key: "Semicolon", shift: true },
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
export const keys = {
|
||||
Again: 0x79,
|
||||
AlternateErase: 0x9d,
|
||||
AltGr: 0xe6, // aka AltRight
|
||||
AltGraph: 0xe5,
|
||||
AltLeft: 0xe2,
|
||||
AltRight: 0xe6,
|
||||
Application: 0x65,
|
||||
|
@ -262,7 +262,6 @@ export const modifiers = {
|
|||
AltRight: 0x40,
|
||||
MetaLeft: 0x08,
|
||||
MetaRight: 0x80,
|
||||
AltGr: 0x40,
|
||||
} as Record<string, number>;
|
||||
|
||||
export const hidKeyToModifierMask = {
|
||||
|
@ -272,18 +271,6 @@ export const hidKeyToModifierMask = {
|
|||
0xe3: modifiers.MetaLeft,
|
||||
0xe4: modifiers.ControlRight,
|
||||
0xe5: modifiers.ShiftRight,
|
||||
0xe6: modifiers.AltRight, // can also be AltGr
|
||||
0xe6: modifiers.AltRight,
|
||||
0xe7: modifiers.MetaRight,
|
||||
} as Record<number, number>;
|
||||
|
||||
export const latchingKeys = ["CapsLock", "ScrollLock", "NumLock", "Meta", "Compose", "Kana"];
|
||||
|
||||
export function decodeModifiers(modifier: number) {
|
||||
return {
|
||||
isShiftActive: (modifier & (modifiers.ShiftLeft | modifiers.ShiftRight)) !== 0,
|
||||
isControlActive: (modifier & (modifiers.ControlLeft | modifiers.ControlRight)) !== 0,
|
||||
isAltActive: (modifier & (modifiers.AltLeft | modifiers.AltRight)) !== 0,
|
||||
isMetaActive: (modifier & (modifiers.MetaLeft | modifiers.MetaRight)) !== 0,
|
||||
isAltGrActive: (modifier & modifiers.AltGr) !== 0,
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue