iced_winit/
conversion.rs

1//! Convert [`winit`] types into [`iced_runtime`] types, and viceversa.
2//!
3//! [`winit`]: https://github.com/rust-windowing/winit
4//! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.13/runtime
5use std::hash::DefaultHasher;
6use std::hash::Hash;
7use std::hash::Hasher;
8
9use crate::core::keyboard;
10use crate::core::mouse;
11use crate::core::touch;
12use crate::core::window;
13use crate::core::{Event, Point, Size};
14use iced_futures::core::event::PlatformSpecific;
15
16/// Converts some [`window::Settings`] into some `WindowAttributes` from `winit`.
17pub fn window_attributes(
18    settings: window::Settings,
19    title: &str,
20    primary_monitor: Option<winit::monitor::MonitorHandle>,
21    _id: Option<String>,
22) -> winit::window::WindowAttributes {
23    let mut attributes = winit::window::WindowAttributes::default();
24
25    attributes = attributes
26        .with_title(title)
27        .with_surface_size(winit::dpi::LogicalSize {
28            width: settings.size.width,
29            height: settings.size.height,
30        })
31        .with_resizable(settings.resizable)
32        .with_enabled_buttons(if settings.resizable {
33            winit::window::WindowButtons::all()
34        } else {
35            winit::window::WindowButtons::CLOSE
36                | winit::window::WindowButtons::MINIMIZE
37        })
38        .with_decorations(settings.decorations)
39        .with_transparent(settings.transparent)
40        .with_window_icon(settings.icon.and_then(icon))
41        .with_window_level(window_level(settings.level))
42        .with_visible(settings.visible);
43
44    if let Some(position) =
45        position(primary_monitor.as_ref(), settings.size, settings.position)
46    {
47        attributes = attributes.with_position(position);
48    }
49
50    if let Some(min_size) = settings.min_size {
51        attributes =
52            attributes.with_min_surface_size(winit::dpi::LogicalSize {
53                width: min_size.width,
54                height: min_size.height,
55            });
56    }
57
58    if let Some(max_size) = settings.max_size {
59        attributes =
60            attributes.with_max_surface_size(winit::dpi::LogicalSize {
61                width: max_size.width,
62                height: max_size.height,
63            });
64    }
65
66    #[cfg(any(
67        target_os = "dragonfly",
68        target_os = "freebsd",
69        target_os = "netbsd",
70        target_os = "openbsd"
71    ))]
72    {
73        use ::winit::platform::wayland::WindowAttributesExtWayland;
74
75        if let Some(id) = _id {
76            attributes = attributes.with_name(id.clone(), id);
77        }
78    }
79
80    #[cfg(target_os = "windows")]
81    {
82        use winit::platform::windows::WindowAttributesExtWindows;
83
84        attributes = attributes
85            .with_drag_and_drop(settings.platform_specific.drag_and_drop);
86
87        attributes = attributes
88            .with_skip_taskbar(settings.platform_specific.skip_taskbar);
89
90        attributes = attributes.with_undecorated_shadow(
91            settings.platform_specific.undecorated_shadow,
92        );
93    }
94
95    #[cfg(target_os = "macos")]
96    {
97        use winit::platform::macos::WindowAttributesExtMacOS;
98
99        attributes = attributes
100            .with_title_hidden(settings.platform_specific.title_hidden)
101            .with_titlebar_transparent(
102                settings.platform_specific.titlebar_transparent,
103            )
104            .with_fullsize_content_view(
105                settings.platform_specific.fullsize_content_view,
106            );
107    }
108
109    #[cfg(target_os = "linux")]
110    {
111        #[cfg(feature = "x11")]
112        {
113            use winit::platform::x11::WindowAttributesExtX11;
114
115            attributes = attributes
116                .with_override_redirect(
117                    settings.platform_specific.override_redirect,
118                )
119                .with_name(
120                    &settings.platform_specific.application_id,
121                    &settings.platform_specific.application_id,
122                );
123        }
124        #[cfg(feature = "wayland")]
125        {
126            use winit::platform::wayland::WindowAttributesExtWayland;
127
128            attributes = attributes.with_name(
129                &settings.platform_specific.application_id,
130                &settings.platform_specific.application_id,
131            );
132        }
133    }
134
135    attributes
136}
137
138/// Converts a winit window event into an iced event.
139pub fn window_event(
140    event: winit::event::WindowEvent,
141    scale_factor: f64,
142    modifiers: winit::keyboard::ModifiersState,
143) -> Option<Event> {
144    use winit::event::WindowEvent;
145
146    match event {
147        WindowEvent::SurfaceResized(new_size) => {
148            let logical_size = new_size.to_logical(scale_factor);
149
150            Some(Event::Window(window::Event::Resized(Size {
151                width: logical_size.width,
152                height: logical_size.height,
153            })))
154        }
155        WindowEvent::CloseRequested => {
156            Some(Event::Window(window::Event::CloseRequested))
157        }
158        WindowEvent::CursorMoved { position, .. } => {
159            let position = position.to_logical::<f64>(scale_factor);
160
161            Some(Event::Mouse(mouse::Event::CursorMoved {
162                position: Point::new(position.x as f32, position.y as f32),
163            }))
164        }
165        WindowEvent::CursorEntered { .. } => {
166            Some(Event::Mouse(mouse::Event::CursorEntered))
167        }
168        WindowEvent::CursorLeft { .. } => {
169            Some(Event::Mouse(mouse::Event::CursorLeft))
170        }
171        WindowEvent::MouseInput { button, state, .. } => {
172            let button = mouse_button(button);
173
174            Some(Event::Mouse(match state {
175                winit::event::ElementState::Pressed => {
176                    mouse::Event::ButtonPressed(button)
177                }
178                winit::event::ElementState::Released => {
179                    mouse::Event::ButtonReleased(button)
180                }
181            }))
182        }
183        WindowEvent::MouseWheel { delta, .. } => match delta {
184            winit::event::MouseScrollDelta::LineDelta(delta_x, delta_y) => {
185                Some(Event::Mouse(mouse::Event::WheelScrolled {
186                    delta: mouse::ScrollDelta::Lines {
187                        x: delta_x,
188                        y: delta_y,
189                    },
190                }))
191            }
192            winit::event::MouseScrollDelta::PixelDelta(position) => {
193                Some(Event::Mouse(mouse::Event::WheelScrolled {
194                    delta: mouse::ScrollDelta::Pixels {
195                        x: position.x as f32,
196                        y: position.y as f32,
197                    },
198                }))
199            }
200        },
201        WindowEvent::KeyboardInput { event, .. } => Some(Event::Keyboard({
202            let key = {
203                #[cfg(not(target_arch = "wasm32"))]
204                {
205                    use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
206                    event.key_without_modifiers()
207                }
208
209                #[cfg(target_arch = "wasm32")]
210                {
211                    // TODO: Fix inconsistent API on Wasm
212                    event.logical_key.clone()
213                }
214            };
215
216            let text = {
217                #[cfg(not(target_arch = "wasm32"))]
218                {
219                    use crate::core::SmolStr;
220                    use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
221
222                    event.text_with_all_modifiers().map(SmolStr::new)
223                }
224
225                #[cfg(target_arch = "wasm32")]
226                {
227                    // TODO: Fix inconsistent API on Wasm
228                    event.text
229                }
230            }.filter(|text| !text.as_str().chars().any(is_private_use));
231
232            let winit::event::KeyEvent {
233                state,
234                location,
235                logical_key,
236                physical_key,
237                ..
238            } = event;
239
240            let key = self::key(key);
241            let modified_key = self::key(logical_key);
242            let physical_key = self::physical_key(physical_key);
243            let modifiers = self::modifiers(modifiers);
244
245            let location = match location {
246                winit::keyboard::KeyLocation::Standard => {
247                    keyboard::Location::Standard
248                }
249                winit::keyboard::KeyLocation::Left => keyboard::Location::Left,
250                winit::keyboard::KeyLocation::Right => {
251                    keyboard::Location::Right
252                }
253                winit::keyboard::KeyLocation::Numpad => {
254                    keyboard::Location::Numpad
255                }
256            };
257
258            match state {
259                winit::event::ElementState::Pressed => {
260                    keyboard::Event::KeyPressed {
261                        key,
262                        modified_key,
263                        physical_key,
264                        modifiers,
265                        location,
266                        text,
267                    }
268                }
269                winit::event::ElementState::Released => {
270                    keyboard::Event::KeyReleased {
271                        key,
272                        modified_key,
273                        physical_key,
274                        modifiers,
275                        location,
276                    }
277                }
278            }
279        })),
280        WindowEvent::ModifiersChanged(new_modifiers) => {
281            Some(Event::Keyboard(keyboard::Event::ModifiersChanged(
282                self::modifiers(new_modifiers.state()),
283            )))
284        }
285        WindowEvent::Focused(focused) => Some(Event::Window(if focused {
286            window::Event::Focused
287        } else {
288            window::Event::Unfocused
289        })),
290        WindowEvent::HoveredFile(path) => {
291            Some(Event::Window(window::Event::FileHovered(path.clone())))
292        }
293        WindowEvent::DroppedFile(path) => {
294            Some(Event::Window(window::Event::FileDropped(path.clone())))
295        }
296        WindowEvent::HoveredFileCancelled => {
297            Some(Event::Window(window::Event::FilesHoveredLeft))
298        }
299        WindowEvent::Touch(touch) => {
300            Some(Event::Touch(touch_event(touch, scale_factor)))
301        }
302        WindowEvent::Moved(position) => {
303            let winit::dpi::LogicalPosition { x, y } =
304                position.to_logical(scale_factor);
305
306            Some(Event::Window(window::Event::Moved(Point::new(x, y))))
307        }
308        #[cfg(feature = "wayland")]
309        WindowEvent::SuggestedBounds(bounds) => {
310            let size = bounds.map(|bounds| {
311                let size = bounds.to_logical(scale_factor);
312                Size::new(size.width, size.height)
313            });
314
315            Some(Event::PlatformSpecific(PlatformSpecific::Wayland(
316                iced_runtime::core::event::wayland::Event::Window(
317                    iced_runtime::core::event::wayland::WindowEvent::SuggestedBounds(size),
318                ),
319            )))
320        }
321
322        _ => None,
323    }
324}
325
326/// Converts a [`window::Level`] to a [`winit`] window level.
327///
328/// [`winit`]: https://github.com/rust-windowing/winit
329pub fn window_level(level: window::Level) -> winit::window::WindowLevel {
330    match level {
331        window::Level::Normal => winit::window::WindowLevel::Normal,
332        window::Level::AlwaysOnBottom => {
333            winit::window::WindowLevel::AlwaysOnBottom
334        }
335        window::Level::AlwaysOnTop => winit::window::WindowLevel::AlwaysOnTop,
336    }
337}
338
339/// Converts a [`window::Position`] to a [`winit`] logical position for a given monitor.
340///
341/// [`winit`]: https://github.com/rust-windowing/winit
342pub fn position(
343    monitor: Option<&winit::monitor::MonitorHandle>,
344    size: Size,
345    position: window::Position,
346) -> Option<winit::dpi::Position> {
347    match position {
348        window::Position::Default => None,
349        window::Position::Specific(position) => {
350            Some(winit::dpi::Position::Logical(winit::dpi::LogicalPosition {
351                x: f64::from(position.x),
352                y: f64::from(position.y),
353            }))
354        }
355        window::Position::SpecificWith(to_position) => {
356            if let Some(monitor) = monitor {
357                let start = monitor.position().unwrap_or_default();
358
359                let resolution: winit::dpi::LogicalSize<f32> = monitor
360                    .current_video_mode()
361                    .map(|m| m.size().to_logical(monitor.scale_factor()))
362                    .unwrap_or_default();
363
364                let position = to_position(
365                    size,
366                    Size::new(resolution.width, resolution.height),
367                );
368
369                let centered: winit::dpi::PhysicalPosition<i32> =
370                    winit::dpi::LogicalPosition {
371                        x: position.x,
372                        y: position.y,
373                    }
374                    .to_physical(monitor.scale_factor());
375
376                Some(winit::dpi::Position::Physical(
377                    winit::dpi::PhysicalPosition {
378                        x: start.x + centered.x,
379                        y: start.y + centered.y,
380                    },
381                ))
382            } else {
383                None
384            }
385        }
386        window::Position::Centered => {
387            if let Some(monitor) = monitor {
388                let start = monitor.position().unwrap_or_default();
389
390                let resolution: winit::dpi::LogicalSize<f64> = monitor
391                    .current_video_mode()
392                    .map(|m| m.size().to_logical(monitor.scale_factor()))
393                    .unwrap_or_default();
394
395                let centered: winit::dpi::PhysicalPosition<i32> =
396                    winit::dpi::LogicalPosition {
397                        x: (resolution.width - f64::from(size.width)) / 2.0,
398                        y: (resolution.height - f64::from(size.height)) / 2.0,
399                    }
400                    .to_physical(monitor.scale_factor());
401
402                Some(winit::dpi::Position::Physical(
403                    winit::dpi::PhysicalPosition {
404                        x: start.x + centered.x,
405                        y: start.y + centered.y,
406                    },
407                ))
408            } else {
409                None
410            }
411        }
412    }
413}
414
415/// Converts a [`window::Mode`] to a [`winit`] fullscreen mode.
416///
417/// [`winit`]: https://github.com/rust-windowing/winit
418pub fn fullscreen(
419    monitor: Option<winit::monitor::MonitorHandle>,
420    mode: window::Mode,
421) -> Option<winit::window::Fullscreen> {
422    match mode {
423        window::Mode::Windowed | window::Mode::Hidden => None,
424        window::Mode::Fullscreen => {
425            Some(winit::window::Fullscreen::Borderless(monitor))
426        }
427    }
428}
429
430/// Converts a [`window::Mode`] to a visibility flag.
431pub fn visible(mode: window::Mode) -> bool {
432    match mode {
433        window::Mode::Windowed | window::Mode::Fullscreen => true,
434        window::Mode::Hidden => false,
435    }
436}
437
438/// Converts a [`winit`] fullscreen mode to a [`window::Mode`].
439///
440/// [`winit`]: https://github.com/rust-windowing/winit
441pub fn mode(mode: Option<winit::window::Fullscreen>) -> window::Mode {
442    match mode {
443        None => window::Mode::Windowed,
444        Some(_) => window::Mode::Fullscreen,
445    }
446}
447
448/// Converts a [`mouse::Interaction`] to a [`winit`] cursor icon.
449///
450/// [`winit`]: https://github.com/rust-windowing/winit
451pub fn mouse_interaction(
452    interaction: mouse::Interaction,
453) -> Option<winit::window::CursorIcon> {
454    use mouse::Interaction;
455
456    Some(match interaction {
457        Interaction::None | Interaction::Idle => {
458            winit::window::CursorIcon::Default
459        }
460        Interaction::Pointer => winit::window::CursorIcon::Pointer,
461        Interaction::Working => winit::window::CursorIcon::Progress,
462        Interaction::Grab => winit::window::CursorIcon::Grab,
463        Interaction::Grabbing => winit::window::CursorIcon::Grabbing,
464        Interaction::Crosshair => winit::window::CursorIcon::Crosshair,
465        Interaction::Text => winit::window::CursorIcon::Text,
466        Interaction::ResizingHorizontally => {
467            winit::window::CursorIcon::EwResize
468        }
469        Interaction::ResizingVertically => winit::window::CursorIcon::NsResize,
470        Interaction::ResizingDiagonallyUp => {
471            winit::window::CursorIcon::NeswResize
472        }
473        Interaction::ResizingDiagonallyDown => {
474            winit::window::CursorIcon::NwseResize
475        }
476        Interaction::NotAllowed => winit::window::CursorIcon::NotAllowed,
477        Interaction::ZoomIn => winit::window::CursorIcon::ZoomIn,
478        Interaction::ZoomOut => winit::window::CursorIcon::ZoomOut,
479        Interaction::Cell => winit::window::CursorIcon::Cell,
480        Interaction::Move => winit::window::CursorIcon::Move,
481        Interaction::Copy => winit::window::CursorIcon::Copy,
482        Interaction::Help => winit::window::CursorIcon::Help,
483        Interaction::Hide => {
484            return None;
485        }
486    })
487}
488
489/// Converts a `MouseButton` from [`winit`] to an [`iced`] mouse button.
490///
491/// [`winit`]: https://github.com/rust-windowing/winit
492/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
493pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
494    match mouse_button {
495        winit::event::MouseButton::Left => mouse::Button::Left,
496        winit::event::MouseButton::Right => mouse::Button::Right,
497        winit::event::MouseButton::Middle => mouse::Button::Middle,
498        winit::event::MouseButton::Back => mouse::Button::Back,
499        winit::event::MouseButton::Forward => mouse::Button::Forward,
500        winit::event::MouseButton::Other(other) => mouse::Button::Other(other),
501    }
502}
503
504/// Converts some `ModifiersState` from [`winit`] to an [`iced`] modifiers
505/// state.
506///
507/// [`winit`]: https://github.com/rust-windowing/winit
508/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
509pub fn modifiers(
510    modifiers: winit::keyboard::ModifiersState,
511) -> keyboard::Modifiers {
512    let mut result = keyboard::Modifiers::empty();
513
514    result.set(keyboard::Modifiers::SHIFT, modifiers.shift_key());
515    result.set(keyboard::Modifiers::CTRL, modifiers.control_key());
516    result.set(keyboard::Modifiers::ALT, modifiers.alt_key());
517    result.set(keyboard::Modifiers::LOGO, modifiers.super_key());
518
519    result
520}
521
522/// Converts a physical cursor position to a logical `Point`.
523pub fn cursor_position(
524    position: winit::dpi::PhysicalPosition<f64>,
525    scale_factor: f64,
526) -> Point {
527    let logical_position = position.to_logical(scale_factor);
528
529    Point::new(logical_position.x, logical_position.y)
530}
531
532/// Converts a `Touch` from [`winit`] to an [`iced`] touch event.
533///
534/// [`winit`]: https://github.com/rust-windowing/winit
535/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
536pub fn touch_event(
537    touch: winit::event::Touch,
538    scale_factor: f64,
539) -> touch::Event {
540    // TODO we probably should get the actual internal id in some way instead
541    let mut s = DefaultHasher::new();
542    touch.finger_id.hash(&mut s);
543
544    let id = touch::Finger(s.finish());
545    let position = {
546        let location = touch.location.to_logical::<f64>(scale_factor);
547
548        Point::new(location.x as f32, location.y as f32)
549    };
550
551    match touch.phase {
552        winit::event::TouchPhase::Started => {
553            touch::Event::FingerPressed { id, position }
554        }
555        winit::event::TouchPhase::Moved => {
556            touch::Event::FingerMoved { id, position }
557        }
558        winit::event::TouchPhase::Ended => {
559            touch::Event::FingerLifted { id, position }
560        }
561        winit::event::TouchPhase::Cancelled => {
562            touch::Event::FingerLost { id, position }
563        }
564    }
565}
566
567/// Converts a `Key` from [`winit`] to an [`iced`] key.
568///
569/// [`winit`]: https://github.com/rust-windowing/winit
570/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
571pub fn key(key: winit::keyboard::Key) -> keyboard::Key {
572    use keyboard::key::Named;
573    use winit::keyboard::NamedKey;
574
575    match key {
576        winit::keyboard::Key::Character(c) => keyboard::Key::Character(c),
577        winit::keyboard::Key::Named(named_key) => {
578            keyboard::Key::Named(match named_key {
579                NamedKey::Alt => Named::Alt,
580                NamedKey::AltGraph => Named::AltGraph,
581                NamedKey::CapsLock => Named::CapsLock,
582                NamedKey::Control => Named::Control,
583                NamedKey::Fn => Named::Fn,
584                NamedKey::FnLock => Named::FnLock,
585                NamedKey::NumLock => Named::NumLock,
586                NamedKey::ScrollLock => Named::ScrollLock,
587                NamedKey::Shift => Named::Shift,
588                NamedKey::Symbol => Named::Symbol,
589                NamedKey::SymbolLock => Named::SymbolLock,
590                NamedKey::Meta => Named::Meta,
591                NamedKey::Hyper => Named::Hyper,
592                NamedKey::Super => Named::Super,
593                NamedKey::Enter => Named::Enter,
594                NamedKey::Tab => Named::Tab,
595                NamedKey::Space => Named::Space,
596                NamedKey::ArrowDown => Named::ArrowDown,
597                NamedKey::ArrowLeft => Named::ArrowLeft,
598                NamedKey::ArrowRight => Named::ArrowRight,
599                NamedKey::ArrowUp => Named::ArrowUp,
600                NamedKey::End => Named::End,
601                NamedKey::Home => Named::Home,
602                NamedKey::PageDown => Named::PageDown,
603                NamedKey::PageUp => Named::PageUp,
604                NamedKey::Backspace => Named::Backspace,
605                NamedKey::Clear => Named::Clear,
606                NamedKey::Copy => Named::Copy,
607                NamedKey::CrSel => Named::CrSel,
608                NamedKey::Cut => Named::Cut,
609                NamedKey::Delete => Named::Delete,
610                NamedKey::EraseEof => Named::EraseEof,
611                NamedKey::ExSel => Named::ExSel,
612                NamedKey::Insert => Named::Insert,
613                NamedKey::Paste => Named::Paste,
614                NamedKey::Redo => Named::Redo,
615                NamedKey::Undo => Named::Undo,
616                NamedKey::Accept => Named::Accept,
617                NamedKey::Again => Named::Again,
618                NamedKey::Attn => Named::Attn,
619                NamedKey::Cancel => Named::Cancel,
620                NamedKey::ContextMenu => Named::ContextMenu,
621                NamedKey::Escape => Named::Escape,
622                NamedKey::Execute => Named::Execute,
623                NamedKey::Find => Named::Find,
624                NamedKey::Help => Named::Help,
625                NamedKey::Pause => Named::Pause,
626                NamedKey::Play => Named::Play,
627                NamedKey::Props => Named::Props,
628                NamedKey::Select => Named::Select,
629                NamedKey::ZoomIn => Named::ZoomIn,
630                NamedKey::ZoomOut => Named::ZoomOut,
631                NamedKey::BrightnessDown => Named::BrightnessDown,
632                NamedKey::BrightnessUp => Named::BrightnessUp,
633                NamedKey::Eject => Named::Eject,
634                NamedKey::LogOff => Named::LogOff,
635                NamedKey::Power => Named::Power,
636                NamedKey::PowerOff => Named::PowerOff,
637                NamedKey::PrintScreen => Named::PrintScreen,
638                NamedKey::Hibernate => Named::Hibernate,
639                NamedKey::Standby => Named::Standby,
640                NamedKey::WakeUp => Named::WakeUp,
641                NamedKey::AllCandidates => Named::AllCandidates,
642                NamedKey::Alphanumeric => Named::Alphanumeric,
643                NamedKey::CodeInput => Named::CodeInput,
644                NamedKey::Compose => Named::Compose,
645                NamedKey::Convert => Named::Convert,
646                NamedKey::FinalMode => Named::FinalMode,
647                NamedKey::GroupFirst => Named::GroupFirst,
648                NamedKey::GroupLast => Named::GroupLast,
649                NamedKey::GroupNext => Named::GroupNext,
650                NamedKey::GroupPrevious => Named::GroupPrevious,
651                NamedKey::ModeChange => Named::ModeChange,
652                NamedKey::NextCandidate => Named::NextCandidate,
653                NamedKey::NonConvert => Named::NonConvert,
654                NamedKey::PreviousCandidate => Named::PreviousCandidate,
655                NamedKey::Process => Named::Process,
656                NamedKey::SingleCandidate => Named::SingleCandidate,
657                NamedKey::HangulMode => Named::HangulMode,
658                NamedKey::HanjaMode => Named::HanjaMode,
659                NamedKey::JunjaMode => Named::JunjaMode,
660                NamedKey::Eisu => Named::Eisu,
661                NamedKey::Hankaku => Named::Hankaku,
662                NamedKey::Hiragana => Named::Hiragana,
663                NamedKey::HiraganaKatakana => Named::HiraganaKatakana,
664                NamedKey::KanaMode => Named::KanaMode,
665                NamedKey::KanjiMode => Named::KanjiMode,
666                NamedKey::Katakana => Named::Katakana,
667                NamedKey::Romaji => Named::Romaji,
668                NamedKey::Zenkaku => Named::Zenkaku,
669                NamedKey::ZenkakuHankaku => Named::ZenkakuHankaku,
670                NamedKey::Soft1 => Named::Soft1,
671                NamedKey::Soft2 => Named::Soft2,
672                NamedKey::Soft3 => Named::Soft3,
673                NamedKey::Soft4 => Named::Soft4,
674                NamedKey::ChannelDown => Named::ChannelDown,
675                NamedKey::ChannelUp => Named::ChannelUp,
676                NamedKey::Close => Named::Close,
677                NamedKey::MailForward => Named::MailForward,
678                NamedKey::MailReply => Named::MailReply,
679                NamedKey::MailSend => Named::MailSend,
680                NamedKey::MediaClose => Named::MediaClose,
681                NamedKey::MediaFastForward => Named::MediaFastForward,
682                NamedKey::MediaPause => Named::MediaPause,
683                NamedKey::MediaPlay => Named::MediaPlay,
684                NamedKey::MediaPlayPause => Named::MediaPlayPause,
685                NamedKey::MediaRecord => Named::MediaRecord,
686                NamedKey::MediaRewind => Named::MediaRewind,
687                NamedKey::MediaStop => Named::MediaStop,
688                NamedKey::MediaTrackNext => Named::MediaTrackNext,
689                NamedKey::MediaTrackPrevious => Named::MediaTrackPrevious,
690                NamedKey::New => Named::New,
691                NamedKey::Open => Named::Open,
692                NamedKey::Print => Named::Print,
693                NamedKey::Save => Named::Save,
694                NamedKey::SpellCheck => Named::SpellCheck,
695                NamedKey::Key11 => Named::Key11,
696                NamedKey::Key12 => Named::Key12,
697                NamedKey::AudioBalanceLeft => Named::AudioBalanceLeft,
698                NamedKey::AudioBalanceRight => Named::AudioBalanceRight,
699                NamedKey::AudioBassBoostDown => Named::AudioBassBoostDown,
700                NamedKey::AudioBassBoostToggle => Named::AudioBassBoostToggle,
701                NamedKey::AudioBassBoostUp => Named::AudioBassBoostUp,
702                NamedKey::AudioFaderFront => Named::AudioFaderFront,
703                NamedKey::AudioFaderRear => Named::AudioFaderRear,
704                NamedKey::AudioSurroundModeNext => Named::AudioSurroundModeNext,
705                NamedKey::AudioTrebleDown => Named::AudioTrebleDown,
706                NamedKey::AudioTrebleUp => Named::AudioTrebleUp,
707                NamedKey::AudioVolumeDown => Named::AudioVolumeDown,
708                NamedKey::AudioVolumeUp => Named::AudioVolumeUp,
709                NamedKey::AudioVolumeMute => Named::AudioVolumeMute,
710                NamedKey::MicrophoneToggle => Named::MicrophoneToggle,
711                NamedKey::MicrophoneVolumeDown => Named::MicrophoneVolumeDown,
712                NamedKey::MicrophoneVolumeUp => Named::MicrophoneVolumeUp,
713                NamedKey::MicrophoneVolumeMute => Named::MicrophoneVolumeMute,
714                NamedKey::SpeechCorrectionList => Named::SpeechCorrectionList,
715                NamedKey::SpeechInputToggle => Named::SpeechInputToggle,
716                NamedKey::LaunchApplication1 => Named::LaunchApplication1,
717                NamedKey::LaunchApplication2 => Named::LaunchApplication2,
718                NamedKey::LaunchCalendar => Named::LaunchCalendar,
719                NamedKey::LaunchContacts => Named::LaunchContacts,
720                NamedKey::LaunchMail => Named::LaunchMail,
721                NamedKey::LaunchMediaPlayer => Named::LaunchMediaPlayer,
722                NamedKey::LaunchMusicPlayer => Named::LaunchMusicPlayer,
723                NamedKey::LaunchPhone => Named::LaunchPhone,
724                NamedKey::LaunchScreenSaver => Named::LaunchScreenSaver,
725                NamedKey::LaunchSpreadsheet => Named::LaunchSpreadsheet,
726                NamedKey::LaunchWebBrowser => Named::LaunchWebBrowser,
727                NamedKey::LaunchWebCam => Named::LaunchWebCam,
728                NamedKey::LaunchWordProcessor => Named::LaunchWordProcessor,
729                NamedKey::BrowserBack => Named::BrowserBack,
730                NamedKey::BrowserFavorites => Named::BrowserFavorites,
731                NamedKey::BrowserForward => Named::BrowserForward,
732                NamedKey::BrowserHome => Named::BrowserHome,
733                NamedKey::BrowserRefresh => Named::BrowserRefresh,
734                NamedKey::BrowserSearch => Named::BrowserSearch,
735                NamedKey::BrowserStop => Named::BrowserStop,
736                NamedKey::AppSwitch => Named::AppSwitch,
737                NamedKey::Call => Named::Call,
738                NamedKey::Camera => Named::Camera,
739                NamedKey::CameraFocus => Named::CameraFocus,
740                NamedKey::EndCall => Named::EndCall,
741                NamedKey::GoBack => Named::GoBack,
742                NamedKey::GoHome => Named::GoHome,
743                NamedKey::HeadsetHook => Named::HeadsetHook,
744                NamedKey::LastNumberRedial => Named::LastNumberRedial,
745                NamedKey::Notification => Named::Notification,
746                NamedKey::MannerMode => Named::MannerMode,
747                NamedKey::VoiceDial => Named::VoiceDial,
748                NamedKey::TV => Named::TV,
749                NamedKey::TV3DMode => Named::TV3DMode,
750                NamedKey::TVAntennaCable => Named::TVAntennaCable,
751                NamedKey::TVAudioDescription => Named::TVAudioDescription,
752                NamedKey::TVAudioDescriptionMixDown => {
753                    Named::TVAudioDescriptionMixDown
754                }
755                NamedKey::TVAudioDescriptionMixUp => {
756                    Named::TVAudioDescriptionMixUp
757                }
758                NamedKey::TVContentsMenu => Named::TVContentsMenu,
759                NamedKey::TVDataService => Named::TVDataService,
760                NamedKey::TVInput => Named::TVInput,
761                NamedKey::TVInputComponent1 => Named::TVInputComponent1,
762                NamedKey::TVInputComponent2 => Named::TVInputComponent2,
763                NamedKey::TVInputComposite1 => Named::TVInputComposite1,
764                NamedKey::TVInputComposite2 => Named::TVInputComposite2,
765                NamedKey::TVInputHDMI1 => Named::TVInputHDMI1,
766                NamedKey::TVInputHDMI2 => Named::TVInputHDMI2,
767                NamedKey::TVInputHDMI3 => Named::TVInputHDMI3,
768                NamedKey::TVInputHDMI4 => Named::TVInputHDMI4,
769                NamedKey::TVInputVGA1 => Named::TVInputVGA1,
770                NamedKey::TVMediaContext => Named::TVMediaContext,
771                NamedKey::TVNetwork => Named::TVNetwork,
772                NamedKey::TVNumberEntry => Named::TVNumberEntry,
773                NamedKey::TVPower => Named::TVPower,
774                NamedKey::TVRadioService => Named::TVRadioService,
775                NamedKey::TVSatellite => Named::TVSatellite,
776                NamedKey::TVSatelliteBS => Named::TVSatelliteBS,
777                NamedKey::TVSatelliteCS => Named::TVSatelliteCS,
778                NamedKey::TVSatelliteToggle => Named::TVSatelliteToggle,
779                NamedKey::TVTerrestrialAnalog => Named::TVTerrestrialAnalog,
780                NamedKey::TVTerrestrialDigital => Named::TVTerrestrialDigital,
781                NamedKey::TVTimer => Named::TVTimer,
782                NamedKey::AVRInput => Named::AVRInput,
783                NamedKey::AVRPower => Named::AVRPower,
784                NamedKey::ColorF0Red => Named::ColorF0Red,
785                NamedKey::ColorF1Green => Named::ColorF1Green,
786                NamedKey::ColorF2Yellow => Named::ColorF2Yellow,
787                NamedKey::ColorF3Blue => Named::ColorF3Blue,
788                NamedKey::ColorF4Grey => Named::ColorF4Grey,
789                NamedKey::ColorF5Brown => Named::ColorF5Brown,
790                NamedKey::ClosedCaptionToggle => Named::ClosedCaptionToggle,
791                NamedKey::Dimmer => Named::Dimmer,
792                NamedKey::DisplaySwap => Named::DisplaySwap,
793                NamedKey::DVR => Named::DVR,
794                NamedKey::Exit => Named::Exit,
795                NamedKey::FavoriteClear0 => Named::FavoriteClear0,
796                NamedKey::FavoriteClear1 => Named::FavoriteClear1,
797                NamedKey::FavoriteClear2 => Named::FavoriteClear2,
798                NamedKey::FavoriteClear3 => Named::FavoriteClear3,
799                NamedKey::FavoriteRecall0 => Named::FavoriteRecall0,
800                NamedKey::FavoriteRecall1 => Named::FavoriteRecall1,
801                NamedKey::FavoriteRecall2 => Named::FavoriteRecall2,
802                NamedKey::FavoriteRecall3 => Named::FavoriteRecall3,
803                NamedKey::FavoriteStore0 => Named::FavoriteStore0,
804                NamedKey::FavoriteStore1 => Named::FavoriteStore1,
805                NamedKey::FavoriteStore2 => Named::FavoriteStore2,
806                NamedKey::FavoriteStore3 => Named::FavoriteStore3,
807                NamedKey::Guide => Named::Guide,
808                NamedKey::GuideNextDay => Named::GuideNextDay,
809                NamedKey::GuidePreviousDay => Named::GuidePreviousDay,
810                NamedKey::Info => Named::Info,
811                NamedKey::InstantReplay => Named::InstantReplay,
812                NamedKey::Link => Named::Link,
813                NamedKey::ListProgram => Named::ListProgram,
814                NamedKey::LiveContent => Named::LiveContent,
815                NamedKey::Lock => Named::Lock,
816                NamedKey::MediaApps => Named::MediaApps,
817                NamedKey::MediaAudioTrack => Named::MediaAudioTrack,
818                NamedKey::MediaLast => Named::MediaLast,
819                NamedKey::MediaSkipBackward => Named::MediaSkipBackward,
820                NamedKey::MediaSkipForward => Named::MediaSkipForward,
821                NamedKey::MediaStepBackward => Named::MediaStepBackward,
822                NamedKey::MediaStepForward => Named::MediaStepForward,
823                NamedKey::MediaTopMenu => Named::MediaTopMenu,
824                NamedKey::NavigateIn => Named::NavigateIn,
825                NamedKey::NavigateNext => Named::NavigateNext,
826                NamedKey::NavigateOut => Named::NavigateOut,
827                NamedKey::NavigatePrevious => Named::NavigatePrevious,
828                NamedKey::NextFavoriteChannel => Named::NextFavoriteChannel,
829                NamedKey::NextUserProfile => Named::NextUserProfile,
830                NamedKey::OnDemand => Named::OnDemand,
831                NamedKey::Pairing => Named::Pairing,
832                NamedKey::PinPDown => Named::PinPDown,
833                NamedKey::PinPMove => Named::PinPMove,
834                NamedKey::PinPToggle => Named::PinPToggle,
835                NamedKey::PinPUp => Named::PinPUp,
836                NamedKey::PlaySpeedDown => Named::PlaySpeedDown,
837                NamedKey::PlaySpeedReset => Named::PlaySpeedReset,
838                NamedKey::PlaySpeedUp => Named::PlaySpeedUp,
839                NamedKey::RandomToggle => Named::RandomToggle,
840                NamedKey::RcLowBattery => Named::RcLowBattery,
841                NamedKey::RecordSpeedNext => Named::RecordSpeedNext,
842                NamedKey::RfBypass => Named::RfBypass,
843                NamedKey::ScanChannelsToggle => Named::ScanChannelsToggle,
844                NamedKey::ScreenModeNext => Named::ScreenModeNext,
845                NamedKey::Settings => Named::Settings,
846                NamedKey::SplitScreenToggle => Named::SplitScreenToggle,
847                NamedKey::STBInput => Named::STBInput,
848                NamedKey::STBPower => Named::STBPower,
849                NamedKey::Subtitle => Named::Subtitle,
850                NamedKey::Teletext => Named::Teletext,
851                NamedKey::VideoModeNext => Named::VideoModeNext,
852                NamedKey::Wink => Named::Wink,
853                NamedKey::ZoomToggle => Named::ZoomToggle,
854                NamedKey::F1 => Named::F1,
855                NamedKey::F2 => Named::F2,
856                NamedKey::F3 => Named::F3,
857                NamedKey::F4 => Named::F4,
858                NamedKey::F5 => Named::F5,
859                NamedKey::F6 => Named::F6,
860                NamedKey::F7 => Named::F7,
861                NamedKey::F8 => Named::F8,
862                NamedKey::F9 => Named::F9,
863                NamedKey::F10 => Named::F10,
864                NamedKey::F11 => Named::F11,
865                NamedKey::F12 => Named::F12,
866                NamedKey::F13 => Named::F13,
867                NamedKey::F14 => Named::F14,
868                NamedKey::F15 => Named::F15,
869                NamedKey::F16 => Named::F16,
870                NamedKey::F17 => Named::F17,
871                NamedKey::F18 => Named::F18,
872                NamedKey::F19 => Named::F19,
873                NamedKey::F20 => Named::F20,
874                NamedKey::F21 => Named::F21,
875                NamedKey::F22 => Named::F22,
876                NamedKey::F23 => Named::F23,
877                NamedKey::F24 => Named::F24,
878                NamedKey::F25 => Named::F25,
879                NamedKey::F26 => Named::F26,
880                NamedKey::F27 => Named::F27,
881                NamedKey::F28 => Named::F28,
882                NamedKey::F29 => Named::F29,
883                NamedKey::F30 => Named::F30,
884                NamedKey::F31 => Named::F31,
885                NamedKey::F32 => Named::F32,
886                NamedKey::F33 => Named::F33,
887                NamedKey::F34 => Named::F34,
888                NamedKey::F35 => Named::F35,
889                _ => return keyboard::Key::Unidentified,
890            })
891        }
892        _ => keyboard::Key::Unidentified,
893    }
894}
895
896/// Converts a `PhysicalKey` from [`winit`] to an [`iced`] physical key.
897///
898/// [`winit`]: https://github.com/rust-windowing/winit
899/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
900pub fn physical_key(
901    physical_key: winit::keyboard::PhysicalKey,
902) -> keyboard::key::Physical {
903    match physical_key {
904        winit::keyboard::PhysicalKey::Code(code) => key_code(code)
905            .map(keyboard::key::Physical::Code)
906            .unwrap_or(keyboard::key::Physical::Unidentified(
907                keyboard::key::NativeCode::Unidentified,
908            )),
909        winit::keyboard::PhysicalKey::Unidentified(code) => {
910            keyboard::key::Physical::Unidentified(native_key_code(code))
911        }
912    }
913}
914
915/// Converts a `KeyCode` from [`winit`] to an [`iced`] key code.
916///
917/// [`winit`]: https://github.com/rust-windowing/winit
918/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
919pub fn key_code(
920    key_code: winit::keyboard::KeyCode,
921) -> Option<keyboard::key::Code> {
922    use winit::keyboard::KeyCode;
923
924    Some(match key_code {
925        KeyCode::Backquote => keyboard::key::Code::Backquote,
926        KeyCode::Backslash => keyboard::key::Code::Backslash,
927        KeyCode::BracketLeft => keyboard::key::Code::BracketLeft,
928        KeyCode::BracketRight => keyboard::key::Code::BracketRight,
929        KeyCode::Comma => keyboard::key::Code::Comma,
930        KeyCode::Digit0 => keyboard::key::Code::Digit0,
931        KeyCode::Digit1 => keyboard::key::Code::Digit1,
932        KeyCode::Digit2 => keyboard::key::Code::Digit2,
933        KeyCode::Digit3 => keyboard::key::Code::Digit3,
934        KeyCode::Digit4 => keyboard::key::Code::Digit4,
935        KeyCode::Digit5 => keyboard::key::Code::Digit5,
936        KeyCode::Digit6 => keyboard::key::Code::Digit6,
937        KeyCode::Digit7 => keyboard::key::Code::Digit7,
938        KeyCode::Digit8 => keyboard::key::Code::Digit8,
939        KeyCode::Digit9 => keyboard::key::Code::Digit9,
940        KeyCode::Equal => keyboard::key::Code::Equal,
941        KeyCode::IntlBackslash => keyboard::key::Code::IntlBackslash,
942        KeyCode::IntlRo => keyboard::key::Code::IntlRo,
943        KeyCode::IntlYen => keyboard::key::Code::IntlYen,
944        KeyCode::KeyA => keyboard::key::Code::KeyA,
945        KeyCode::KeyB => keyboard::key::Code::KeyB,
946        KeyCode::KeyC => keyboard::key::Code::KeyC,
947        KeyCode::KeyD => keyboard::key::Code::KeyD,
948        KeyCode::KeyE => keyboard::key::Code::KeyE,
949        KeyCode::KeyF => keyboard::key::Code::KeyF,
950        KeyCode::KeyG => keyboard::key::Code::KeyG,
951        KeyCode::KeyH => keyboard::key::Code::KeyH,
952        KeyCode::KeyI => keyboard::key::Code::KeyI,
953        KeyCode::KeyJ => keyboard::key::Code::KeyJ,
954        KeyCode::KeyK => keyboard::key::Code::KeyK,
955        KeyCode::KeyL => keyboard::key::Code::KeyL,
956        KeyCode::KeyM => keyboard::key::Code::KeyM,
957        KeyCode::KeyN => keyboard::key::Code::KeyN,
958        KeyCode::KeyO => keyboard::key::Code::KeyO,
959        KeyCode::KeyP => keyboard::key::Code::KeyP,
960        KeyCode::KeyQ => keyboard::key::Code::KeyQ,
961        KeyCode::KeyR => keyboard::key::Code::KeyR,
962        KeyCode::KeyS => keyboard::key::Code::KeyS,
963        KeyCode::KeyT => keyboard::key::Code::KeyT,
964        KeyCode::KeyU => keyboard::key::Code::KeyU,
965        KeyCode::KeyV => keyboard::key::Code::KeyV,
966        KeyCode::KeyW => keyboard::key::Code::KeyW,
967        KeyCode::KeyX => keyboard::key::Code::KeyX,
968        KeyCode::KeyY => keyboard::key::Code::KeyY,
969        KeyCode::KeyZ => keyboard::key::Code::KeyZ,
970        KeyCode::Minus => keyboard::key::Code::Minus,
971        KeyCode::Period => keyboard::key::Code::Period,
972        KeyCode::Quote => keyboard::key::Code::Quote,
973        KeyCode::Semicolon => keyboard::key::Code::Semicolon,
974        KeyCode::Slash => keyboard::key::Code::Slash,
975        KeyCode::AltLeft => keyboard::key::Code::AltLeft,
976        KeyCode::AltRight => keyboard::key::Code::AltRight,
977        KeyCode::Backspace => keyboard::key::Code::Backspace,
978        KeyCode::CapsLock => keyboard::key::Code::CapsLock,
979        KeyCode::ContextMenu => keyboard::key::Code::ContextMenu,
980        KeyCode::ControlLeft => keyboard::key::Code::ControlLeft,
981        KeyCode::ControlRight => keyboard::key::Code::ControlRight,
982        KeyCode::Enter => keyboard::key::Code::Enter,
983        KeyCode::SuperLeft => keyboard::key::Code::SuperLeft,
984        KeyCode::SuperRight => keyboard::key::Code::SuperRight,
985        KeyCode::ShiftLeft => keyboard::key::Code::ShiftLeft,
986        KeyCode::ShiftRight => keyboard::key::Code::ShiftRight,
987        KeyCode::Space => keyboard::key::Code::Space,
988        KeyCode::Tab => keyboard::key::Code::Tab,
989        KeyCode::Convert => keyboard::key::Code::Convert,
990        KeyCode::KanaMode => keyboard::key::Code::KanaMode,
991        KeyCode::Lang1 => keyboard::key::Code::Lang1,
992        KeyCode::Lang2 => keyboard::key::Code::Lang2,
993        KeyCode::Lang3 => keyboard::key::Code::Lang3,
994        KeyCode::Lang4 => keyboard::key::Code::Lang4,
995        KeyCode::Lang5 => keyboard::key::Code::Lang5,
996        KeyCode::NonConvert => keyboard::key::Code::NonConvert,
997        KeyCode::Delete => keyboard::key::Code::Delete,
998        KeyCode::End => keyboard::key::Code::End,
999        KeyCode::Help => keyboard::key::Code::Help,
1000        KeyCode::Home => keyboard::key::Code::Home,
1001        KeyCode::Insert => keyboard::key::Code::Insert,
1002        KeyCode::PageDown => keyboard::key::Code::PageDown,
1003        KeyCode::PageUp => keyboard::key::Code::PageUp,
1004        KeyCode::ArrowDown => keyboard::key::Code::ArrowDown,
1005        KeyCode::ArrowLeft => keyboard::key::Code::ArrowLeft,
1006        KeyCode::ArrowRight => keyboard::key::Code::ArrowRight,
1007        KeyCode::ArrowUp => keyboard::key::Code::ArrowUp,
1008        KeyCode::NumLock => keyboard::key::Code::NumLock,
1009        KeyCode::Numpad0 => keyboard::key::Code::Numpad0,
1010        KeyCode::Numpad1 => keyboard::key::Code::Numpad1,
1011        KeyCode::Numpad2 => keyboard::key::Code::Numpad2,
1012        KeyCode::Numpad3 => keyboard::key::Code::Numpad3,
1013        KeyCode::Numpad4 => keyboard::key::Code::Numpad4,
1014        KeyCode::Numpad5 => keyboard::key::Code::Numpad5,
1015        KeyCode::Numpad6 => keyboard::key::Code::Numpad6,
1016        KeyCode::Numpad7 => keyboard::key::Code::Numpad7,
1017        KeyCode::Numpad8 => keyboard::key::Code::Numpad8,
1018        KeyCode::Numpad9 => keyboard::key::Code::Numpad9,
1019        KeyCode::NumpadAdd => keyboard::key::Code::NumpadAdd,
1020        KeyCode::NumpadBackspace => keyboard::key::Code::NumpadBackspace,
1021        KeyCode::NumpadClear => keyboard::key::Code::NumpadClear,
1022        KeyCode::NumpadClearEntry => keyboard::key::Code::NumpadClearEntry,
1023        KeyCode::NumpadComma => keyboard::key::Code::NumpadComma,
1024        KeyCode::NumpadDecimal => keyboard::key::Code::NumpadDecimal,
1025        KeyCode::NumpadDivide => keyboard::key::Code::NumpadDivide,
1026        KeyCode::NumpadEnter => keyboard::key::Code::NumpadEnter,
1027        KeyCode::NumpadEqual => keyboard::key::Code::NumpadEqual,
1028        KeyCode::NumpadHash => keyboard::key::Code::NumpadHash,
1029        KeyCode::NumpadMemoryAdd => keyboard::key::Code::NumpadMemoryAdd,
1030        KeyCode::NumpadMemoryClear => keyboard::key::Code::NumpadMemoryClear,
1031        KeyCode::NumpadMemoryRecall => keyboard::key::Code::NumpadMemoryRecall,
1032        KeyCode::NumpadMemoryStore => keyboard::key::Code::NumpadMemoryStore,
1033        KeyCode::NumpadMemorySubtract => {
1034            keyboard::key::Code::NumpadMemorySubtract
1035        }
1036        KeyCode::NumpadMultiply => keyboard::key::Code::NumpadMultiply,
1037        KeyCode::NumpadParenLeft => keyboard::key::Code::NumpadParenLeft,
1038        KeyCode::NumpadParenRight => keyboard::key::Code::NumpadParenRight,
1039        KeyCode::NumpadStar => keyboard::key::Code::NumpadStar,
1040        KeyCode::NumpadSubtract => keyboard::key::Code::NumpadSubtract,
1041        KeyCode::Escape => keyboard::key::Code::Escape,
1042        KeyCode::Fn => keyboard::key::Code::Fn,
1043        KeyCode::FnLock => keyboard::key::Code::FnLock,
1044        KeyCode::PrintScreen => keyboard::key::Code::PrintScreen,
1045        KeyCode::ScrollLock => keyboard::key::Code::ScrollLock,
1046        KeyCode::Pause => keyboard::key::Code::Pause,
1047        KeyCode::BrowserBack => keyboard::key::Code::BrowserBack,
1048        KeyCode::BrowserFavorites => keyboard::key::Code::BrowserFavorites,
1049        KeyCode::BrowserForward => keyboard::key::Code::BrowserForward,
1050        KeyCode::BrowserHome => keyboard::key::Code::BrowserHome,
1051        KeyCode::BrowserRefresh => keyboard::key::Code::BrowserRefresh,
1052        KeyCode::BrowserSearch => keyboard::key::Code::BrowserSearch,
1053        KeyCode::BrowserStop => keyboard::key::Code::BrowserStop,
1054        KeyCode::Eject => keyboard::key::Code::Eject,
1055        KeyCode::LaunchApp1 => keyboard::key::Code::LaunchApp1,
1056        KeyCode::LaunchApp2 => keyboard::key::Code::LaunchApp2,
1057        KeyCode::LaunchMail => keyboard::key::Code::LaunchMail,
1058        KeyCode::MediaPlayPause => keyboard::key::Code::MediaPlayPause,
1059        KeyCode::MediaSelect => keyboard::key::Code::MediaSelect,
1060        KeyCode::MediaStop => keyboard::key::Code::MediaStop,
1061        KeyCode::MediaTrackNext => keyboard::key::Code::MediaTrackNext,
1062        KeyCode::MediaTrackPrevious => keyboard::key::Code::MediaTrackPrevious,
1063        KeyCode::Power => keyboard::key::Code::Power,
1064        KeyCode::Sleep => keyboard::key::Code::Sleep,
1065        KeyCode::AudioVolumeDown => keyboard::key::Code::AudioVolumeDown,
1066        KeyCode::AudioVolumeMute => keyboard::key::Code::AudioVolumeMute,
1067        KeyCode::AudioVolumeUp => keyboard::key::Code::AudioVolumeUp,
1068        KeyCode::WakeUp => keyboard::key::Code::WakeUp,
1069        KeyCode::Meta => keyboard::key::Code::Meta,
1070        KeyCode::Hyper => keyboard::key::Code::Hyper,
1071        KeyCode::Turbo => keyboard::key::Code::Turbo,
1072        KeyCode::Abort => keyboard::key::Code::Abort,
1073        KeyCode::Resume => keyboard::key::Code::Resume,
1074        KeyCode::Suspend => keyboard::key::Code::Suspend,
1075        KeyCode::Again => keyboard::key::Code::Again,
1076        KeyCode::Copy => keyboard::key::Code::Copy,
1077        KeyCode::Cut => keyboard::key::Code::Cut,
1078        KeyCode::Find => keyboard::key::Code::Find,
1079        KeyCode::Open => keyboard::key::Code::Open,
1080        KeyCode::Paste => keyboard::key::Code::Paste,
1081        KeyCode::Props => keyboard::key::Code::Props,
1082        KeyCode::Select => keyboard::key::Code::Select,
1083        KeyCode::Undo => keyboard::key::Code::Undo,
1084        KeyCode::Hiragana => keyboard::key::Code::Hiragana,
1085        KeyCode::Katakana => keyboard::key::Code::Katakana,
1086        KeyCode::F1 => keyboard::key::Code::F1,
1087        KeyCode::F2 => keyboard::key::Code::F2,
1088        KeyCode::F3 => keyboard::key::Code::F3,
1089        KeyCode::F4 => keyboard::key::Code::F4,
1090        KeyCode::F5 => keyboard::key::Code::F5,
1091        KeyCode::F6 => keyboard::key::Code::F6,
1092        KeyCode::F7 => keyboard::key::Code::F7,
1093        KeyCode::F8 => keyboard::key::Code::F8,
1094        KeyCode::F9 => keyboard::key::Code::F9,
1095        KeyCode::F10 => keyboard::key::Code::F10,
1096        KeyCode::F11 => keyboard::key::Code::F11,
1097        KeyCode::F12 => keyboard::key::Code::F12,
1098        KeyCode::F13 => keyboard::key::Code::F13,
1099        KeyCode::F14 => keyboard::key::Code::F14,
1100        KeyCode::F15 => keyboard::key::Code::F15,
1101        KeyCode::F16 => keyboard::key::Code::F16,
1102        KeyCode::F17 => keyboard::key::Code::F17,
1103        KeyCode::F18 => keyboard::key::Code::F18,
1104        KeyCode::F19 => keyboard::key::Code::F19,
1105        KeyCode::F20 => keyboard::key::Code::F20,
1106        KeyCode::F21 => keyboard::key::Code::F21,
1107        KeyCode::F22 => keyboard::key::Code::F22,
1108        KeyCode::F23 => keyboard::key::Code::F23,
1109        KeyCode::F24 => keyboard::key::Code::F24,
1110        KeyCode::F25 => keyboard::key::Code::F25,
1111        KeyCode::F26 => keyboard::key::Code::F26,
1112        KeyCode::F27 => keyboard::key::Code::F27,
1113        KeyCode::F28 => keyboard::key::Code::F28,
1114        KeyCode::F29 => keyboard::key::Code::F29,
1115        KeyCode::F30 => keyboard::key::Code::F30,
1116        KeyCode::F31 => keyboard::key::Code::F31,
1117        KeyCode::F32 => keyboard::key::Code::F32,
1118        KeyCode::F33 => keyboard::key::Code::F33,
1119        KeyCode::F34 => keyboard::key::Code::F34,
1120        KeyCode::F35 => keyboard::key::Code::F35,
1121        _ => None?,
1122    })
1123}
1124
1125/// Converts a `NativeKeyCode` from [`winit`] to an [`iced`] native key code.
1126///
1127/// [`winit`]: https://github.com/rust-windowing/winit
1128/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12
1129pub fn native_key_code(
1130    native_key_code: winit::keyboard::NativeKeyCode,
1131) -> keyboard::key::NativeCode {
1132    use winit::keyboard::NativeKeyCode;
1133
1134    match native_key_code {
1135        NativeKeyCode::Unidentified => keyboard::key::NativeCode::Unidentified,
1136        NativeKeyCode::Android(code) => {
1137            keyboard::key::NativeCode::Android(code)
1138        }
1139        NativeKeyCode::MacOS(code) => keyboard::key::NativeCode::MacOS(code),
1140        NativeKeyCode::Windows(code) => {
1141            keyboard::key::NativeCode::Windows(code)
1142        }
1143        NativeKeyCode::Xkb(code) => keyboard::key::NativeCode::Xkb(code),
1144    }
1145}
1146
1147/// Converts some [`UserAttention`] into it's `winit` counterpart.
1148///
1149/// [`UserAttention`]: window::UserAttention
1150pub fn user_attention(
1151    user_attention: window::UserAttention,
1152) -> winit::window::UserAttentionType {
1153    match user_attention {
1154        window::UserAttention::Critical => {
1155            winit::window::UserAttentionType::Critical
1156        }
1157        window::UserAttention::Informational => {
1158            winit::window::UserAttentionType::Informational
1159        }
1160    }
1161}
1162
1163/// Converts some [`window::Icon`] into it's `winit` counterpart.
1164///
1165/// Returns `None` if there is an error during the conversion.
1166pub fn icon(icon: window::Icon) -> Option<winit::window::Icon> {
1167    let (pixels, size) = icon.into_raw();
1168
1169    winit::window::Icon::from_rgba(pixels, size.width, size.height).ok()
1170}
1171
1172// See: https://en.wikipedia.org/wiki/Private_Use_Areas
1173fn is_private_use(c: char) -> bool {
1174    ('\u{E000}'..='\u{F8FF}').contains(&c)
1175}
1176
1177#[cfg(feature = "a11y")]
1178pub(crate) fn a11y(
1179    event: iced_accessibility::accesskit::ActionRequest,
1180) -> Event {
1181    // XXX
1182    let id =
1183        iced_runtime::core::id::Id::from(u128::from(event.target.0) as u64);
1184    Event::A11y(id, event)
1185}