ui-events-winit 0.2.0

A library for bridging ui-events and winit
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
// Copyright 2025 the UI Events Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Support routines for converting keyboard data from [`winit`]

use ui_events::keyboard::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers, NamedKey};
use winit::keyboard::{KeyLocation, ModifiersState};

extern crate alloc;
use alloc::string::String;

/// Convert a [`winit::event::KeyEvent`] and [`winit::keyboard::ModifiersState`] to a [`KeyboardEvent`].
pub fn from_winit_keyboard_event(
    winit_event: winit::event::KeyEvent,
    mods: ModifiersState,
) -> KeyboardEvent {
    KeyboardEvent {
        key: from_winit_key(winit_event.logical_key),
        code: from_winit_code(winit_event.physical_key),
        modifiers: from_winit_modifier_state(mods),
        location: from_winit_location(winit_event.location),
        is_composing: false,
        repeat: winit_event.repeat,
        state: match winit_event.state {
            winit::event::ElementState::Pressed => KeyState::Down,
            winit::event::ElementState::Released => KeyState::Up,
        },
    }
}

/// Convert a [`winit::keyboard::KeyLocation`] to a [`ui_events::keyboard::Location`].
pub fn from_winit_location(winit_location: KeyLocation) -> Location {
    match winit_location {
        KeyLocation::Standard => Location::Standard,
        KeyLocation::Left => Location::Left,
        KeyLocation::Right => Location::Right,
        KeyLocation::Numpad => Location::Numpad,
    }
}

/// Convert a [`winit::keyboard::ModifiersState`] to a [`ui_events::keyboard::Modifiers`].
pub fn from_winit_modifier_state(modifiers_state: ModifiersState) -> Modifiers {
    let mut modifiers = Modifiers::default();
    if modifiers_state.control_key() {
        modifiers.insert(Modifiers::CONTROL);
    }
    if modifiers_state.alt_key() {
        modifiers.insert(Modifiers::ALT);
    }
    if modifiers_state.shift_key() {
        modifiers.insert(Modifiers::SHIFT);
    }
    if modifiers_state.super_key() {
        modifiers.insert(Modifiers::META);
    }
    modifiers
}

