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