1use std::{
2 fmt::Display,
3 hash::{Hash, Hasher},
4 str::FromStr,
5};
6
7use crate::keyboard::{Key, KeyCode, NativeKey, PhysicalKey};
8
9#[derive(Clone, Debug, Eq)]
10pub enum KeyInput {
11 Keyboard(crate::keyboard::Key, crate::keyboard::PhysicalKey),
12 Pointer(crate::pointer::PointerButton),
13}
14
15impl KeyInput {
16 fn keyboard_from_str(s: &str) -> Option<(Key, PhysicalKey)> {
17 fn is_key_string(s: &str) -> bool {
19 s.chars().all(|c| !c.is_control()) && s.chars().skip(1).all(|c| !c.is_ascii())
20 }
21
22 fn char_to_keycode(char: &str) -> PhysicalKey {
23 match char {
24 "a" => PhysicalKey::Code(KeyCode::KeyA),
25 "b" => PhysicalKey::Code(KeyCode::KeyB),
26 "c" => PhysicalKey::Code(KeyCode::KeyC),
27 "d" => PhysicalKey::Code(KeyCode::KeyD),
28 "e" => PhysicalKey::Code(KeyCode::KeyE),
29 "f" => PhysicalKey::Code(KeyCode::KeyF),
30 "g" => PhysicalKey::Code(KeyCode::KeyG),
31 "h" => PhysicalKey::Code(KeyCode::KeyH),
32 "i" => PhysicalKey::Code(KeyCode::KeyI),
33 "j" => PhysicalKey::Code(KeyCode::KeyJ),
34 "k" => PhysicalKey::Code(KeyCode::KeyK),
35 "l" => PhysicalKey::Code(KeyCode::KeyL),
36 "m" => PhysicalKey::Code(KeyCode::KeyM),
37 "n" => PhysicalKey::Code(KeyCode::KeyN),
38 "o" => PhysicalKey::Code(KeyCode::KeyO),
39 "p" => PhysicalKey::Code(KeyCode::KeyP),
40 "q" => PhysicalKey::Code(KeyCode::KeyQ),
41 "r" => PhysicalKey::Code(KeyCode::KeyR),
42 "s" => PhysicalKey::Code(KeyCode::KeyS),
43 "t" => PhysicalKey::Code(KeyCode::KeyT),
44 "u" => PhysicalKey::Code(KeyCode::KeyU),
45 "v" => PhysicalKey::Code(KeyCode::KeyV),
46 "w" => PhysicalKey::Code(KeyCode::KeyW),
47 "x" => PhysicalKey::Code(KeyCode::KeyX),
48 "y" => PhysicalKey::Code(KeyCode::KeyY),
49 "z" => PhysicalKey::Code(KeyCode::KeyZ),
50 "=" => PhysicalKey::Code(KeyCode::Equal),
51 "-" => PhysicalKey::Code(KeyCode::Minus),
52 "0" => PhysicalKey::Code(KeyCode::Digit0),
53 "1" => PhysicalKey::Code(KeyCode::Digit1),
54 "2" => PhysicalKey::Code(KeyCode::Digit2),
55 "3" => PhysicalKey::Code(KeyCode::Digit3),
56 "4" => PhysicalKey::Code(KeyCode::Digit4),
57 "5" => PhysicalKey::Code(KeyCode::Digit5),
58 "6" => PhysicalKey::Code(KeyCode::Digit6),
59 "7" => PhysicalKey::Code(KeyCode::Digit7),
60 "8" => PhysicalKey::Code(KeyCode::Digit8),
61 "9" => PhysicalKey::Code(KeyCode::Digit9),
62 "`" => PhysicalKey::Code(KeyCode::Backquote),
63 "/" => PhysicalKey::Code(KeyCode::Slash),
64 "\\" => PhysicalKey::Code(KeyCode::Backslash),
65 "," => PhysicalKey::Code(KeyCode::Comma),
66 "." => PhysicalKey::Code(KeyCode::Period),
67 "*" => PhysicalKey::Code(KeyCode::NumpadMultiply),
68 "+" => PhysicalKey::Code(KeyCode::NumpadAdd),
69 ";" => PhysicalKey::Code(KeyCode::Semicolon),
70 "'" => PhysicalKey::Code(KeyCode::Quote),
71 "[" => PhysicalKey::Code(KeyCode::BracketLeft),
72 "]" => PhysicalKey::Code(KeyCode::BracketRight),
73 "<" => PhysicalKey::Code(KeyCode::IntlBackslash),
74 _ => PhysicalKey::Code(KeyCode::Fn),
75 }
76 }
77
78 use crate::keyboard::NamedKey::*;
80 Some(match s {
81 s if is_key_string(s) => {
82 let char = Key::Character(s.into());
83 (char.clone(), char_to_keycode(char.to_text().unwrap()))
84 }
85 "unidentified" => (
86 Key::Unidentified(NativeKey::Unidentified),
87 PhysicalKey::Code(KeyCode::Fn),
88 ),
89 "alt" => (Key::Named(Alt), PhysicalKey::Code(KeyCode::AltLeft)),
90 "altgraph" => (Key::Named(AltGraph), PhysicalKey::Code(KeyCode::AltRight)),
91 "capslock" => (Key::Named(CapsLock), PhysicalKey::Code(KeyCode::CapsLock)),
92 "control" => (Key::Named(Control), PhysicalKey::Code(KeyCode::ControlLeft)),
93 "fn" => (Key::Named(Fn), PhysicalKey::Code(KeyCode::Fn)),
94 "fnlock" => (Key::Named(FnLock), PhysicalKey::Code(KeyCode::FnLock)),
95 "meta" => (Key::Named(Meta), PhysicalKey::Code(KeyCode::Meta)),
96 "numlock" => (Key::Named(NumLock), PhysicalKey::Code(KeyCode::NumLock)),
97 "scrolllock" => (
98 Key::Named(ScrollLock),
99 PhysicalKey::Code(KeyCode::ScrollLock),
100 ),
101 "shift" => (Key::Named(Shift), PhysicalKey::Code(KeyCode::ShiftLeft)),
102 "symbol" => (Key::Named(Symbol), PhysicalKey::Code(KeyCode::Fn)),
103 "symbollock" => (Key::Named(SymbolLock), PhysicalKey::Code(KeyCode::Fn)),
104 "hyper" => (Key::Named(Hyper), PhysicalKey::Code(KeyCode::Hyper)),
105 "super" => (Key::Named(Super), PhysicalKey::Code(KeyCode::Meta)),
106 "enter" => (Key::Named(Enter), PhysicalKey::Code(KeyCode::Enter)),
107 "tab" => (Key::Named(Tab), PhysicalKey::Code(KeyCode::Tab)),
108 "arrowdown" => (Key::Named(ArrowDown), PhysicalKey::Code(KeyCode::ArrowDown)),
109 "arrowleft" => (Key::Named(ArrowLeft), PhysicalKey::Code(KeyCode::ArrowLeft)),
110 "arrowright" => (
111 Key::Named(ArrowRight),
112 PhysicalKey::Code(KeyCode::ArrowRight),
113 ),
114 "arrowup" => (Key::Named(ArrowUp), PhysicalKey::Code(KeyCode::ArrowUp)),
115 "end" => (Key::Named(End), PhysicalKey::Code(KeyCode::End)),
116 "home" => (Key::Named(Home), PhysicalKey::Code(KeyCode::Home)),
117 "pagedown" => (Key::Named(PageDown), PhysicalKey::Code(KeyCode::PageDown)),
118 "pageup" => (Key::Named(PageUp), PhysicalKey::Code(KeyCode::PageUp)),
119 "backspace" => (Key::Named(Backspace), PhysicalKey::Code(KeyCode::Backspace)),
120 "clear" => (Key::Named(Clear), PhysicalKey::Code(KeyCode::Fn)),
121 "copy" => (Key::Named(Copy), PhysicalKey::Code(KeyCode::Copy)),
122 "crsel" => (Key::Named(CrSel), PhysicalKey::Code(KeyCode::Fn)),
123 "cut" => (Key::Named(Cut), PhysicalKey::Code(KeyCode::Cut)),
124 "delete" => (Key::Named(Delete), PhysicalKey::Code(KeyCode::Delete)),
125 "eraseeof" => (Key::Named(EraseEof), PhysicalKey::Code(KeyCode::Fn)),
126 "exsel" => (Key::Named(ExSel), PhysicalKey::Code(KeyCode::Fn)),
127 "insert" => (Key::Named(Insert), PhysicalKey::Code(KeyCode::Insert)),
128 "paste" => (Key::Named(Paste), PhysicalKey::Code(KeyCode::Paste)),
129 "redo" => (Key::Named(Redo), PhysicalKey::Code(KeyCode::Fn)),
130 "undo" => (Key::Named(Undo), PhysicalKey::Code(KeyCode::Undo)),
131 "accept" => (Key::Named(Accept), PhysicalKey::Code(KeyCode::Fn)),
132 "again" => (Key::Named(Again), PhysicalKey::Code(KeyCode::Again)),
133 "attn" => (Key::Named(Attn), PhysicalKey::Code(KeyCode::Fn)),
134 "cancel" => (Key::Named(Cancel), PhysicalKey::Code(KeyCode::Fn)),
135 "contextmenu" => (
136 Key::Named(ContextMenu),
137 PhysicalKey::Code(KeyCode::ContextMenu),
138 ),
139 "escape" => (Key::Named(Escape), PhysicalKey::Code(KeyCode::Escape)),
140 "execute" => (Key::Named(Execute), PhysicalKey::Code(KeyCode::Fn)),
141 "find" => (Key::Named(Find), PhysicalKey::Code(KeyCode::Find)),
142 "help" => (Key::Named(Help), PhysicalKey::Code(KeyCode::Help)),
143 "pause" => (Key::Named(Pause), PhysicalKey::Code(KeyCode::Pause)),
144 "play" => (Key::Named(Play), PhysicalKey::Code(KeyCode::MediaPlayPause)),
145 "props" => (Key::Named(Props), PhysicalKey::Code(KeyCode::Props)),
146 "select" => (Key::Named(Select), PhysicalKey::Code(KeyCode::Select)),
147 "zoomin" => (Key::Named(ZoomIn), PhysicalKey::Code(KeyCode::Fn)),
148 "zoomout" => (Key::Named(ZoomOut), PhysicalKey::Code(KeyCode::Fn)),
149 "brightnessdown" => (Key::Named(BrightnessDown), PhysicalKey::Code(KeyCode::Fn)),
150 "brightnessup" => (Key::Named(BrightnessUp), PhysicalKey::Code(KeyCode::Fn)),
151 "eject" => (Key::Named(Eject), PhysicalKey::Code(KeyCode::Eject)),
152 "logoff" => (Key::Named(LogOff), PhysicalKey::Code(KeyCode::Fn)),
153 "power" => (Key::Named(Power), PhysicalKey::Code(KeyCode::Power)),
154 "poweroff" => (Key::Named(PowerOff), PhysicalKey::Code(KeyCode::Fn)),
155 "printscreen" => (
156 Key::Named(PrintScreen),
157 PhysicalKey::Code(KeyCode::PrintScreen),
158 ),
159 "hibernate" => (Key::Named(Hibernate), PhysicalKey::Code(KeyCode::Fn)),
160 "standby" => (Key::Named(Standby), PhysicalKey::Code(KeyCode::Fn)),
161 "wakeup" => (Key::Named(WakeUp), PhysicalKey::Code(KeyCode::WakeUp)),
162 "allcandidates" => (Key::Named(AllCandidates), PhysicalKey::Code(KeyCode::Fn)),
163 "alphanumeric" => (Key::Named(Alphanumeric), PhysicalKey::Code(KeyCode::Fn)),
164 "codeinput" => (Key::Named(CodeInput), PhysicalKey::Code(KeyCode::Fn)),
165 "compose" => (Key::Named(Compose), PhysicalKey::Code(KeyCode::Fn)),
166 "convert" => (Key::Named(Convert), PhysicalKey::Code(KeyCode::Convert)),
167 "dead" => (Key::Dead(None), PhysicalKey::Code(KeyCode::Fn)),
168 "finalmode" => (Key::Named(FinalMode), PhysicalKey::Code(KeyCode::Fn)),
169 "groupfirst" => (Key::Named(GroupFirst), PhysicalKey::Code(KeyCode::Fn)),
170 "grouplast" => (Key::Named(GroupLast), PhysicalKey::Code(KeyCode::Fn)),
171 "groupnext" => (Key::Named(GroupNext), PhysicalKey::Code(KeyCode::Fn)),
172 "groupprevious" => (Key::Named(GroupPrevious), PhysicalKey::Code(KeyCode::Fn)),
173 "modechange" => (Key::Named(ModeChange), PhysicalKey::Code(KeyCode::Fn)),
174 "nextcandidate" => (Key::Named(NextCandidate), PhysicalKey::Code(KeyCode::Fn)),
175 "nonconvert" => (
176 Key::Named(NonConvert),
177 PhysicalKey::Code(KeyCode::NonConvert),
178 ),
179 "previouscandidate" => (
180 Key::Named(PreviousCandidate),
181 PhysicalKey::Code(KeyCode::Fn),
182 ),
183 "process" => (Key::Named(Process), PhysicalKey::Code(KeyCode::Fn)),
184 "singlecandidate" => (Key::Named(SingleCandidate), PhysicalKey::Code(KeyCode::Fn)),
185 "hangulmode" => (Key::Named(HangulMode), PhysicalKey::Code(KeyCode::Fn)),
186 "hanjamode" => (Key::Named(HanjaMode), PhysicalKey::Code(KeyCode::Fn)),
187 "junjamode" => (Key::Named(JunjaMode), PhysicalKey::Code(KeyCode::Fn)),
188 "eisu" => (Key::Named(Eisu), PhysicalKey::Code(KeyCode::Fn)),
189 "hankaku" => (Key::Named(Hankaku), PhysicalKey::Code(KeyCode::Fn)),
190 "hiragana" => (Key::Named(Hiragana), PhysicalKey::Code(KeyCode::Hiragana)),
191 "hiraganakatakana" => (Key::Named(HiraganaKatakana), PhysicalKey::Code(KeyCode::Fn)),
192 "kanamode" => (Key::Named(KanaMode), PhysicalKey::Code(KeyCode::KanaMode)),
193 "kanjimode" => (Key::Named(KanjiMode), PhysicalKey::Code(KeyCode::Fn)),
194 "katakana" => (Key::Named(Katakana), PhysicalKey::Code(KeyCode::Katakana)),
195 "romaji" => (Key::Named(Romaji), PhysicalKey::Code(KeyCode::Fn)),
196 "zenkaku" => (Key::Named(Zenkaku), PhysicalKey::Code(KeyCode::Fn)),
197 "zenkakuhankaku" => (Key::Named(ZenkakuHankaku), PhysicalKey::Code(KeyCode::Fn)),
198 "f1" => (Key::Named(F1), PhysicalKey::Code(KeyCode::F1)),
199 "f2" => (Key::Named(F2), PhysicalKey::Code(KeyCode::F2)),
200 "f3" => (Key::Named(F3), PhysicalKey::Code(KeyCode::F3)),
201 "f4" => (Key::Named(F4), PhysicalKey::Code(KeyCode::F4)),
202 "f5" => (Key::Named(F5), PhysicalKey::Code(KeyCode::F5)),
203 "f6" => (Key::Named(F6), PhysicalKey::Code(KeyCode::F6)),
204 "f7" => (Key::Named(F7), PhysicalKey::Code(KeyCode::F7)),
205 "f8" => (Key::Named(F8), PhysicalKey::Code(KeyCode::F8)),
206 "f9" => (Key::Named(F9), PhysicalKey::Code(KeyCode::F9)),
207 "f10" => (Key::Named(F10), PhysicalKey::Code(KeyCode::F10)),
208 "f11" => (Key::Named(F11), PhysicalKey::Code(KeyCode::F11)),
209 "f12" => (Key::Named(F12), PhysicalKey::Code(KeyCode::F12)),
210 "soft1" => (Key::Named(Soft1), PhysicalKey::Code(KeyCode::Fn)),
211 "soft2" => (Key::Named(Soft2), PhysicalKey::Code(KeyCode::Fn)),
212 "soft3" => (Key::Named(Soft3), PhysicalKey::Code(KeyCode::Fn)),
213 "soft4" => (Key::Named(Soft4), PhysicalKey::Code(KeyCode::Fn)),
214 "channeldown" => (Key::Named(ChannelDown), PhysicalKey::Code(KeyCode::Fn)),
215 "channelup" => (Key::Named(ChannelUp), PhysicalKey::Code(KeyCode::Fn)),
216 "close" => (Key::Named(Close), PhysicalKey::Code(KeyCode::Fn)),
217 "mailforward" => (Key::Named(MailForward), PhysicalKey::Code(KeyCode::Fn)),
218 "mailreply" => (Key::Named(MailReply), PhysicalKey::Code(KeyCode::Fn)),
219 "mailsend" => (Key::Named(MailSend), PhysicalKey::Code(KeyCode::Fn)),
220 "mediaclose" => (Key::Named(MediaClose), PhysicalKey::Code(KeyCode::Fn)),
221 "mediafastforward" => (Key::Named(MediaFastForward), PhysicalKey::Code(KeyCode::Fn)),
222 "mediapause" => (Key::Named(MediaPause), PhysicalKey::Code(KeyCode::Fn)),
223 "mediaplay" => (Key::Named(MediaPlay), PhysicalKey::Code(KeyCode::Fn)),
224 "mediaplaypause" => (
225 Key::Named(MediaPlayPause),
226 PhysicalKey::Code(KeyCode::MediaPlayPause),
227 ),
228 "mediarecord" => (Key::Named(MediaRecord), PhysicalKey::Code(KeyCode::Fn)),
229 "mediarewind" => (Key::Named(MediaRewind), PhysicalKey::Code(KeyCode::Fn)),
230 "mediastop" => (Key::Named(MediaStop), PhysicalKey::Code(KeyCode::MediaStop)),
231 "mediatracknext" => (
232 Key::Named(MediaTrackNext),
233 PhysicalKey::Code(KeyCode::MediaTrackNext),
234 ),
235 "mediatrackprevious" => (
236 Key::Named(MediaTrackPrevious),
237 PhysicalKey::Code(KeyCode::MediaTrackPrevious),
238 ),
239 "new" => (Key::Named(New), PhysicalKey::Code(KeyCode::Fn)),
240 "open" => (Key::Named(Open), PhysicalKey::Code(KeyCode::Open)),
241 "print" => (Key::Named(Print), PhysicalKey::Code(KeyCode::Fn)),
242 "save" => (Key::Named(Save), PhysicalKey::Code(KeyCode::Fn)),
243 "spellcheck" => (Key::Named(SpellCheck), PhysicalKey::Code(KeyCode::Fn)),
244 "key11" => (Key::Named(Key11), PhysicalKey::Code(KeyCode::Fn)),
245 "key12" => (Key::Named(Key12), PhysicalKey::Code(KeyCode::Fn)),
246 "audiobalanceleft" => (Key::Named(AudioBalanceLeft), PhysicalKey::Code(KeyCode::Fn)),
247 "audiobalanceright" => (
248 Key::Named(AudioBalanceRight),
249 PhysicalKey::Code(KeyCode::Fn),
250 ),
251 "audiobassboostdown" => (
252 Key::Named(AudioBassBoostDown),
253 PhysicalKey::Code(KeyCode::Fn),
254 ),
255 "audiobassboosttoggle" => (
256 Key::Named(AudioBassBoostToggle),
257 PhysicalKey::Code(KeyCode::Fn),
258 ),
259 "audiobassboostup" => (Key::Named(AudioBassBoostUp), PhysicalKey::Code(KeyCode::Fn)),
260 "audiofaderfront" => (Key::Named(AudioFaderFront), PhysicalKey::Code(KeyCode::Fn)),
261 "audiofaderrear" => (Key::Named(AudioFaderRear), PhysicalKey::Code(KeyCode::Fn)),
262 "audiosurroundmodenext" => (
263 Key::Named(AudioSurroundModeNext),
264 PhysicalKey::Code(KeyCode::Fn),
265 ),
266 "audiotrebledown" => (Key::Named(AudioTrebleDown), PhysicalKey::Code(KeyCode::Fn)),
267 "audiotrebleup" => (Key::Named(AudioTrebleUp), PhysicalKey::Code(KeyCode::Fn)),
268 "audiovolumedown" => (
269 Key::Named(AudioVolumeDown),
270 PhysicalKey::Code(KeyCode::AudioVolumeDown),
271 ),
272 "audiovolumeup" => (
273 Key::Named(AudioVolumeUp),
274 PhysicalKey::Code(KeyCode::AudioVolumeUp),
275 ),
276 "audiovolumemute" => (
277 Key::Named(AudioVolumeMute),
278 PhysicalKey::Code(KeyCode::AudioVolumeMute),
279 ),
280 "microphonetoggle" => (Key::Named(MicrophoneToggle), PhysicalKey::Code(KeyCode::Fn)),
281 "microphonevolumedown" => (
282 Key::Named(MicrophoneVolumeDown),
283 PhysicalKey::Code(KeyCode::Fn),
284 ),
285 "microphonevolumeup" => (
286 Key::Named(MicrophoneVolumeUp),
287 PhysicalKey::Code(KeyCode::Fn),
288 ),
289 "microphonevolumemute" => (
290 Key::Named(MicrophoneVolumeMute),
291 PhysicalKey::Code(KeyCode::Fn),
292 ),
293 "speechcorrectionlist" => (
294 Key::Named(SpeechCorrectionList),
295 PhysicalKey::Code(KeyCode::Fn),
296 ),
297 "speechinputtoggle" => (
298 Key::Named(SpeechInputToggle),
299 PhysicalKey::Code(KeyCode::Fn),
300 ),
301 "launchapplication1" => (
302 Key::Named(LaunchApplication1),
303 PhysicalKey::Code(KeyCode::Fn),
304 ),
305 "launchapplication2" => (
306 Key::Named(LaunchApplication2),
307 PhysicalKey::Code(KeyCode::Fn),
308 ),
309 "launchcalendar" => (Key::Named(LaunchCalendar), PhysicalKey::Code(KeyCode::Fn)),
310 "launchcontacts" => (Key::Named(LaunchContacts), PhysicalKey::Code(KeyCode::Fn)),
311 "launchmail" => (
312 Key::Named(LaunchMail),
313 PhysicalKey::Code(KeyCode::LaunchMail),
314 ),
315 "launchmediaplayer" => (
316 Key::Named(LaunchMediaPlayer),
317 PhysicalKey::Code(KeyCode::Fn),
318 ),
319 "launchmusicplayer" => (
320 Key::Named(LaunchMusicPlayer),
321 PhysicalKey::Code(KeyCode::Fn),
322 ),
323 "launchphone" => (Key::Named(LaunchPhone), PhysicalKey::Code(KeyCode::Fn)),
324 "launchscreensaver" => (
325 Key::Named(LaunchScreenSaver),
326 PhysicalKey::Code(KeyCode::Fn),
327 ),
328 "launchspreadsheet" => (
329 Key::Named(LaunchSpreadsheet),
330 PhysicalKey::Code(KeyCode::Fn),
331 ),
332 "launchwebbrowser" => (Key::Named(LaunchWebBrowser), PhysicalKey::Code(KeyCode::Fn)),
333 "launchwebcam" => (Key::Named(LaunchWebCam), PhysicalKey::Code(KeyCode::Fn)),
334 "launchwordprocessor" => (
335 Key::Named(LaunchWordProcessor),
336 PhysicalKey::Code(KeyCode::Fn),
337 ),
338 "browserback" => (
339 Key::Named(BrowserBack),
340 PhysicalKey::Code(KeyCode::BrowserBack),
341 ),
342 "browserfavorites" => (
343 Key::Named(BrowserFavorites),
344 PhysicalKey::Code(KeyCode::BrowserFavorites),
345 ),
346 "browserforward" => (
347 Key::Named(BrowserForward),
348 PhysicalKey::Code(KeyCode::BrowserForward),
349 ),
350 "browserhome" => (
351 Key::Named(BrowserHome),
352 PhysicalKey::Code(KeyCode::BrowserHome),
353 ),
354 "browserrefresh" => (
355 Key::Named(BrowserRefresh),
356 PhysicalKey::Code(KeyCode::BrowserRefresh),
357 ),
358 "browsersearch" => (
359 Key::Named(BrowserSearch),
360 PhysicalKey::Code(KeyCode::BrowserSearch),
361 ),
362 "browserstop" => (
363 Key::Named(BrowserStop),
364 PhysicalKey::Code(KeyCode::BrowserStop),
365 ),
366 "appswitch" => (Key::Named(AppSwitch), PhysicalKey::Code(KeyCode::Fn)),
367 "call" => (Key::Named(Call), PhysicalKey::Code(KeyCode::Fn)),
368 "camera" => (Key::Named(Camera), PhysicalKey::Code(KeyCode::Fn)),
369 "camerafocus" => (Key::Named(CameraFocus), PhysicalKey::Code(KeyCode::Fn)),
370 "endcall" => (Key::Named(EndCall), PhysicalKey::Code(KeyCode::Fn)),
371 "goback" => (Key::Named(GoBack), PhysicalKey::Code(KeyCode::Fn)),
372 "gohome" => (Key::Named(GoHome), PhysicalKey::Code(KeyCode::Fn)),
373 "headsethook" => (Key::Named(HeadsetHook), PhysicalKey::Code(KeyCode::Fn)),
374 "lastnumberredial" => (Key::Named(LastNumberRedial), PhysicalKey::Code(KeyCode::Fn)),
375 "notification" => (Key::Named(Notification), PhysicalKey::Code(KeyCode::Fn)),
376 "mannermode" => (Key::Named(MannerMode), PhysicalKey::Code(KeyCode::Fn)),
377 "voicedial" => (Key::Named(VoiceDial), PhysicalKey::Code(KeyCode::Fn)),
378 "tv" => (Key::Named(TV), PhysicalKey::Code(KeyCode::Fn)),
379 "tv3dmode" => (Key::Named(TV3DMode), PhysicalKey::Code(KeyCode::Fn)),
380 "tvantennacable" => (Key::Named(TVAntennaCable), PhysicalKey::Code(KeyCode::Fn)),
381 "tvaudiodescription" => (
382 Key::Named(TVAudioDescription),
383 PhysicalKey::Code(KeyCode::Fn),
384 ),
385 "tvaudiodescriptionmixdown" => (
386 Key::Named(TVAudioDescriptionMixDown),
387 PhysicalKey::Code(KeyCode::Fn),
388 ),
389 "tvaudiodescriptionmixup" => (
390 Key::Named(TVAudioDescriptionMixUp),
391 PhysicalKey::Code(KeyCode::Fn),
392 ),
393 "tvcontentsmenu" => (Key::Named(TVContentsMenu), PhysicalKey::Code(KeyCode::Fn)),
394 "tvdataservice" => (Key::Named(TVDataService), PhysicalKey::Code(KeyCode::Fn)),
395 "tvinput" => (Key::Named(TVInput), PhysicalKey::Code(KeyCode::Fn)),
396 "tvinputcomponent1" => (
397 Key::Named(TVInputComponent1),
398 PhysicalKey::Code(KeyCode::Fn),
399 ),
400 "tvinputcomponent2" => (
401 Key::Named(TVInputComponent2),
402 PhysicalKey::Code(KeyCode::Fn),
403 ),
404 "tvinputcomposite1" => (
405 Key::Named(TVInputComposite1),
406 PhysicalKey::Code(KeyCode::Fn),
407 ),
408 "tvinputcomposite2" => (
409 Key::Named(TVInputComposite2),
410 PhysicalKey::Code(KeyCode::Fn),
411 ),
412 "tvinputhdmi1" => (Key::Named(TVInputHDMI1), PhysicalKey::Code(KeyCode::Fn)),
413 "tvinputhdmi2" => (Key::Named(TVInputHDMI2), PhysicalKey::Code(KeyCode::Fn)),
414 "tvinputhdmi3" => (Key::Named(TVInputHDMI3), PhysicalKey::Code(KeyCode::Fn)),
415 "tvinputhdmi4" => (Key::Named(TVInputHDMI4), PhysicalKey::Code(KeyCode::Fn)),
416 "tvinputvga1" => (Key::Named(TVInputVGA1), PhysicalKey::Code(KeyCode::Fn)),
417 "tvmediacontext" => (Key::Named(TVMediaContext), PhysicalKey::Code(KeyCode::Fn)),
418 "tvnetwork" => (Key::Named(TVNetwork), PhysicalKey::Code(KeyCode::Fn)),
419 "tvnumberentry" => (Key::Named(TVNumberEntry), PhysicalKey::Code(KeyCode::Fn)),
420 "tvpower" => (Key::Named(TVPower), PhysicalKey::Code(KeyCode::Fn)),
421 "tvradioservice" => (Key::Named(TVRadioService), PhysicalKey::Code(KeyCode::Fn)),
422 "tvsatellite" => (Key::Named(TVSatellite), PhysicalKey::Code(KeyCode::Fn)),
423 "tvsatellitebs" => (Key::Named(TVSatelliteBS), PhysicalKey::Code(KeyCode::Fn)),
424 "tvsatellitecs" => (Key::Named(TVSatelliteCS), PhysicalKey::Code(KeyCode::Fn)),
425 "tvsatellitetoggle" => (
426 Key::Named(TVSatelliteToggle),
427 PhysicalKey::Code(KeyCode::Fn),
428 ),
429 "tvterrestrialanalog" => (
430 Key::Named(TVTerrestrialAnalog),
431 PhysicalKey::Code(KeyCode::Fn),
432 ),
433 "tvterrestrialdigital" => (
434 Key::Named(TVTerrestrialDigital),
435 PhysicalKey::Code(KeyCode::Fn),
436 ),
437 "tvtimer" => (Key::Named(TVTimer), PhysicalKey::Code(KeyCode::Fn)),
438 "avrinput" => (Key::Named(AVRInput), PhysicalKey::Code(KeyCode::Fn)),
439 "avrpower" => (Key::Named(AVRPower), PhysicalKey::Code(KeyCode::Fn)),
440 "colorf0red" => (Key::Named(ColorF0Red), PhysicalKey::Code(KeyCode::Fn)),
441 "colorf1green" => (Key::Named(ColorF1Green), PhysicalKey::Code(KeyCode::Fn)),
442 "colorf2yellow" => (Key::Named(ColorF2Yellow), PhysicalKey::Code(KeyCode::Fn)),
443 "colorf3blue" => (Key::Named(ColorF3Blue), PhysicalKey::Code(KeyCode::Fn)),
444 "colorf4grey" => (Key::Named(ColorF4Grey), PhysicalKey::Code(KeyCode::Fn)),
445 "colorf5brown" => (Key::Named(ColorF5Brown), PhysicalKey::Code(KeyCode::Fn)),
446 "closedcaptiontoggle" => (
447 Key::Named(ClosedCaptionToggle),
448 PhysicalKey::Code(KeyCode::Fn),
449 ),
450 "dimmer" => (Key::Named(Dimmer), PhysicalKey::Code(KeyCode::Fn)),
451 "displayswap" => (Key::Named(DisplaySwap), PhysicalKey::Code(KeyCode::Fn)),
452 "dvr" => (Key::Named(DVR), PhysicalKey::Code(KeyCode::Fn)),
453 "exit" => (Key::Named(Exit), PhysicalKey::Code(KeyCode::Fn)),
454 "favoriteclear0" => (Key::Named(FavoriteClear0), PhysicalKey::Code(KeyCode::Fn)),
455 "favoriteclear1" => (Key::Named(FavoriteClear1), PhysicalKey::Code(KeyCode::Fn)),
456 "favoriteclear2" => (Key::Named(FavoriteClear2), PhysicalKey::Code(KeyCode::Fn)),
457 "favoriteclear3" => (Key::Named(FavoriteClear3), PhysicalKey::Code(KeyCode::Fn)),
458 "favoriterecall0" => (Key::Named(FavoriteRecall0), PhysicalKey::Code(KeyCode::Fn)),
459 "favoriterecall1" => (Key::Named(FavoriteRecall1), PhysicalKey::Code(KeyCode::Fn)),
460 "favoriterecall2" => (Key::Named(FavoriteRecall2), PhysicalKey::Code(KeyCode::Fn)),
461 "favoriterecall3" => (Key::Named(FavoriteRecall3), PhysicalKey::Code(KeyCode::Fn)),
462 "favoritestore0" => (Key::Named(FavoriteStore0), PhysicalKey::Code(KeyCode::Fn)),
463 "favoritestore1" => (Key::Named(FavoriteStore1), PhysicalKey::Code(KeyCode::Fn)),
464 "favoritestore2" => (Key::Named(FavoriteStore2), PhysicalKey::Code(KeyCode::Fn)),
465 "favoritestore3" => (Key::Named(FavoriteStore3), PhysicalKey::Code(KeyCode::Fn)),
466 "guide" => (Key::Named(Guide), PhysicalKey::Code(KeyCode::Fn)),
467 "guidenextday" => (Key::Named(GuideNextDay), PhysicalKey::Code(KeyCode::Fn)),
468 "guidepreviousday" => (Key::Named(GuidePreviousDay), PhysicalKey::Code(KeyCode::Fn)),
469 "info" => (Key::Named(Info), PhysicalKey::Code(KeyCode::Fn)),
470 "instantreplay" => (Key::Named(InstantReplay), PhysicalKey::Code(KeyCode::Fn)),
471 "link" => (Key::Named(Link), PhysicalKey::Code(KeyCode::Fn)),
472 "listprogram" => (Key::Named(ListProgram), PhysicalKey::Code(KeyCode::Fn)),
473 "livecontent" => (Key::Named(LiveContent), PhysicalKey::Code(KeyCode::Fn)),
474 "lock" => (Key::Named(Lock), PhysicalKey::Code(KeyCode::Fn)),
475 "mediaapps" => (Key::Named(MediaApps), PhysicalKey::Code(KeyCode::Fn)),
476 "mediaaudiotrack" => (Key::Named(MediaAudioTrack), PhysicalKey::Code(KeyCode::Fn)),
477 "medialast" => (Key::Named(MediaLast), PhysicalKey::Code(KeyCode::Fn)),
478 "mediaskipbackward" => (
479 Key::Named(MediaSkipBackward),
480 PhysicalKey::Code(KeyCode::Fn),
481 ),
482 "mediaskipforward" => (Key::Named(MediaSkipForward), PhysicalKey::Code(KeyCode::Fn)),
483 "mediastepbackward" => (
484 Key::Named(MediaStepBackward),
485 PhysicalKey::Code(KeyCode::Fn),
486 ),
487 "mediastepforward" => (Key::Named(MediaStepForward), PhysicalKey::Code(KeyCode::Fn)),
488 "mediatopmenu" => (Key::Named(MediaTopMenu), PhysicalKey::Code(KeyCode::Fn)),
489 "navigatein" => (Key::Named(NavigateIn), PhysicalKey::Code(KeyCode::Fn)),
490 "navigatenext" => (Key::Named(NavigateNext), PhysicalKey::Code(KeyCode::Fn)),
491 "navigateout" => (Key::Named(NavigateOut), PhysicalKey::Code(KeyCode::Fn)),
492 "navigateprevious" => (Key::Named(NavigatePrevious), PhysicalKey::Code(KeyCode::Fn)),
493 "nextfavoritechannel" => (
494 Key::Named(NextFavoriteChannel),
495 PhysicalKey::Code(KeyCode::Fn),
496 ),
497 "nextuserprofile" => (Key::Named(NextUserProfile), PhysicalKey::Code(KeyCode::Fn)),
498 "ondemand" => (Key::Named(OnDemand), PhysicalKey::Code(KeyCode::Fn)),
499 "pairing" => (Key::Named(Pairing), PhysicalKey::Code(KeyCode::Fn)),
500 "pinpdown" => (Key::Named(PinPDown), PhysicalKey::Code(KeyCode::Fn)),
501 "pinpmove" => (Key::Named(PinPMove), PhysicalKey::Code(KeyCode::Fn)),
502 "pinptoggle" => (Key::Named(PinPToggle), PhysicalKey::Code(KeyCode::Fn)),
503 "pinpup" => (Key::Named(PinPUp), PhysicalKey::Code(KeyCode::Fn)),
504 "playspeeddown" => (Key::Named(PlaySpeedDown), PhysicalKey::Code(KeyCode::Fn)),
505 "playspeedreset" => (Key::Named(PlaySpeedReset), PhysicalKey::Code(KeyCode::Fn)),
506 "playspeedup" => (Key::Named(PlaySpeedUp), PhysicalKey::Code(KeyCode::Fn)),
507 "randomtoggle" => (Key::Named(RandomToggle), PhysicalKey::Code(KeyCode::Fn)),
508 "rclowbattery" => (Key::Named(RcLowBattery), PhysicalKey::Code(KeyCode::Fn)),
509 "recordspeednext" => (Key::Named(RecordSpeedNext), PhysicalKey::Code(KeyCode::Fn)),
510 "rfbypass" => (Key::Named(RfBypass), PhysicalKey::Code(KeyCode::Fn)),
511 "scanchannelstoggle" => (
512 Key::Named(ScanChannelsToggle),
513 PhysicalKey::Code(KeyCode::Fn),
514 ),
515 "screenmodenext" => (Key::Named(ScreenModeNext), PhysicalKey::Code(KeyCode::Fn)),
516 "settings" => (Key::Named(Settings), PhysicalKey::Code(KeyCode::Fn)),
517 "splitscreentoggle" => (
518 Key::Named(SplitScreenToggle),
519 PhysicalKey::Code(KeyCode::Fn),
520 ),
521 "stbinput" => (Key::Named(STBInput), PhysicalKey::Code(KeyCode::Fn)),
522 "stbpower" => (Key::Named(STBPower), PhysicalKey::Code(KeyCode::Fn)),
523 "subtitle" => (Key::Named(Subtitle), PhysicalKey::Code(KeyCode::Fn)),
524 "teletext" => (Key::Named(Teletext), PhysicalKey::Code(KeyCode::Fn)),
525 "videomodenext" => (Key::Named(VideoModeNext), PhysicalKey::Code(KeyCode::Fn)),
526 "wink" => (Key::Named(Wink), PhysicalKey::Code(KeyCode::Fn)),
527 "zoomtoggle" => (Key::Named(ZoomToggle), PhysicalKey::Code(KeyCode::Fn)),
528
529 "esc" => (Key::Named(Escape), PhysicalKey::Code(KeyCode::Escape)),
531 "space" => (Key::Named(Space), PhysicalKey::Code(KeyCode::Space)),
532 "bs" => (Key::Named(Backspace), PhysicalKey::Code(KeyCode::Backspace)),
533 "up" => (Key::Named(ArrowUp), PhysicalKey::Code(KeyCode::ArrowUp)),
534 "down" => (Key::Named(ArrowDown), PhysicalKey::Code(KeyCode::ArrowDown)),
535 "right" => (
536 Key::Named(ArrowRight),
537 PhysicalKey::Code(KeyCode::ArrowRight),
538 ),
539 "left" => (Key::Named(ArrowLeft), PhysicalKey::Code(KeyCode::ArrowLeft)),
540 "del" => (Key::Named(Delete), PhysicalKey::Code(KeyCode::Delete)),
541
542 _ => return None,
543 })
544 }
545
546 fn mouse_from_str(s: &str) -> Option<crate::pointer::PointerButton> {
547 use crate::pointer::PointerButton as B;
548
549 Some(match s {
550 "mousemiddle" => B::Auxiliary,
551 "mouseforward" => B::X2,
552 "mousebackward" => B::X1,
553 _ => return None,
554 })
555 }
556}
557
558impl Display for KeyInput {
559 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
560 use crate::pointer::PointerButton as B;
561
562 match self {
563 Self::Keyboard(_key, key_code) => match key_code {
564 PhysicalKey::Unidentified(_) => f.write_str("Unidentified"),
565 PhysicalKey::Code(KeyCode::Backquote) => f.write_str("`"),
566 PhysicalKey::Code(KeyCode::Backslash) => f.write_str("\\"),
567 PhysicalKey::Code(KeyCode::BracketLeft) => f.write_str("["),
568 PhysicalKey::Code(KeyCode::BracketRight) => f.write_str("]"),
569 PhysicalKey::Code(KeyCode::Comma) => f.write_str(","),
570 PhysicalKey::Code(KeyCode::Digit0) => f.write_str("0"),
571 PhysicalKey::Code(KeyCode::Digit1) => f.write_str("1"),
572 PhysicalKey::Code(KeyCode::Digit2) => f.write_str("2"),
573 PhysicalKey::Code(KeyCode::Digit3) => f.write_str("3"),
574 PhysicalKey::Code(KeyCode::Digit4) => f.write_str("4"),
575 PhysicalKey::Code(KeyCode::Digit5) => f.write_str("5"),
576 PhysicalKey::Code(KeyCode::Digit6) => f.write_str("6"),
577 PhysicalKey::Code(KeyCode::Digit7) => f.write_str("7"),
578 PhysicalKey::Code(KeyCode::Digit8) => f.write_str("8"),
579 PhysicalKey::Code(KeyCode::Digit9) => f.write_str("9"),
580 PhysicalKey::Code(KeyCode::Equal) => f.write_str("="),
581 PhysicalKey::Code(KeyCode::IntlBackslash) => f.write_str("<"),
582 PhysicalKey::Code(KeyCode::IntlRo) => f.write_str("IntlRo"),
583 PhysicalKey::Code(KeyCode::IntlYen) => f.write_str("IntlYen"),
584 PhysicalKey::Code(KeyCode::KeyA) => f.write_str("A"),
585 PhysicalKey::Code(KeyCode::KeyB) => f.write_str("B"),
586 PhysicalKey::Code(KeyCode::KeyC) => f.write_str("C"),
587 PhysicalKey::Code(KeyCode::KeyD) => f.write_str("D"),
588 PhysicalKey::Code(KeyCode::KeyE) => f.write_str("E"),
589 PhysicalKey::Code(KeyCode::KeyF) => f.write_str("F"),
590 PhysicalKey::Code(KeyCode::KeyG) => f.write_str("G"),
591 PhysicalKey::Code(KeyCode::KeyH) => f.write_str("H"),
592 PhysicalKey::Code(KeyCode::KeyI) => f.write_str("I"),
593 PhysicalKey::Code(KeyCode::KeyJ) => f.write_str("J"),
594 PhysicalKey::Code(KeyCode::KeyK) => f.write_str("K"),
595 PhysicalKey::Code(KeyCode::KeyL) => f.write_str("L"),
596 PhysicalKey::Code(KeyCode::KeyM) => f.write_str("M"),
597 PhysicalKey::Code(KeyCode::KeyN) => f.write_str("N"),
598 PhysicalKey::Code(KeyCode::KeyO) => f.write_str("O"),
599 PhysicalKey::Code(KeyCode::KeyP) => f.write_str("P"),
600 PhysicalKey::Code(KeyCode::KeyQ) => f.write_str("Q"),
601 PhysicalKey::Code(KeyCode::KeyR) => f.write_str("R"),
602 PhysicalKey::Code(KeyCode::KeyS) => f.write_str("S"),
603 PhysicalKey::Code(KeyCode::KeyT) => f.write_str("T"),
604 PhysicalKey::Code(KeyCode::KeyU) => f.write_str("U"),
605 PhysicalKey::Code(KeyCode::KeyV) => f.write_str("V"),
606 PhysicalKey::Code(KeyCode::KeyW) => f.write_str("W"),
607 PhysicalKey::Code(KeyCode::KeyX) => f.write_str("X"),
608 PhysicalKey::Code(KeyCode::KeyY) => f.write_str("Y"),
609 PhysicalKey::Code(KeyCode::KeyZ) => f.write_str("Z"),
610 PhysicalKey::Code(KeyCode::Minus) => f.write_str("-"),
611 PhysicalKey::Code(KeyCode::Period) => f.write_str("."),
612 PhysicalKey::Code(KeyCode::Quote) => f.write_str("'"),
613 PhysicalKey::Code(KeyCode::Semicolon) => f.write_str(";"),
614 PhysicalKey::Code(KeyCode::Slash) => f.write_str("/"),
615 PhysicalKey::Code(KeyCode::AltLeft) => f.write_str("Alt"),
616 PhysicalKey::Code(KeyCode::AltRight) => f.write_str("Alt"),
617 PhysicalKey::Code(KeyCode::Backspace) => f.write_str("backspace"),
618 PhysicalKey::Code(KeyCode::CapsLock) => f.write_str("CapsLock"),
619 PhysicalKey::Code(KeyCode::ContextMenu) => f.write_str("ContextMenu"),
620 PhysicalKey::Code(KeyCode::ControlLeft) => f.write_str("Ctrl"),
621 PhysicalKey::Code(KeyCode::ControlRight) => f.write_str("Ctrl"),
622 PhysicalKey::Code(KeyCode::Enter) => f.write_str("Enter"),
623 PhysicalKey::Code(KeyCode::SuperLeft) => match std::env::consts::OS {
624 "macos" => f.write_str("Cmd"),
625 "windows" => f.write_str("Win"),
626 _ => f.write_str("Meta"),
627 },
628 PhysicalKey::Code(KeyCode::SuperRight) => match std::env::consts::OS {
629 "macos" => f.write_str("Cmd"),
630 "windows" => f.write_str("Win"),
631 _ => f.write_str("Meta"),
632 },
633 PhysicalKey::Code(KeyCode::ShiftLeft) => f.write_str("Shift"),
634 PhysicalKey::Code(KeyCode::ShiftRight) => f.write_str("Shift"),
635 PhysicalKey::Code(KeyCode::Space) => f.write_str("Space"),
636 PhysicalKey::Code(KeyCode::Tab) => f.write_str("Tab"),
637 PhysicalKey::Code(KeyCode::Convert) => f.write_str("Convert"),
638 PhysicalKey::Code(KeyCode::KanaMode) => f.write_str("KanaMode"),
639 PhysicalKey::Code(KeyCode::Lang1) => f.write_str("Lang1"),
640 PhysicalKey::Code(KeyCode::Lang2) => f.write_str("Lang2"),
641 PhysicalKey::Code(KeyCode::Lang3) => f.write_str("Lang3"),
642 PhysicalKey::Code(KeyCode::Lang4) => f.write_str("Lang4"),
643 PhysicalKey::Code(KeyCode::Lang5) => f.write_str("Lang5"),
644 PhysicalKey::Code(KeyCode::NonConvert) => f.write_str("NonConvert"),
645 PhysicalKey::Code(KeyCode::Delete) => f.write_str("Delete"),
646 PhysicalKey::Code(KeyCode::End) => f.write_str("End"),
647 PhysicalKey::Code(KeyCode::Help) => f.write_str("Help"),
648 PhysicalKey::Code(KeyCode::Home) => f.write_str("Home"),
649 PhysicalKey::Code(KeyCode::Insert) => f.write_str("Insert"),
650 PhysicalKey::Code(KeyCode::PageDown) => f.write_str("PageDown"),
651 PhysicalKey::Code(KeyCode::PageUp) => f.write_str("PageUp"),
652 PhysicalKey::Code(KeyCode::ArrowDown) => f.write_str("Down"),
653 PhysicalKey::Code(KeyCode::ArrowLeft) => f.write_str("Left"),
654 PhysicalKey::Code(KeyCode::ArrowRight) => f.write_str("Right"),
655 PhysicalKey::Code(KeyCode::ArrowUp) => f.write_str("Up"),
656 PhysicalKey::Code(KeyCode::NumLock) => f.write_str("NumLock"),
657 PhysicalKey::Code(KeyCode::Numpad0) => f.write_str("Numpad0"),
658 PhysicalKey::Code(KeyCode::Numpad1) => f.write_str("Numpad1"),
659 PhysicalKey::Code(KeyCode::Numpad2) => f.write_str("Numpad2"),
660 PhysicalKey::Code(KeyCode::Numpad3) => f.write_str("Numpad3"),
661 PhysicalKey::Code(KeyCode::Numpad4) => f.write_str("Numpad4"),
662 PhysicalKey::Code(KeyCode::Numpad5) => f.write_str("Numpad5"),
663 PhysicalKey::Code(KeyCode::Numpad6) => f.write_str("Numpad6"),
664 PhysicalKey::Code(KeyCode::Numpad7) => f.write_str("Numpad7"),
665 PhysicalKey::Code(KeyCode::Numpad8) => f.write_str("Numpad8"),
666 PhysicalKey::Code(KeyCode::Numpad9) => f.write_str("Numpad9"),
667 PhysicalKey::Code(KeyCode::NumpadAdd) => f.write_str("NumpadAdd"),
668 PhysicalKey::Code(KeyCode::NumpadBackspace) => f.write_str("NumpadBackspace"),
669 PhysicalKey::Code(KeyCode::NumpadClear) => f.write_str("NumpadClear"),
670 PhysicalKey::Code(KeyCode::NumpadClearEntry) => f.write_str("NumpadClearEntry"),
671 PhysicalKey::Code(KeyCode::NumpadComma) => f.write_str("NumpadComma"),
672 PhysicalKey::Code(KeyCode::NumpadDecimal) => f.write_str("NumpadDecimal"),
673 PhysicalKey::Code(KeyCode::NumpadDivide) => f.write_str("NumpadDivide"),
674 PhysicalKey::Code(KeyCode::NumpadEnter) => f.write_str("NumpadEnter"),
675 PhysicalKey::Code(KeyCode::NumpadEqual) => f.write_str("NumpadEqual"),
676 PhysicalKey::Code(KeyCode::NumpadHash) => f.write_str("NumpadHash"),
677 PhysicalKey::Code(KeyCode::NumpadMemoryAdd) => f.write_str("NumpadMemoryAdd"),
678 PhysicalKey::Code(KeyCode::NumpadMemoryClear) => f.write_str("NumpadMemoryClear"),
679 PhysicalKey::Code(KeyCode::NumpadMemoryRecall) => f.write_str("NumpadMemoryRecall"),
680 PhysicalKey::Code(KeyCode::NumpadMemoryStore) => f.write_str("NumpadMemoryStore"),
681 PhysicalKey::Code(KeyCode::NumpadMemorySubtract) => {
682 f.write_str("NumpadMemorySubtract")
683 }
684 PhysicalKey::Code(KeyCode::NumpadMultiply) => f.write_str("NumpadMultiply"),
685 PhysicalKey::Code(KeyCode::NumpadParenLeft) => f.write_str("NumpadParenLeft"),
686 PhysicalKey::Code(KeyCode::NumpadParenRight) => f.write_str("NumpadParenRight"),
687 PhysicalKey::Code(KeyCode::NumpadStar) => f.write_str("NumpadStar"),
688 PhysicalKey::Code(KeyCode::NumpadSubtract) => f.write_str("NumpadSubtract"),
689 PhysicalKey::Code(KeyCode::Escape) => f.write_str("Escape"),
690 PhysicalKey::Code(KeyCode::Fn) => f.write_str("Fn"),
691 PhysicalKey::Code(KeyCode::FnLock) => f.write_str("FnLock"),
692 PhysicalKey::Code(KeyCode::PrintScreen) => f.write_str("PrintScreen"),
693 PhysicalKey::Code(KeyCode::ScrollLock) => f.write_str("ScrollLock"),
694 PhysicalKey::Code(KeyCode::Pause) => f.write_str("Pause"),
695 PhysicalKey::Code(KeyCode::BrowserBack) => f.write_str("BrowserBack"),
696 PhysicalKey::Code(KeyCode::BrowserFavorites) => f.write_str("BrowserFavorites"),
697 PhysicalKey::Code(KeyCode::BrowserForward) => f.write_str("BrowserForward"),
698 PhysicalKey::Code(KeyCode::BrowserHome) => f.write_str("BrowserHome"),
699 PhysicalKey::Code(KeyCode::BrowserRefresh) => f.write_str("BrowserRefresh"),
700 PhysicalKey::Code(KeyCode::BrowserSearch) => f.write_str("BrowserSearch"),
701 PhysicalKey::Code(KeyCode::BrowserStop) => f.write_str("BrowserStop"),
702 PhysicalKey::Code(KeyCode::Eject) => f.write_str("Eject"),
703 PhysicalKey::Code(KeyCode::LaunchApp1) => f.write_str("LaunchApp1"),
704 PhysicalKey::Code(KeyCode::LaunchApp2) => f.write_str("LaunchApp2"),
705 PhysicalKey::Code(KeyCode::LaunchMail) => f.write_str("LaunchMail"),
706 PhysicalKey::Code(KeyCode::MediaPlayPause) => f.write_str("MediaPlayPause"),
707 PhysicalKey::Code(KeyCode::MediaSelect) => f.write_str("MediaSelect"),
708 PhysicalKey::Code(KeyCode::MediaStop) => f.write_str("MediaStop"),
709 PhysicalKey::Code(KeyCode::MediaTrackNext) => f.write_str("MediaTrackNext"),
710 PhysicalKey::Code(KeyCode::MediaTrackPrevious) => f.write_str("MediaTrackPrevious"),
711 PhysicalKey::Code(KeyCode::Power) => f.write_str("Power"),
712 PhysicalKey::Code(KeyCode::Sleep) => f.write_str("Sleep"),
713 PhysicalKey::Code(KeyCode::AudioVolumeDown) => f.write_str("AudioVolumeDown"),
714 PhysicalKey::Code(KeyCode::AudioVolumeMute) => f.write_str("AudioVolumeMute"),
715 PhysicalKey::Code(KeyCode::AudioVolumeUp) => f.write_str("AudioVolumeUp"),
716 PhysicalKey::Code(KeyCode::WakeUp) => f.write_str("WakeUp"),
717 PhysicalKey::Code(KeyCode::Meta) => match std::env::consts::OS {
718 "macos" => f.write_str("Cmd"),
719 "windows" => f.write_str("Win"),
720 _ => f.write_str("Meta"),
721 },
722 PhysicalKey::Code(KeyCode::Hyper) => f.write_str("Hyper"),
723 PhysicalKey::Code(KeyCode::Turbo) => f.write_str("Turbo"),
724 PhysicalKey::Code(KeyCode::Abort) => f.write_str("Abort"),
725 PhysicalKey::Code(KeyCode::Resume) => f.write_str("Resume"),
726 PhysicalKey::Code(KeyCode::Suspend) => f.write_str("Suspend"),
727 PhysicalKey::Code(KeyCode::Again) => f.write_str("Again"),
728 PhysicalKey::Code(KeyCode::Copy) => f.write_str("Copy"),
729 PhysicalKey::Code(KeyCode::Cut) => f.write_str("Cut"),
730 PhysicalKey::Code(KeyCode::Find) => f.write_str("Find"),
731 PhysicalKey::Code(KeyCode::Open) => f.write_str("Open"),
732 PhysicalKey::Code(KeyCode::Paste) => f.write_str("Paste"),
733 PhysicalKey::Code(KeyCode::Props) => f.write_str("Props"),
734 PhysicalKey::Code(KeyCode::Select) => f.write_str("Select"),
735 PhysicalKey::Code(KeyCode::Undo) => f.write_str("Undo"),
736 PhysicalKey::Code(KeyCode::Hiragana) => f.write_str("Hiragana"),
737 PhysicalKey::Code(KeyCode::Katakana) => f.write_str("Katakana"),
738 PhysicalKey::Code(KeyCode::F1) => f.write_str("F1"),
739 PhysicalKey::Code(KeyCode::F2) => f.write_str("F2"),
740 PhysicalKey::Code(KeyCode::F3) => f.write_str("F3"),
741 PhysicalKey::Code(KeyCode::F4) => f.write_str("F4"),
742 PhysicalKey::Code(KeyCode::F5) => f.write_str("F5"),
743 PhysicalKey::Code(KeyCode::F6) => f.write_str("F6"),
744 PhysicalKey::Code(KeyCode::F7) => f.write_str("F7"),
745 PhysicalKey::Code(KeyCode::F8) => f.write_str("F8"),
746 PhysicalKey::Code(KeyCode::F9) => f.write_str("F9"),
747 PhysicalKey::Code(KeyCode::F10) => f.write_str("F10"),
748 PhysicalKey::Code(KeyCode::F11) => f.write_str("F11"),
749 PhysicalKey::Code(KeyCode::F12) => f.write_str("F12"),
750 PhysicalKey::Code(KeyCode::F13) => f.write_str("F13"),
751 PhysicalKey::Code(KeyCode::F14) => f.write_str("F14"),
752 PhysicalKey::Code(KeyCode::F15) => f.write_str("F15"),
753 PhysicalKey::Code(KeyCode::F16) => f.write_str("F16"),
754 PhysicalKey::Code(KeyCode::F17) => f.write_str("F17"),
755 PhysicalKey::Code(KeyCode::F18) => f.write_str("F18"),
756 PhysicalKey::Code(KeyCode::F19) => f.write_str("F19"),
757 PhysicalKey::Code(KeyCode::F20) => f.write_str("F20"),
758 PhysicalKey::Code(KeyCode::F21) => f.write_str("F21"),
759 PhysicalKey::Code(KeyCode::F22) => f.write_str("F22"),
760 PhysicalKey::Code(KeyCode::F23) => f.write_str("F23"),
761 PhysicalKey::Code(KeyCode::F24) => f.write_str("F24"),
762 PhysicalKey::Code(KeyCode::F25) => f.write_str("F25"),
763 PhysicalKey::Code(KeyCode::F26) => f.write_str("F26"),
764 PhysicalKey::Code(KeyCode::F27) => f.write_str("F27"),
765 PhysicalKey::Code(KeyCode::F28) => f.write_str("F28"),
766 PhysicalKey::Code(KeyCode::F29) => f.write_str("F29"),
767 PhysicalKey::Code(KeyCode::F30) => f.write_str("F30"),
768 PhysicalKey::Code(KeyCode::F31) => f.write_str("F31"),
769 PhysicalKey::Code(KeyCode::F32) => f.write_str("F32"),
770 PhysicalKey::Code(KeyCode::F33) => f.write_str("F33"),
771 PhysicalKey::Code(KeyCode::F34) => f.write_str("F34"),
772 PhysicalKey::Code(KeyCode::F35) => f.write_str("F35"),
773 _ => f.write_str("Unidentified"),
774 },
775 Self::Pointer(B::Auxiliary) => f.write_str("MouseMiddle"),
776 Self::Pointer(B::X2) => f.write_str("MouseForward"),
777 Self::Pointer(B::X1) => f.write_str("MouseBackward"),
778 Self::Pointer(_) => f.write_str("MouseUnimplemented"),
779 }
780 }
781}
782
783impl FromStr for KeyInput {
784 type Err = ();
785
786 fn from_str(s: &str) -> Result<Self, Self::Err> {
787 let s = s.to_lowercase();
788
789 KeyInput::keyboard_from_str(&s)
790 .map(|key| KeyInput::Keyboard(key.0, key.1))
791 .or_else(|| KeyInput::mouse_from_str(&s).map(KeyInput::Pointer))
792 .ok_or(())
793 }
794}
795
796impl Hash for KeyInput {
797 fn hash<H: Hasher>(&self, state: &mut H) {
798 match self {
799 Self::Keyboard(_key, key_code) => key_code.hash(state),
800 Self::Pointer(btn) => (*btn as u8).hash(state),
802 }
803 }
804}
805
806impl PartialEq for KeyInput {
807 fn eq(&self, other: &Self) -> bool {
808 match (self, other) {
809 (KeyInput::Keyboard(_key_a, key_code_a), KeyInput::Keyboard(_key_b, key_code_b)) => {
810 key_code_a.eq(key_code_b)
811 }
812 (KeyInput::Pointer(a), KeyInput::Pointer(b)) => a.eq(b),
813 _ => false,
814 }
815 }
816}