/// Convert a [`winit::keyboard::Key`] to a [`ui_events::keyboard::Key`].
pub fn from_winit_key(winit_key: winit::keyboard::Key) -> Key {
    use winit::keyboard::Key as WK;
    use winit::keyboard::NamedKey as WNK;
    match winit_key {
        WK::Character(c) => Key::Character(c.to_string()),
        WK::Unidentified(_) => Key::Named(NamedKey::Unidentified),
        WK::Dead(_) => Key::Named(NamedKey::Dead),
        WK::Named(WNK::Space) => Key::Character(String::from(" ")),
        WK::Named(k) => Key::Named(match k {
            WNK::Alt => NamedKey::Alt,
            WNK::AltGraph => NamedKey::AltGraph,
            WNK::CapsLock => NamedKey::CapsLock,
            WNK::Control => NamedKey::Control,
            WNK::Fn => NamedKey::Fn,
            WNK::FnLock => NamedKey::FnLock,
            WNK::NumLock => NamedKey::NumLock,
            WNK::ScrollLock => NamedKey::ScrollLock,
            WNK::Shift => NamedKey::Shift,
            WNK::Symbol => NamedKey::Symbol,
            WNK::SymbolLock => NamedKey::SymbolLock,
            #[expect(deprecated, reason = "Deprecated but not unused.")]
            WNK::Meta => NamedKey::Super,
            #[expect(deprecated, reason = "Deprecated but not unused.")]
            WNK::Hyper => NamedKey::Hyper,
            WNK::Super => NamedKey::Meta,
            WNK::Enter => NamedKey::Enter,
            WNK::Tab => NamedKey::Tab,
            WNK::ArrowDown => NamedKey::ArrowDown,
            WNK::ArrowLeft => NamedKey::ArrowLeft,
            WNK::ArrowRight => NamedKey::ArrowRight,
            WNK::ArrowUp => NamedKey::ArrowUp,
            WNK::End => NamedKey::End,
            WNK::Home => NamedKey::Home,
            WNK::PageDown => NamedKey::PageDown,
            WNK::PageUp => NamedKey::PageUp,
            WNK::Backspace => NamedKey::Backspace,
            WNK::Clear => NamedKey::Clear,
            WNK::Copy => NamedKey::Copy,
            WNK::CrSel => NamedKey::CrSel,
            WNK::Cut => NamedKey::Cut,
            WNK::Delete => NamedKey::Delete,
            WNK::EraseEof => NamedKey::EraseEof,
            WNK::ExSel => NamedKey::ExSel,
            WNK::Insert => NamedKey::Insert,
            WNK::Paste => NamedKey::Paste,
            WNK::Redo => NamedKey::Redo,
            WNK::Undo => NamedKey::Undo,
            WNK::Accept => NamedKey::Accept,
            WNK::Again => NamedKey::Again,
            WNK::Attn => NamedKey::Attn,
            WNK::Cancel => NamedKey::Cancel,
            WNK::ContextMenu => NamedKey::ContextMenu,
            WNK::Escape => NamedKey::Escape,
            WNK::Execute => NamedKey::Execute,
            WNK::Find => NamedKey::Find,
            WNK::Help => NamedKey::Help,
            WNK::Pause => NamedKey::Pause,
            WNK::Play => NamedKey::Play,
            WNK::Props => NamedKey::Props,
            WNK::Select => NamedKey::Select,
            WNK::ZoomIn => NamedKey::ZoomIn,
            WNK::ZoomOut => NamedKey::ZoomOut,
            WNK::BrightnessDown => NamedKey::BrightnessDown,
            WNK::BrightnessUp => NamedKey::BrightnessUp,
            WNK::Eject => NamedKey::Eject,
            WNK::LogOff => NamedKey::LogOff,
            WNK::Power => NamedKey::Power,
            WNK::PowerOff => NamedKey::PowerOff,
            WNK::PrintScreen => NamedKey::PrintScreen,
            WNK::Hibernate => NamedKey::Hibernate,
            WNK::Standby => NamedKey::Standby,
            WNK::WakeUp => NamedKey::WakeUp,
            WNK::AllCandidates => NamedKey::AllCandidates,
            WNK::Alphanumeric => NamedKey::Alphanumeric,
            WNK::CodeInput => NamedKey::CodeInput,
            WNK::Compose => NamedKey::Compose,
            WNK::Convert => NamedKey::Convert,
            WNK::FinalMode => NamedKey::FinalMode,
            WNK::GroupFirst => NamedKey::GroupFirst,
            WNK::GroupLast => NamedKey::GroupLast,
            WNK::GroupNext => NamedKey::GroupNext,
            WNK::GroupPrevious => NamedKey::GroupPrevious,
            WNK::ModeChange => NamedKey::ModeChange,
            WNK::NextCandidate => NamedKey::NextCandidate,
            WNK::NonConvert => NamedKey::NonConvert,
            WNK::PreviousCandidate => NamedKey::PreviousCandidate,
            WNK::Process => NamedKey::Process,
            WNK::SingleCandidate => NamedKey::SingleCandidate,
            WNK::HangulMode => NamedKey::HangulMode,
            WNK::HanjaMode => NamedKey::HanjaMode,
            WNK::JunjaMode => NamedKey::JunjaMode,
            WNK::Eisu => NamedKey::Eisu,
            WNK::Hankaku => NamedKey::Hankaku,
            WNK::Hiragana => NamedKey::Hiragana,
            WNK::HiraganaKatakana => NamedKey::HiraganaKatakana,
            WNK::KanaMode => NamedKey::KanaMode,
            WNK::KanjiMode => NamedKey::KanjiMode,
            WNK::Katakana => NamedKey::Katakana,
            WNK::Romaji => NamedKey::Romaji,
            WNK::Zenkaku => NamedKey::Zenkaku,
            WNK::ZenkakuHankaku => NamedKey::ZenkakuHankaku,
            WNK::Soft1 => NamedKey::Soft1,
            WNK::Soft2 => NamedKey::Soft2,
            WNK::Soft3 => NamedKey::Soft3,
            WNK::Soft4 => NamedKey::Soft4,
            WNK::ChannelDown => NamedKey::ChannelDown,
            WNK::ChannelUp => NamedKey::ChannelUp,
            WNK::Close => NamedKey::Close,
            WNK::MailForward => NamedKey::MailForward,
            WNK::MailReply => NamedKey::MailReply,
            WNK::MailSend => NamedKey::MailSend,
            WNK::MediaClose => NamedKey::MediaClose,
            WNK::MediaFastForward => NamedKey::MediaFastForward,
            WNK::MediaPause => NamedKey::MediaPause,
            WNK::MediaPlay => NamedKey::MediaPlay,
            WNK::MediaPlayPause => NamedKey::MediaPlayPause,
            WNK::MediaRecord => NamedKey::MediaRecord,
            WNK::MediaRewind => NamedKey::MediaRewind,
            WNK::MediaStop => NamedKey::MediaStop,
            WNK::MediaTrackNext => NamedKey::MediaTrackNext,
            WNK::MediaTrackPrevious => NamedKey::MediaTrackPrevious,
            WNK::New => NamedKey::New,
            WNK::Open => NamedKey::Open,
            WNK::Print => NamedKey::Print,
            WNK::Save => NamedKey::Save,
            WNK::SpellCheck => NamedKey::SpellCheck,
            WNK::Key11 => NamedKey::Key11,
            WNK::Key12 => NamedKey::Key12,
            WNK::AudioBalanceLeft => NamedKey::AudioBalanceLeft,
            WNK::AudioBalanceRight => NamedKey::AudioBalanceRight,
            WNK::AudioBassBoostDown => NamedKey::AudioBassBoostDown,
            WNK::AudioBassBoostToggle => NamedKey::AudioBassBoostToggle,
            WNK::AudioBassBoostUp => NamedKey::AudioBassBoostUp,
            WNK::AudioFaderFront => NamedKey::AudioFaderFront,
            WNK::AudioFaderRear => NamedKey::AudioFaderRear,
            WNK::AudioSurroundModeNext => NamedKey::AudioSurroundModeNext,
            WNK::AudioTrebleDown => NamedKey::AudioTrebleDown,
            WNK::AudioTrebleUp => NamedKey::AudioTrebleUp,
            WNK::AudioVolumeDown => NamedKey::AudioVolumeDown,
            WNK::AudioVolumeUp => NamedKey::AudioVolumeUp,
            WNK::AudioVolumeMute => NamedKey::AudioVolumeMute,
            WNK::MicrophoneToggle => NamedKey::MicrophoneToggle,
            WNK::MicrophoneVolumeDown => NamedKey::MicrophoneVolumeDown,
            WNK::MicrophoneVolumeUp => NamedKey::MicrophoneVolumeUp,
            WNK::MicrophoneVolumeMute => NamedKey::MicrophoneVolumeMute,
            WNK::SpeechCorrectionList => NamedKey::SpeechCorrectionList,
            WNK::SpeechInputToggle => NamedKey::SpeechInputToggle,
            WNK::LaunchApplication1 => NamedKey::LaunchApplication1,
            WNK::LaunchApplication2 => NamedKey::LaunchApplication2,
            WNK::LaunchCalendar => NamedKey::LaunchCalendar,
            WNK::LaunchContacts => NamedKey::LaunchContacts,
            WNK::LaunchMail => NamedKey::LaunchMail,
            WNK::LaunchMediaPlayer => NamedKey::LaunchMediaPlayer,
            WNK::LaunchMusicPlayer => NamedKey::LaunchMusicPlayer,
            WNK::LaunchPhone => NamedKey::LaunchPhone,
            WNK::LaunchScreenSaver => NamedKey::LaunchScreenSaver,
            WNK::LaunchSpreadsheet => NamedKey::LaunchSpreadsheet,
            WNK::LaunchWebBrowser => NamedKey::LaunchWebBrowser,
            WNK::LaunchWebCam => NamedKey::LaunchWebCam,
            WNK::LaunchWordProcessor => NamedKey::LaunchWordProcessor,
            WNK::BrowserBack => NamedKey::BrowserBack,
            WNK::BrowserFavorites => NamedKey::BrowserFavorites,
            WNK::BrowserForward => NamedKey::BrowserForward,
            WNK::BrowserHome => NamedKey::BrowserHome,
            WNK::BrowserRefresh => NamedKey::BrowserRefresh,
            WNK::BrowserSearch => NamedKey::BrowserSearch,
            WNK::BrowserStop => NamedKey::BrowserStop,
            WNK::AppSwitch => NamedKey::AppSwitch,
            WNK::Call => NamedKey::Call,
            WNK::Camera => NamedKey::Camera,
            WNK::CameraFocus => NamedKey::CameraFocus,
            WNK::EndCall => NamedKey::EndCall,
            WNK::GoBack => NamedKey::GoBack,
            WNK::GoHome => NamedKey::GoHome,
            WNK::HeadsetHook => NamedKey::HeadsetHook,
            WNK::LastNumberRedial => NamedKey::LastNumberRedial,
            WNK::Notification => NamedKey::Notification,
            WNK::MannerMode => NamedKey::MannerMode,
            WNK::VoiceDial => NamedKey::VoiceDial,
            WNK::TV => NamedKey::TV,
            WNK::TV3DMode => NamedKey::TV3DMode,
            WNK::TVAntennaCable => NamedKey::TVAntennaCable,
            WNK::TVAudioDescription => NamedKey::TVAudioDescription,
            WNK::TVAudioDescriptionMixDown => NamedKey::TVAudioDescriptionMixDown,
            WNK::TVAudioDescriptionMixUp => NamedKey::TVAudioDescriptionMixUp,
            WNK::TVContentsMenu => NamedKey::TVContentsMenu,
            WNK::TVDataService => NamedKey::TVDataService,
            WNK::TVInput => NamedKey::TVInput,
            WNK::TVInputComponent1 => NamedKey::TVInputComponent1,
            WNK::TVInputComponent2 => NamedKey::TVInputComponent2,
            WNK::TVInputComposite1 => NamedKey::TVInputComposite1,
            WNK::TVInputComposite2 => NamedKey::TVInputComposite2,
            WNK::TVInputHDMI1 => NamedKey::TVInputHDMI1,
            WNK::TVInputHDMI2 => NamedKey::TVInputHDMI2,
            WNK::TVInputHDMI3 => NamedKey::TVInputHDMI3,
            WNK::TVInputHDMI4 => NamedKey::TVInputHDMI4,
            WNK::TVInputVGA1 => NamedKey::TVInputVGA1,
            WNK::TVMediaContext => NamedKey::TVMediaContext,
            WNK::TVNetwork => NamedKey::TVNetwork,
            WNK::TVNumberEntry => NamedKey::TVNumberEntry,
            WNK::TVPower => NamedKey::TVPower,
            WNK::TVRadioService => NamedKey::TVRadioService,
            WNK::TVSatellite => NamedKey::TVSatellite,
            WNK::TVSatelliteBS => NamedKey::TVSatelliteBS,
            WNK::TVSatelliteCS => NamedKey::TVSatelliteCS,
            WNK::TVSatelliteToggle => NamedKey::TVSatelliteToggle,
            WNK::TVTerrestrialAnalog => NamedKey::TVTerrestrialAnalog,
            WNK::TVTerrestrialDigital => NamedKey::TVTerrestrialDigital,
            WNK::TVTimer => NamedKey::TVTimer,
            WNK::AVRInput => NamedKey::AVRInput,
            WNK::AVRPower => NamedKey::AVRPower,
            WNK::ColorF0Red => NamedKey::ColorF0Red,
            WNK::ColorF1Green => NamedKey::ColorF1Green,
            WNK::ColorF2Yellow => NamedKey::ColorF2Yellow,
            WNK::ColorF3Blue => NamedKey::ColorF3Blue,
            WNK::ColorF4Grey => NamedKey::ColorF4Grey,
            WNK::ColorF5Brown => NamedKey::ColorF5Brown,
            WNK::ClosedCaptionToggle => NamedKey::ClosedCaptionToggle,
            WNK::Dimmer => NamedKey::Dimmer,
            WNK::DisplaySwap => NamedKey::DisplaySwap,
            WNK::DVR => NamedKey::DVR,
            WNK::Exit => NamedKey::Exit,
            WNK::FavoriteClear0 => NamedKey::FavoriteClear0,
            WNK::FavoriteClear1 => NamedKey::FavoriteClear1,
            WNK::FavoriteClear2 => NamedKey::FavoriteClear2,
            WNK::FavoriteClear3 => NamedKey::FavoriteClear3,
            WNK::FavoriteRecall0 => NamedKey::FavoriteRecall0,
            WNK::FavoriteRecall1 => NamedKey::FavoriteRecall1,
            WNK::FavoriteRecall2 => NamedKey::FavoriteRecall2,
            WNK::FavoriteRecall3 => NamedKey::FavoriteRecall3,
            WNK::FavoriteStore0 => NamedKey::FavoriteStore0,
            WNK::FavoriteStore1 => NamedKey::FavoriteStore1,
            WNK::FavoriteStore2 => NamedKey::FavoriteStore2,
            WNK::FavoriteStore3 => NamedKey::FavoriteStore3,
            WNK::Guide => NamedKey::Guide,
            WNK::GuideNextDay => NamedKey::GuideNextDay,
            WNK::GuidePreviousDay => NamedKey::GuidePreviousDay,
            WNK::Info => NamedKey::Info,
            WNK::InstantReplay => NamedKey::InstantReplay,
            WNK::Link => NamedKey::Link,
            WNK::ListProgram => NamedKey::ListProgram,
            WNK::LiveContent => NamedKey::LiveContent,
            WNK::Lock => NamedKey::Lock,
            WNK::MediaApps => NamedKey::MediaApps,
            WNK::MediaAudioTrack => NamedKey::MediaAudioTrack,
            WNK::MediaLast => NamedKey::MediaLast,
            WNK::MediaSkipBackward => NamedKey::MediaSkipBackward,
            WNK::MediaSkipForward => NamedKey::MediaSkipForward,
            WNK::MediaStepBackward => NamedKey::MediaStepBackward,
            WNK::MediaStepForward => NamedKey::MediaStepForward,
            WNK::MediaTopMenu => NamedKey::MediaTopMenu,
            WNK::NavigateIn => NamedKey::NavigateIn,
            WNK::NavigateNext => NamedKey::NavigateNext,
            WNK::NavigateOut => NamedKey::NavigateOut,
            WNK::NavigatePrevious => NamedKey::NavigatePrevious,
            WNK::NextFavoriteChannel => NamedKey::NextFavoriteChannel,
            WNK::NextUserProfile => NamedKey::NextUserProfile,
            WNK::OnDemand => NamedKey::OnDemand,
            WNK::Pairing => NamedKey::Pairing,
            WNK::PinPDown => NamedKey::PinPDown,
            WNK::PinPMove => NamedKey::PinPMove,
            WNK::PinPToggle => NamedKey::PinPToggle,
            WNK::PinPUp => NamedKey::PinPUp,
            WNK::PlaySpeedDown => NamedKey::PlaySpeedDown,
            WNK::PlaySpeedReset => NamedKey::PlaySpeedReset,
            WNK::PlaySpeedUp => NamedKey::PlaySpeedUp,
            WNK::RandomToggle => NamedKey::RandomToggle,
            WNK::RcLowBattery => NamedKey::RcLowBattery,
            WNK::RecordSpeedNext => NamedKey::RecordSpeedNext,
            WNK::RfBypass => NamedKey::RfBypass,
            WNK::ScanChannelsToggle => NamedKey::ScanChannelsToggle,
            WNK::ScreenModeNext => NamedKey::ScreenModeNext,
            WNK::Settings => NamedKey::Settings,
            WNK::SplitScreenToggle => NamedKey::SplitScreenToggle,
            WNK::STBInput => NamedKey::STBInput,
            WNK::STBPower => NamedKey::STBPower,
            WNK::Subtitle => NamedKey::Subtitle,
            WNK::Teletext => NamedKey::Teletext,
            WNK::VideoModeNext => NamedKey::VideoModeNext,
            WNK::Wink => NamedKey::Wink,
            WNK::ZoomToggle => NamedKey::ZoomToggle,
            WNK::F1 => NamedKey::F1,
            WNK::F2 => NamedKey::F2,
            WNK::F3 => NamedKey::F3,
            WNK::F4 => NamedKey::F4,
            WNK::F5 => NamedKey::F5,
            WNK::F6 => NamedKey::F6,
            WNK::F7 => NamedKey::F7,
            WNK::F8 => NamedKey::F8,
            WNK::F9 => NamedKey::F9,
            WNK::F10 => NamedKey::F10,
            WNK::F11 => NamedKey::F11,
            WNK::F12 => NamedKey::F12,
            WNK::F13 => NamedKey::F13,
            WNK::F14 => NamedKey::F14,
            WNK::F15 => NamedKey::F15,
            WNK::F16 => NamedKey::F16,
            WNK::F17 => NamedKey::F17,
            WNK::F18 => NamedKey::F18,
            WNK::F19 => NamedKey::F19,
            WNK::F20 => NamedKey::F20,
            WNK::F21 => NamedKey::F21,
            WNK::F22 => NamedKey::F22,
            WNK::F23 => NamedKey::F23,
            WNK::F24 => NamedKey::F24,
            WNK::F25 => NamedKey::F25,
            WNK::F26 => NamedKey::F26,
            WNK::F27 => NamedKey::F27,
            WNK::F28 => NamedKey::F28,
            WNK::F29 => NamedKey::F29,
            WNK::F30 => NamedKey::F30,
            WNK::F31 => NamedKey::F31,
            WNK::F32 => NamedKey::F32,
            WNK::F33 => NamedKey::F33,
            WNK::F34 => NamedKey::F34,
            WNK::F35 => NamedKey::F35,
            _ => NamedKey::Unidentified,
        }),
    }
}

