Skip to content

Commit 3887f7e

Browse files
committed
Improve accent handling
1 parent 2be96d3 commit 3887f7e

File tree

4 files changed

+80
-26
lines changed

4 files changed

+80
-26
lines changed

ui/src/components/popovers/PasteModal.tsx

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ const hidKeyboardPayload = (keys: number[], modifier: number) => {
1717
return { keys, modifier };
1818
};
1919

20+
const modifierCode = (shift?: boolean, altRight?: boolean) => {
21+
return shift ? modifiers["ShiftLeft"] : 0
22+
| (altRight ? modifiers["AltRight"] : 0)
23+
}
24+
const noModifier = 0
25+
2026
export default function PasteModal() {
2127
const TextAreaRef = useRef<HTMLTextAreaElement>(null);
2228
const setPasteMode = useHidStore(state => state.setPasteModeEnabled);
@@ -58,34 +64,26 @@ export default function PasteModal() {
5864
if (!keyboardLayout) continue;
5965
if (!chars[keyboardLayout]) continue;
6066

61-
const { key, shift, altRight, space, capsLock, trema } = chars[keyboardLayout][char] ?? {};
67+
const { key, shift, altRight, deadKey, accentKey } = chars[keyboardLayout][char]
6268
if (!key) continue;
6369

6470
const keyz = [ keys[key] ];
65-
const modz = [ shift ? modifiers["ShiftLeft"] : 0
66-
| (altRight ? modifiers["AltRight"] : 0) ];
71+
const modz = [ modifierCode(shift, altRight) ];
6772

68-
if (space) {
73+
if (deadKey) {
6974
keyz.push(keys["Space"]);
70-
modz.push(0);
71-
}
72-
if (capsLock) {
73-
keyz.unshift(keys["CapsLock"]);
74-
modz.unshift(0);
75-
76-
keyz.push(keys["CapsLock"]);
77-
modz.push(0);
75+
modz.push(noModifier);
7876
}
79-
if (trema) {
80-
keyz.unshift(keys["BracketRight"]); // trema ¨
81-
modz.unshift(0)
77+
if (accentKey) {
78+
keyz.unshift(keys[accentKey.key])
79+
modz.unshift(modifierCode(accentKey.shift, accentKey.altRight))
8280
}
8381

84-
for (const [index, keyy] of keyz.entries()) {
82+
for (const [index, kei] of keyz.entries()) {
8583
await new Promise<void>((resolve, reject) => {
8684
send(
8785
"keyboardReport",
88-
hidKeyboardPayload([keyy], modz[index]),
86+
hidKeyboardPayload([kei], modz[index]),
8987
params => {
9088
if ("error" in params) return reject(params.error);
9189
send("keyboardReport", hidKeyboardPayload([], 0), params => {
@@ -172,7 +170,7 @@ export default function PasteModal() {
172170
</div>
173171
<div className="space-y-4">
174172
<p className="text-xs text-slate-600 dark:text-slate-400">
175-
Sending key codes for keyboard layout {layouts[keyboardLayout]}
173+
Sending key codes using keyboard layout {layouts[keyboardLayout]}
176174
</p>
177175
</div>
178176
</div>

ui/src/keyboardLayouts.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { chars as chars_en_US } from "@/keyboardLayouts/en_US"
22
import { chars as chars_de_CH } from "@/keyboardLayouts/de_CH"
33

4+
type KeyInfo = { key: string | number; shift?: boolean, altRight?: boolean }
5+
export type KeyCombo = KeyInfo & { deadKey?: boolean, accentKey?: KeyInfo }
6+
47
export const layouts = {
58
"en_US": "English (US)",
69
"de_CH": "Swiss German"
@@ -9,4 +12,4 @@ export const layouts = {
912
export const chars = {
1013
"en_US": chars_en_US,
1114
"de_CH": chars_de_CH,
12-
} as Record<string, Record<string, { key: string | number; shift?: boolean, altRight?: boolean, space?: boolean, capsLock?: boolean, trema?: boolean }>>;
15+
} as Record<string, Record <string, KeyCombo>>

ui/src/keyboardLayouts/de_CH.ts

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,90 @@
1+
import { KeyCombo } from "../keyboardLayouts"
2+
3+
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
4+
const keyAcute = { key: "Minus", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter
5+
const keyHat = { key: "Equal" } // accent circonflexe (accent hat), mark ^ placed above the letter
6+
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
7+
const keyTilde = { key: "Equal", altRight: true } // tilde, mark ~ placed above the letter
8+
19
export const chars = {
210
A: { key: "KeyA", shift: true },
3-
"Ä": { key: "KeyA", shift: true, trema: true },
11+
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
12+
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
13+
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
14+
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
15+
"Ã": { key: "KeyA", shift: true, accentKey: keyTilde },
16+
"Æ": { key: "KeyA", shift: true, altRight: true },
417
B: { key: "KeyB", shift: true },
518
C: { key: "KeyC", shift: true },
619
D: { key: "KeyD", shift: true },
720
E: { key: "KeyE", shift: true },
21+
"Ë": { key: "KeyE", shift: true, accentKey: keyTrema },
22+
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
23+
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
24+
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
25+
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTilde },
826
F: { key: "KeyF", shift: true },
927
G: { key: "KeyG", shift: true },
1028
H: { key: "KeyH", shift: true },
1129
I: { key: "KeyI", shift: true },
30+
"Ï": { key: "KeyI", shift: true, accentKey: keyTrema },
31+
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
32+
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
33+
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
34+
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTilde },
1235
J: { key: "KeyJ", shift: true },
1336
K: { key: "KeyK", shift: true },
1437
L: { key: "KeyL", shift: true },
1538
M: { key: "KeyM", shift: true },
1639
N: { key: "KeyN", shift: true },
1740
O: { key: "KeyO", shift: true },
18-
"Ö": { key: "KeyO", shift: true, trema: true },
41+
"Ö": { key: "KeyO", shift: true, accentKey: keyTrema },
42+
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute },
43+
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
44+
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
45+
"Õ": { key: "KeyO", shift: true, accentKey: keyTilde },
46+
"Œ": { key: "KeyO", shift: true, altRight: true },
1947
P: { key: "KeyP", shift: true },
2048
Q: { key: "KeyQ", shift: true },
2149
R: { key: "KeyR", shift: true },
2250
S: { key: "KeyS", shift: true },
2351
T: { key: "KeyT", shift: true },
2452
U: { key: "KeyU", shift: true },
25-
"Ü": { key: "KeyU", shift: true, trema: true },
53+
"Ü": { key: "KeyU", shift: true, accentKey: keyTrema },
54+
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
55+
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
56+
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
57+
"Ũ": { key: "KeyU", shift: true, accentKey: keyTilde },
2658
V: { key: "KeyV", shift: true },
2759
W: { key: "KeyW", shift: true },
2860
X: { key: "KeyX", shift: true },
2961
Y: { key: "KeyZ", shift: true },
3062
Z: { key: "KeyY", shift: true },
3163
a: { key: "KeyA" },
64+
"á": { key: "KeyA", accentKey: keyAcute },
65+
"â": { key: "KeyA", accentKey: keyHat },
66+
"ã": { key: "KeyA", accentKey: keyTilde },
3267
"æ": { key: "KeyA", altRight: true },
3368
b: { key: "KeyB" },
3469
c: { key: "KeyC" },
3570
d: { key: "KeyD" },
3671
"ð": { key: "KeyD", altRight: true },
3772
e: { key: "KeyE" },
73+
"ë": { key: "KeyE", accentKey: keyTrema },
74+
"ê": { key: "KeyE", accentKey: keyHat },
75+
"ẽ": { key: "KeyE", accentKey: keyTilde },
3876
f: { key: "KeyF" },
3977
"đ": { key: "KeyF", altRight: true },
4078
g: { key: "KeyG" },
4179
"ŋ": { key: "KeyG", altRight: true },
4280
h: { key: "KeyH" },
4381
"ħ": { key: "KeyH", altRight: true },
4482
i: { key: "KeyI" },
83+
"ï": { key: "KeyI", accentKey: keyTrema },
84+
"í": { key: "KeyI", accentKey: keyAcute },
85+
"î": { key: "KeyI", accentKey: keyHat },
86+
"ì": { key: "KeyI", accentKey: keyGrave },
87+
"ĩ": { key: "KeyI", accentKey: keyTilde },
4588
"→": { key: "KeyI", altRight: true },
4689
j: { key: "KeyJ" },
4790
k: { key: "KeyK" },
@@ -52,6 +95,10 @@ export const chars = {
5295
"µ": { key: "KeyM", altRight: true },
5396
n: { key: "KeyN" },
5497
o: { key: "KeyO" },
98+
"ó": { key: "KeyO", accentKey: keyAcute },
99+
"ô": { key: "KeyO", accentKey: keyHat },
100+
"ò": { key: "KeyO", accentKey: keyGrave },
101+
"õ": { key: "KeyO", accentKey: keyTilde },
55102
"œ": { key: "KeyO", altRight: true },
56103
p: { key: "KeyP" },
57104
"þ": { key: "KeyP", altRight: true },
@@ -63,6 +110,10 @@ export const chars = {
63110
t: { key: "KeyT" },
64111
"ŧ": { key: "KeyT", altRight: true },
65112
u: { key: "KeyU" },
113+
"ú": { key: "KeyU", accentKey: keyAcute },
114+
"û": { key: "KeyU", accentKey: keyHat },
115+
"ù": { key: "KeyU", accentKey: keyGrave },
116+
"ũ": { key: "KeyU", accentKey: keyTilde },
66117
"↓": { key: "KeyU", altRight: true },
67118
v: { key: "KeyV" },
68119
"„": { key: "KeyV", altRight: true },
@@ -105,9 +156,9 @@ export const chars = {
105156
"=": { key: "Digit0", shift: true },
106157
"'": { key: "Minus" },
107158
"?": { key: "Minus", shift: true },
108-
"^": { key: "Equal", space: true }, // dead key
159+
"^": { key: "Equal", deadKey: true },
109160
"`": { key: "Equal", shift: true },
110-
"~": { key: "Equal", altRight: true, space: true }, // dead key
161+
"~": { key: "Equal", altRight: true, deadKey: true },
111162
"ü": { key: "BracketLeft" },
112163
"è": { key: "BracketLeft", shift: true },
113164
"[": { key: "BracketLeft", altRight: true },
@@ -137,4 +188,4 @@ export const chars = {
137188
"\n": { key: "Enter" },
138189
Enter: { key: "Enter" },
139190
Tab: { key: "Tab" },
140-
} as Record<string, { key: string | number; shift?: boolean, altRight?: boolean, space?: boolean, capsLock?: boolean, trema?: boolean }>
191+
} as Record<string, KeyCombo>;

ui/src/keyboardLayouts/en_US.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { KeyCombo } from "../keyboardLayouts"
2+
13
export const chars = {
24
A: { key: "KeyA", shift: true },
35
B: { key: "KeyB", shift: true },
@@ -99,4 +101,4 @@ export const chars = {
99101
"\n": { key: "Enter", shift: false },
100102
Enter: { key: "Enter", shift: false },
101103
Tab: { key: "Tab", shift: false },
102-
} as Record<string, { key: string | number; shift: boolean }>
104+
} as Record<string, KeyCombo>

0 commit comments

Comments
 (0)