]> git.proxmox.com Git - mirror_novnc.git/blame - core/input/util.js
Drop support for legacy Edge
[mirror_novnc.git] / core / input / util.js
CommitLineData
75839905 1import KeyTable from "./keysym.js";
3ae0bb09 2import keysyms from "./keysymdef.js";
80cb8ffd 3import vkeys from "./vkeys.js";
f714f7de 4import fixedkeys from "./fixedkeys.js";
9782d4a3 5import DOMKeyTable from "./domkeytable.js";
59ef2916 6import * as browser from "../util/browser.js";
4ef7566b 7
80cb8ffd 8// Get 'KeyboardEvent.code', handling legacy browsers
3f1cda2e 9export function getKeycode(evt) {
80cb8ffd
PO
10 // Are we getting proper key identifiers?
11 // (unfortunately Firefox and Chrome are crappy here and gives
12 // us an empty string on some platforms, rather than leaving it
13 // undefined)
14 if (evt.code) {
15 // Mozilla isn't fully in sync with the spec yet
16 switch (evt.code) {
17 case 'OSLeft': return 'MetaLeft';
18 case 'OSRight': return 'MetaRight';
19 }
20
21 return evt.code;
6d6f0db0 22 }
80cb8ffd
PO
23
24 // The de-facto standard is to use Windows Virtual-Key codes
25 // in the 'keyCode' field for non-printable characters. However
26 // Webkit sets it to the same as charCode in 'keypress' events.
27 if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) {
2b5f94fa 28 let code = vkeys[evt.keyCode];
80cb8ffd
PO
29
30 // macOS has messed up this code for some reason
59ef2916 31 if (browser.isMac() && (code === 'ContextMenu')) {
80cb8ffd
PO
32 code = 'MetaRight';
33 }
34
35 // The keyCode doesn't distinguish between left and right
36 // for the standard modifiers
37 if (evt.location === 2) {
38 switch (code) {
39 case 'ShiftLeft': return 'ShiftRight';
40 case 'ControlLeft': return 'ControlRight';
41 case 'AltLeft': return 'AltRight';
42 }
43 }
44
45 // Nor a bunch of the numpad keys
46 if (evt.location === 3) {
47 switch (code) {
48 case 'Delete': return 'NumpadDecimal';
49 case 'Insert': return 'Numpad0';
50 case 'End': return 'Numpad1';
51 case 'ArrowDown': return 'Numpad2';
52 case 'PageDown': return 'Numpad3';
53 case 'ArrowLeft': return 'Numpad4';
54 case 'ArrowRight': return 'Numpad6';
55 case 'Home': return 'Numpad7';
56 case 'ArrowUp': return 'Numpad8';
57 case 'PageUp': return 'Numpad9';
58 case 'Enter': return 'NumpadEnter';
59 }
60 }
61
62 return code;
6d6f0db0 63 }
80cb8ffd
PO
64
65 return 'Unidentified';
6d6f0db0
SR
66}
67
9782d4a3
PO
68// Get 'KeyboardEvent.key', handling legacy browsers
69export function getKey(evt) {
70 // Are we getting a proper key value?
71 if (evt.key !== undefined) {
72 // IE and Edge use some ancient version of the spec
73 // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
74 switch (evt.key) {
75 case 'Spacebar': return ' ';
76 case 'Esc': return 'Escape';
77 case 'Scroll': return 'ScrollLock';
78 case 'Win': return 'Meta';
79 case 'Apps': return 'ContextMenu';
80 case 'Up': return 'ArrowUp';
81 case 'Left': return 'ArrowLeft';
82 case 'Right': return 'ArrowRight';
83 case 'Down': return 'ArrowDown';
84 case 'Del': return 'Delete';
85 case 'Divide': return '/';
86 case 'Multiply': return '*';
87 case 'Subtract': return '-';
88 case 'Add': return '+';
89 case 'Decimal': return evt.char;
90 }
91
92 // Mozilla isn't fully in sync with the spec yet
93 switch (evt.key) {
94 case 'OS': return 'Meta';
ebee9cdd
PO
95 case 'LaunchMyComputer': return 'LaunchApplication1';
96 case 'LaunchCalculator': return 'LaunchApplication2';
9782d4a3
PO
97 }
98
e7c4d669
PO
99 // iOS leaks some OS names
100 switch (evt.key) {
101 case 'UIKeyInputUpArrow': return 'ArrowUp';
102 case 'UIKeyInputDownArrow': return 'ArrowDown';
103 case 'UIKeyInputLeftArrow': return 'ArrowLeft';
104 case 'UIKeyInputRightArrow': return 'ArrowRight';
105 case 'UIKeyInputEscape': return 'Escape';
106 }
107
9d956e91
PO
108 // Broken behaviour in Chrome
109 if ((evt.key === '\x00') && (evt.code === 'NumpadDecimal')) {
110 return 'Delete';
111 }
112
dccf6fac 113 return evt.key;
9782d4a3 114 }
bfa1b237 115
9782d4a3 116 // Try to deduce it based on the physical key
2b5f94fa 117 const code = getKeycode(evt);
f714f7de
PO
118 if (code in fixedkeys) {
119 return fixedkeys[code];
6d6f0db0 120 }
bfa1b237 121
9782d4a3
PO
122 // If that failed, then see if we have a printable character
123 if (evt.charCode) {
124 return String.fromCharCode(evt.charCode);
125 }
4ef7566b 126
9782d4a3
PO
127 // At this point we have nothing left to go on
128 return 'Unidentified';
129}
130
131// Get the most reliable keysym value we can get from a key event
3f1cda2e 132export function getKeysym(evt) {
2b5f94fa 133 const key = getKey(evt);
9782d4a3
PO
134
135 if (key === 'Unidentified') {
136 return null;
4ef7566b 137 }
138
9782d4a3
PO
139 // First look up special keys
140 if (key in DOMKeyTable) {
2b5f94fa 141 let location = evt.location;
f714f7de 142
9782d4a3
PO
143 // Safari screws up location for the right cmd key
144 if ((key === 'Meta') && (location === 0)) {
145 location = 2;
f714f7de 146 }
4ef7566b 147
3388c92c
PO
148 // And for Clear
149 if ((key === 'Clear') && (location === 3)) {
150 let code = getKeycode(evt);
151 if (code === 'NumLock') {
152 location = 0;
153 }
154 }
155
9782d4a3
PO
156 if ((location === undefined) || (location > 3)) {
157 location = 0;
f714f7de 158 }
4ef7566b 159
75839905
PO
160 // The original Meta key now gets confused with the Windows key
161 // https://bugs.chromium.org/p/chromium/issues/detail?id=1020141
162 // https://bugzilla.mozilla.org/show_bug.cgi?id=1232918
163 if (key === 'Meta') {
164 let code = getKeycode(evt);
165 if (code === 'AltLeft') {
166 return KeyTable.XK_Meta_L;
167 } else if (code === 'AltRight') {
168 return KeyTable.XK_Meta_R;
169 }
170 }
171
3388c92c
PO
172 // macOS has Clear instead of NumLock, but the remote system is
173 // probably not macOS, so lying here is probably best...
174 if (key === 'Clear') {
175 let code = getKeycode(evt);
176 if (code === 'NumLock') {
177 return KeyTable.XK_Num_Lock;
178 }
179 }
180
9782d4a3 181 return DOMKeyTable[key][location];
6d6f0db0 182 }
282834ca 183
f714f7de 184 // Now we need to look at the Unicode symbol instead
4ef7566b 185
9782d4a3
PO
186 // Special key? (FIXME: Should have been caught earlier)
187 if (key.length !== 1) {
188 return null;
f714f7de 189 }
6d6f0db0 190
2b5f94fa 191 const codepoint = key.charCodeAt();
f714f7de
PO
192 if (codepoint) {
193 return keysyms.lookup(codepoint);
4ef7566b 194 }
f714f7de
PO
195
196 return null;
6d6f0db0 197}