/// Convert a [`winit::keyboard::PhysicalKey`] to a [`ui_events::keyboard::Code`].
pub fn from_winit_code(physical_key: winit::keyboard::PhysicalKey) -> Code {
    use winit::keyboard::KeyCode as KC;
    use winit::keyboard::PhysicalKey;
    match physical_key {
        PhysicalKey::Unidentified(_) => Code::Unidentified,
        PhysicalKey::Code(key_code) => match key_code {
            // Variants that don't match 1:1
            // With winit 0.31, these are renamed to swap the meta and super to match the W3C specs.
            #[expect(deprecated, reason = "Deprecated but not unused.")]
            KC::Meta => Code::Super,
            KC::SuperLeft => Code::MetaLeft,
            KC::SuperRight => Code::MetaRight,

            KC::Backquote => Code::Backquote,
            KC::Backslash => Code::Backslash,
            KC::BracketLeft => Code::BracketLeft,
            KC::BracketRight => Code::BracketRight,
            KC::Comma => Code::Comma,
            KC::Digit0 => Code::Digit0,
            KC::Digit1 => Code::Digit1,
            KC::Digit2 => Code::Digit2,
            KC::Digit3 => Code::Digit3,
            KC::Digit4 => Code::Digit4,
            KC::Digit5 => Code::Digit5,
            KC::Digit6 => Code::Digit6,
            KC::Digit7 => Code::Digit7,
            KC::Digit8 => Code::Digit8,
            KC::Digit9 => Code::Digit9,
            KC::Equal => Code::Equal,
            KC::IntlBackslash => Code::IntlBackslash,
            KC::IntlRo => Code::IntlRo,
            KC::IntlYen => Code::IntlYen,
            KC::KeyA => Code::KeyA,
            KC::KeyB => Code::KeyB,
            KC::KeyC => Code::KeyC,
            KC::KeyD => Code::KeyD,
            KC::KeyE => Code::KeyE,
            KC::KeyF => Code::KeyF,
            KC::KeyG => Code::KeyG,
            KC::KeyH => Code::KeyH,
            KC::KeyI => Code::KeyI,
            KC::KeyJ => Code::KeyJ,
            KC::KeyK => Code::KeyK,
            KC::KeyL => Code::KeyL,
            KC::KeyM => Code::KeyM,
            KC::KeyN => Code::KeyN,
            KC::KeyO => Code::KeyO,
            KC::KeyP => Code::KeyP,
            KC::KeyQ => Code::KeyQ,
            KC::KeyR => Code::KeyR,
            KC::KeyS => Code::KeyS,
            KC::KeyT => Code::KeyT,
            KC::KeyU => Code::KeyU,
            KC::KeyV => Code::KeyV,
            KC::KeyW => Code::KeyW,
            KC::KeyX => Code::KeyX,
            KC::KeyY => Code::KeyY,
            KC::KeyZ => Code::KeyZ,
            KC::Minus => Code::Minus,
            KC::Period => Code::Period,
            KC::Quote => Code::Quote,
            KC::Semicolon => Code::Semicolon,
            KC::Slash => Code::Slash,
            KC::AltLeft => Code::AltLeft,
            KC::AltRight => Code::AltRight,
            KC::Backspace => Code::Backspace,
            KC::CapsLock => Code::CapsLock,
            KC::ContextMenu => Code::ContextMenu,
            KC::ControlLeft => Code::ControlLeft,
            KC::ControlRight => Code::ControlRight,
            KC::Enter => Code::Enter,
            KC::ShiftLeft => Code::ShiftLeft,
            KC::ShiftRight => Code::ShiftRight,
            KC::Space => Code::Space,
            KC::Tab => Code::Tab,
            KC::Convert => Code::Convert,
            KC::KanaMode => Code::KanaMode,
            KC::Lang1 => Code::Lang1,
            KC::Lang2 => Code::Lang2,
            KC::Lang3 => Code::Lang3,
            KC::Lang4 => Code::Lang4,
            KC::Lang5 => Code::Lang5,
            KC::NonConvert => Code::NonConvert,
            KC::Delete => Code::Delete,
            KC::End => Code::End,
            KC::Help => Code::Help,
            KC::Home => Code::Home,
            KC::Insert => Code::Insert,
            KC::PageDown => Code::PageDown,
            KC::PageUp => Code::PageUp,
            KC::ArrowDown => Code::ArrowDown,
            KC::ArrowLeft => Code::ArrowLeft,
            KC::ArrowRight => Code::ArrowRight,
            KC::ArrowUp => Code::ArrowUp,
            KC::NumLock => Code::NumLock,
            KC::Numpad0 => Code::Numpad0,
            KC::Numpad1 => Code::Numpad1,
            KC::Numpad2 => Code::Numpad2,
            KC::Numpad3 => Code::Numpad3,
            KC::Numpad4 => Code::Numpad4,
            KC::Numpad5 => Code::Numpad5,
            KC::Numpad6 => Code::Numpad6,
            KC::Numpad7 => Code::Numpad7,
            KC::Numpad8 => Code::Numpad8,
            KC::Numpad9 => Code::Numpad9,
            KC::NumpadAdd => Code::NumpadAdd,
            KC::NumpadBackspace => Code::NumpadBackspace,
            KC::NumpadClear => Code::NumpadClear,
            KC::NumpadClearEntry => Code::NumpadClearEntry,
            KC::NumpadComma => Code::NumpadComma,
            KC::NumpadDecimal => Code::NumpadDecimal,
            KC::NumpadDivide => Code::NumpadDivide,
            KC::NumpadEnter => Code::NumpadEnter,
            KC::NumpadEqual => Code::NumpadEqual,
            KC::NumpadHash => Code::NumpadHash,
            KC::NumpadMemoryAdd => Code::NumpadMemoryAdd,
            KC::NumpadMemoryClear => Code::NumpadMemoryClear,
            KC::NumpadMemoryRecall => Code::NumpadMemoryRecall,
            KC::NumpadMemoryStore => Code::NumpadMemoryStore,
            KC::NumpadMemorySubtract => Code::NumpadMemorySubtract,
            KC::NumpadMultiply => Code::NumpadMultiply,
            KC::NumpadParenLeft => Code::NumpadParenLeft,
            KC::NumpadParenRight => Code::NumpadParenRight,
            KC::NumpadStar => Code::NumpadStar,
            KC::NumpadSubtract => Code::NumpadSubtract,
            KC::Escape => Code::Escape,
            KC::Fn => Code::Fn,
            KC::FnLock => Code::FnLock,
            KC::PrintScreen => Code::PrintScreen,
            KC::ScrollLock => Code::ScrollLock,
            KC::Pause => Code::Pause,
            KC::BrowserBack => Code::BrowserBack,
            KC::BrowserFavorites => Code::BrowserFavorites,
            KC::BrowserForward => Code::BrowserForward,
            KC::BrowserHome => Code::BrowserHome,
            KC::BrowserRefresh => Code::BrowserRefresh,
            KC::BrowserSearch => Code::BrowserSearch,
            KC::BrowserStop => Code::BrowserStop,
            KC::Eject => Code::Eject,
            KC::LaunchApp1 => Code::LaunchApp1,
            KC::LaunchApp2 => Code::LaunchApp2,
            KC::LaunchMail => Code::LaunchMail,
            KC::MediaPlayPause => Code::MediaPlayPause,
            KC::MediaSelect => Code::MediaSelect,
            KC::MediaStop => Code::MediaStop,
            KC::MediaTrackNext => Code::MediaTrackNext,
            KC::MediaTrackPrevious => Code::MediaTrackPrevious,
            KC::Power => Code::Power,
            KC::Sleep => Code::Sleep,
            KC::AudioVolumeDown => Code::AudioVolumeDown,
            KC::AudioVolumeMute => Code::AudioVolumeMute,
            KC::AudioVolumeUp => Code::AudioVolumeUp,
            KC::WakeUp => Code::WakeUp,
            #[expect(deprecated, reason = "Deprecated but not unused.")]
            KC::Hyper => Code::Hyper,
            #[expect(deprecated, reason = "Deprecated but not unused.")]
            KC::Turbo => Code::Turbo,
            KC::Abort => Code::Abort,
            KC::Resume => Code::Resume,
            KC::Suspend => Code::Suspend,
            KC::Again => Code::Again,
            KC::Copy => Code::Copy,
            KC::Cut => Code::Cut,
            KC::Find => Code::Find,
            KC::Open => Code::Open,
            KC::Paste => Code::Paste,
            KC::Props => Code::Props,
            KC::Select => Code::Select,
            KC::Undo => Code::Undo,
            KC::Hiragana => Code::Hiragana,
            KC::Katakana => Code::Katakana,
            KC::F1 => Code::F1,
            KC::F2 => Code::F2,
            KC::F3 => Code::F3,
            KC::F4 => Code::F4,
            KC::F5 => Code::F5,
            KC::F6 => Code::F6,
            KC::F7 => Code::F7,
            KC::F8 => Code::F8,
            KC::F9 => Code::F9,
            KC::F10 => Code::F10,
            KC::F11 => Code::F11,
            KC::F12 => Code::F12,
            KC::F13 => Code::F13,
            KC::F14 => Code::F14,
            KC::F15 => Code::F15,
            KC::F16 => Code::F16,
            KC::F17 => Code::F17,
            KC::F18 => Code::F18,
            KC::F19 => Code::F19,
            KC::F20 => Code::F20,
            KC::F21 => Code::F21,
            KC::F22 => Code::F22,
            KC::F23 => Code::F23,
            KC::F24 => Code::F24,
            KC::F25 => Code::F25,
            KC::F26 => Code::F26,
            KC::F27 => Code::F27,
            KC::F28 => Code::F28,
            KC::F29 => Code::F29,
            KC::F30 => Code::F30,
            KC::F31 => Code::F31,
            KC::F32 => Code::F32,
            KC::F33 => Code::F33,
            KC::F34 => Code::F34,
            KC::F35 => Code::F35,
            _ => Code::Unidentified,
        },
    }
}