diff options
Diffstat (limited to 'winit/src')
-rw-r--r-- | winit/src/application.rs | 389 | ||||
-rw-r--r-- | winit/src/application/state.rs | 24 | ||||
-rw-r--r-- | winit/src/conversion.rs | 583 | ||||
-rw-r--r-- | winit/src/multi_window.rs | 580 | ||||
-rw-r--r-- | winit/src/multi_window/state.rs | 24 |
5 files changed, 823 insertions, 777 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs index 35a35872..bf48538d 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -115,7 +115,9 @@ where let mut debug = Debug::new(); debug.startup_started(); - let event_loop = EventLoopBuilder::with_user_event().build(); + let event_loop = EventLoopBuilder::with_user_event() + .build() + .expect("Create event loop"); let proxy = event_loop.create_proxy(); let runtime = { @@ -155,7 +157,7 @@ where { use winit::platform::web::WindowExtWebSys; - let canvas = window.canvas(); + let canvas = window.canvas().expect("Get window canvas"); let window = web_sys::window().unwrap(); let document = window.document().unwrap(); @@ -210,45 +212,28 @@ where let mut context = task::Context::from_waker(task::noop_waker_ref()); - platform::run(event_loop, move |event, _, control_flow| { - use winit::event_loop::ControlFlow; - - if let ControlFlow::ExitWithCode(_) = control_flow { + let _ = event_loop.run(move |event, event_loop| { + if event_loop.exiting() { return; } - let event = match event { - winit::event::Event::WindowEvent { - event: - winit::event::WindowEvent::ScaleFactorChanged { - new_inner_size, - .. - }, - window_id, - } => Some(winit::event::Event::WindowEvent { - event: winit::event::WindowEvent::Resized(*new_inner_size), - window_id, - }), - _ => event.to_static(), - }; - - if let Some(event) = event { - event_sender.start_send(event).expect("Send event"); + event_sender.start_send(event).expect("Send event"); - let poll = instance.as_mut().poll(&mut context); + let poll = instance.as_mut().poll(&mut context); - match poll { - task::Poll::Pending => { - if let Ok(Some(flow)) = control_receiver.try_next() { - *control_flow = flow; - } - } - task::Poll::Ready(_) => { - *control_flow = ControlFlow::Exit; + match poll { + task::Poll::Pending => { + if let Ok(Some(flow)) = control_receiver.try_next() { + event_loop.set_control_flow(flow); } - }; - } - }) + } + task::Poll::Ready(_) => { + event_loop.exit(); + } + }; + }); + + Ok(()) } async fn run_instance<A, E, C>( @@ -259,7 +244,7 @@ async fn run_instance<A, E, C>( mut proxy: winit::event_loop::EventLoopProxy<A::Message>, mut debug: Debug, mut event_receiver: mpsc::UnboundedReceiver< - winit::event::Event<'_, A::Message>, + winit::event::Event<A::Message>, >, mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>, init_command: Command<A::Message>, @@ -327,77 +312,56 @@ async fn run_instance<A, E, C>( while let Some(event) = event_receiver.next().await { match event { - event::Event::NewEvents(start_cause) => { - redraw_pending = matches!( - start_cause, - event::StartCause::Init - | event::StartCause::Poll - | event::StartCause::ResumeTimeReached { .. } - ); + event::Event::NewEvents( + event::StartCause::Init + | event::StartCause::ResumeTimeReached { .. }, + ) if !redraw_pending => { + window.request_redraw(); + redraw_pending = true; } - event::Event::MainEventsCleared => { - if !redraw_pending && events.is_empty() && messages.is_empty() { - continue; - } + event::Event::PlatformSpecific(event::PlatformSpecific::MacOS( + event::MacOS::ReceivedUrl(url), + )) => { + use crate::core::event; - debug.event_processing_started(); + events.push(Event::PlatformSpecific( + event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl( + url, + )), + )); + } + event::Event::UserEvent(message) => { + messages.push(message); + } + event::Event::WindowEvent { + event: event::WindowEvent::RedrawRequested { .. }, + .. + } => { + let physical_size = state.physical_size(); - let (interface_state, statuses) = user_interface.update( - &events, - state.cursor(), - &mut renderer, - &mut clipboard, - &mut messages, - ); + if physical_size.width == 0 || physical_size.height == 0 { + continue; + } - debug.event_processing_finished(); + let current_viewport_version = state.viewport_version(); - for (event, status) in - events.drain(..).zip(statuses.into_iter()) - { - runtime.broadcast(event, status); - } + if viewport_version != current_viewport_version { + let logical_size = state.logical_size(); - if !messages.is_empty() - || matches!( - interface_state, - user_interface::State::Outdated - ) - { - let mut cache = - ManuallyDrop::into_inner(user_interface).into_cache(); + debug.layout_started(); + user_interface = ManuallyDrop::new( + ManuallyDrop::into_inner(user_interface) + .relayout(logical_size, &mut renderer), + ); + debug.layout_finished(); - // Update application - update( - &mut application, - &mut compositor, + compositor.configure_surface( &mut surface, - &mut cache, - &state, - &mut renderer, - &mut runtime, - &mut clipboard, - &mut should_exit, - &mut proxy, - &mut debug, - &mut messages, - &window, + physical_size.width, + physical_size.height, ); - // Update window - state.synchronize(&application, &window); - - user_interface = ManuallyDrop::new(build_user_interface( - &application, - cache, - &mut renderer, - state.logical_size(), - &mut debug, - )); - - if should_exit { - break; - } + viewport_version = current_viewport_version; } // TODO: Avoid redrawing all the time by forcing widgets to @@ -418,6 +382,24 @@ async fn run_instance<A, E, C>( &mut messages, ); + let _ = control_sender.start_send(match interface_state { + user_interface::State::Updated { + redraw_request: Some(redraw_request), + } => match redraw_request { + window::RedrawRequest::NextFrame => { + window.request_redraw(); + + ControlFlow::Wait + } + window::RedrawRequest::At(at) => { + ControlFlow::WaitUntil(at) + } + }, + _ => ControlFlow::Wait, + }); + + runtime.broadcast(redraw_event, core::event::Status::Ignored); + debug.draw_started(); let new_mouse_interaction = user_interface.draw( &mut renderer, @@ -427,6 +409,7 @@ async fn run_instance<A, E, C>( }, state.cursor(), ); + redraw_pending = false; debug.draw_finished(); if new_mouse_interaction != mouse_interaction { @@ -437,85 +420,7 @@ async fn run_instance<A, E, C>( mouse_interaction = new_mouse_interaction; } - window.request_redraw(); - runtime.broadcast(redraw_event, core::event::Status::Ignored); - - let _ = control_sender.start_send(match interface_state { - user_interface::State::Updated { - redraw_request: Some(redraw_request), - } => match redraw_request { - window::RedrawRequest::NextFrame => ControlFlow::Poll, - window::RedrawRequest::At(at) => { - ControlFlow::WaitUntil(at) - } - }, - _ => ControlFlow::Wait, - }); - - redraw_pending = false; - } - event::Event::PlatformSpecific(event::PlatformSpecific::MacOS( - event::MacOS::ReceivedUrl(url), - )) => { - use crate::core::event; - - events.push(Event::PlatformSpecific( - event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl( - url, - )), - )); - } - event::Event::UserEvent(message) => { - messages.push(message); - } - event::Event::RedrawRequested(_) => { - let physical_size = state.physical_size(); - - if physical_size.width == 0 || physical_size.height == 0 { - continue; - } - debug.render_started(); - let current_viewport_version = state.viewport_version(); - - if viewport_version != current_viewport_version { - let logical_size = state.logical_size(); - - debug.layout_started(); - user_interface = ManuallyDrop::new( - ManuallyDrop::into_inner(user_interface) - .relayout(logical_size, &mut renderer), - ); - debug.layout_finished(); - - debug.draw_started(); - let new_mouse_interaction = user_interface.draw( - &mut renderer, - state.theme(), - &renderer::Style { - text_color: state.text_color(), - }, - state.cursor(), - ); - - if new_mouse_interaction != mouse_interaction { - window.set_cursor_icon(conversion::mouse_interaction( - new_mouse_interaction, - )); - - mouse_interaction = new_mouse_interaction; - } - debug.draw_finished(); - - compositor.configure_surface( - &mut surface, - physical_size.width, - physical_size.height, - ); - - viewport_version = current_viewport_version; - } - match compositor.present( &mut renderer, &mut surface, @@ -557,13 +462,80 @@ async fn run_instance<A, E, C>( if let Some(event) = conversion::window_event( window::Id::MAIN, - &window_event, + window_event, state.scale_factor(), state.modifiers(), ) { events.push(event); } } + event::Event::AboutToWait => { + if events.is_empty() && messages.is_empty() { + continue; + } + + debug.event_processing_started(); + + let (interface_state, statuses) = user_interface.update( + &events, + state.cursor(), + &mut renderer, + &mut clipboard, + &mut messages, + ); + + debug.event_processing_finished(); + + for (event, status) in + events.drain(..).zip(statuses.into_iter()) + { + runtime.broadcast(event, status); + } + + if !messages.is_empty() + || matches!( + interface_state, + user_interface::State::Outdated + ) + { + let mut cache = + ManuallyDrop::into_inner(user_interface).into_cache(); + + // Update application + update( + &mut application, + &mut compositor, + &mut surface, + &mut cache, + &mut state, + &mut renderer, + &mut runtime, + &mut clipboard, + &mut should_exit, + &mut proxy, + &mut debug, + &mut messages, + &window, + ); + + user_interface = ManuallyDrop::new(build_user_interface( + &application, + cache, + &mut renderer, + state.logical_size(), + &mut debug, + )); + + if should_exit { + break; + } + } + + if !redraw_pending { + window.request_redraw(); + redraw_pending = true; + } + } _ => {} } } @@ -575,8 +547,8 @@ async fn run_instance<A, E, C>( /// Returns true if the provided event should cause an [`Application`] to /// exit. pub fn requests_exit( - event: &winit::event::WindowEvent<'_>, - _modifiers: winit::event::ModifiersState, + event: &winit::event::WindowEvent, + _modifiers: winit::keyboard::ModifiersState, ) -> bool { use winit::event::WindowEvent; @@ -584,14 +556,14 @@ pub fn requests_exit( WindowEvent::CloseRequested => true, #[cfg(target_os = "macos")] WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(winit::event::VirtualKeyCode::Q), + event: + winit::event::KeyEvent { + logical_key: winit::keyboard::Key::Character(c), state: winit::event::ElementState::Pressed, .. }, .. - } if _modifiers.logo() => true, + } if c == "q" && _modifiers.super_key() => true, _ => false, } } @@ -626,7 +598,7 @@ pub fn update<A: Application, C, E: Executor>( compositor: &mut C, surface: &mut C::Surface, cache: &mut user_interface::Cache, - state: &State<A>, + state: &mut State<A>, renderer: &mut A::Renderer, runtime: &mut Runtime<E, Proxy<A::Message>, A::Message>, clipboard: &mut Clipboard, @@ -663,6 +635,8 @@ pub fn update<A: Application, C, E: Executor>( ); } + state.synchronize(application, window); + let subscription = application.subscription(); runtime.track(subscription.into_recipes()); } @@ -726,10 +700,11 @@ pub fn run_command<A, C, E>( ); } window::Action::Resize(_id, size) => { - window.set_inner_size(winit::dpi::LogicalSize { - width: size.width, - height: size.height, - }); + let _ = + window.request_inner_size(winit::dpi::LogicalSize { + width: size.width, + height: size.height, + }); } window::Action::FetchSize(_id, callback) => { let size = @@ -888,43 +863,3 @@ pub fn run_command<A, C, E>( } } } - -#[cfg(not(target_arch = "wasm32"))] -mod platform { - pub fn run<T, F>( - mut event_loop: winit::event_loop::EventLoop<T>, - event_handler: F, - ) -> Result<(), super::Error> - where - F: 'static - + FnMut( - winit::event::Event<'_, T>, - &winit::event_loop::EventLoopWindowTarget<T>, - &mut winit::event_loop::ControlFlow, - ), - { - use winit::platform::run_return::EventLoopExtRunReturn; - - let _ = event_loop.run_return(event_handler); - - Ok(()) - } -} - -#[cfg(target_arch = "wasm32")] -mod platform { - pub fn run<T, F>( - event_loop: winit::event_loop::EventLoop<T>, - event_handler: F, - ) -> ! - where - F: 'static - + FnMut( - winit::event::Event<'_, T>, - &winit::event_loop::EventLoopWindowTarget<T>, - &mut winit::event_loop::ControlFlow, - ), - { - event_loop.run(event_handler) - } -} diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index e655529a..8c9b20e0 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -22,7 +22,7 @@ where viewport: Viewport, viewport_version: usize, cursor_position: Option<winit::dpi::PhysicalPosition<f64>>, - modifiers: winit::event::ModifiersState, + modifiers: winit::keyboard::ModifiersState, theme: <A::Renderer as core::Renderer>::Theme, appearance: application::Appearance, application: PhantomData<A>, @@ -54,7 +54,7 @@ where viewport, viewport_version: 0, cursor_position: None, - modifiers: winit::event::ModifiersState::default(), + modifiers: winit::keyboard::ModifiersState::default(), theme, appearance, application: PhantomData, @@ -102,7 +102,7 @@ where } /// Returns the current keyboard modifiers of the [`State`]. - pub fn modifiers(&self) -> winit::event::ModifiersState { + pub fn modifiers(&self) -> winit::keyboard::ModifiersState { self.modifiers } @@ -126,7 +126,7 @@ where pub fn update( &mut self, window: &Window, - event: &WindowEvent<'_>, + event: &WindowEvent, _debug: &mut Debug, ) { match event { @@ -142,10 +142,9 @@ where } WindowEvent::ScaleFactorChanged { scale_factor: new_scale_factor, - new_inner_size, + .. } => { - let size = - Size::new(new_inner_size.width, new_inner_size.height); + let size = self.viewport.physical_size(); self.viewport = Viewport::with_physical_size( size, @@ -164,13 +163,16 @@ where self.cursor_position = None; } WindowEvent::ModifiersChanged(new_modifiers) => { - self.modifiers = *new_modifiers; + self.modifiers = new_modifiers.state(); } #[cfg(feature = "debug")] WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(winit::event::VirtualKeyCode::F12), + event: + winit::event::KeyEvent { + logical_key: + winit::keyboard::Key::Named( + winit::keyboard::NamedKey::F12, + ), state: winit::event::ElementState::Pressed, .. }, diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 7e51a2d4..90a5d27f 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -128,9 +128,9 @@ pub fn window_settings( /// Converts a winit window event into an iced event. pub fn window_event( id: window::Id, - event: &winit::event::WindowEvent<'_>, + event: winit::event::WindowEvent, scale_factor: f64, - modifiers: winit::event::ModifiersState, + modifiers: winit::keyboard::ModifiersState, ) -> Option<Event> { use winit::event::WindowEvent; @@ -146,17 +146,6 @@ pub fn window_event( }, )) } - WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { - let logical_size = new_inner_size.to_logical(scale_factor); - - Some(Event::Window( - id, - window::Event::Resized { - width: logical_size.width, - height: logical_size.height, - }, - )) - } WindowEvent::CloseRequested => { Some(Event::Window(id, window::Event::CloseRequested)) } @@ -174,7 +163,7 @@ pub fn window_event( Some(Event::Mouse(mouse::Event::CursorLeft)) } WindowEvent::MouseInput { button, state, .. } => { - let button = mouse_button(*button); + let button = mouse_button(button); Some(Event::Mouse(match state { winit::event::ElementState::Pressed => { @@ -189,8 +178,8 @@ pub fn window_event( winit::event::MouseScrollDelta::LineDelta(delta_x, delta_y) => { Some(Event::Mouse(mouse::Event::WheelScrolled { delta: mouse::ScrollDelta::Lines { - x: *delta_x, - y: *delta_y, + x: delta_x, + y: delta_y, }, })) } @@ -203,42 +192,59 @@ pub fn window_event( })) } }, - WindowEvent::ReceivedCharacter(c) if !is_private_use_character(*c) => { - Some(Event::Keyboard(keyboard::Event::CharacterReceived(*c))) - } WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(virtual_keycode), + event: + winit::event::KeyEvent { + logical_key, state, + text, + location, .. }, .. } => Some(Event::Keyboard({ - let key_code = key_code(*virtual_keycode); + let key = key(logical_key); let modifiers = self::modifiers(modifiers); + let location = match location { + winit::keyboard::KeyLocation::Standard => { + keyboard::Location::Standard + } + winit::keyboard::KeyLocation::Left => keyboard::Location::Left, + winit::keyboard::KeyLocation::Right => { + keyboard::Location::Right + } + winit::keyboard::KeyLocation::Numpad => { + keyboard::Location::Numpad + } + }; + match state { winit::event::ElementState::Pressed => { keyboard::Event::KeyPressed { - key_code, + key, modifiers, + location, + text, } } winit::event::ElementState::Released => { keyboard::Event::KeyReleased { - key_code, + key, modifiers, + location, } } } })), - WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard( - keyboard::Event::ModifiersChanged(self::modifiers(*new_modifiers)), - )), + WindowEvent::ModifiersChanged(new_modifiers) => { + Some(Event::Keyboard(keyboard::Event::ModifiersChanged( + self::modifiers(new_modifiers.state()), + ))) + } WindowEvent::Focused(focused) => Some(Event::Window( id, - if *focused { + if focused { window::Event::Focused } else { window::Event::Unfocused @@ -254,7 +260,7 @@ pub fn window_event( Some(Event::Window(id, window::Event::FilesHoveredLeft)) } WindowEvent::Touch(touch) => { - Some(Event::Touch(touch_event(*touch, scale_factor))) + Some(Event::Touch(touch_event(touch, scale_factor))) } WindowEvent::Moved(position) => { let winit::dpi::LogicalPosition { x, y } = @@ -365,7 +371,7 @@ pub fn mouse_interaction( match interaction { Interaction::Idle => winit::window::CursorIcon::Default, - Interaction::Pointer => winit::window::CursorIcon::Hand, + Interaction::Pointer => winit::window::CursorIcon::Pointer, Interaction::Working => winit::window::CursorIcon::Progress, Interaction::Grab => winit::window::CursorIcon::Grab, Interaction::Grabbing => winit::window::CursorIcon::Grabbing, @@ -388,6 +394,8 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { winit::event::MouseButton::Left => mouse::Button::Left, winit::event::MouseButton::Right => mouse::Button::Right, winit::event::MouseButton::Middle => mouse::Button::Middle, + winit::event::MouseButton::Back => mouse::Button::Back, + winit::event::MouseButton::Forward => mouse::Button::Forward, winit::event::MouseButton::Other(other) => mouse::Button::Other(other), } } @@ -398,14 +406,14 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 pub fn modifiers( - modifiers: winit::event::ModifiersState, + modifiers: winit::keyboard::ModifiersState, ) -> keyboard::Modifiers { let mut result = keyboard::Modifiers::empty(); - result.set(keyboard::Modifiers::SHIFT, modifiers.shift()); - result.set(keyboard::Modifiers::CTRL, modifiers.ctrl()); - result.set(keyboard::Modifiers::ALT, modifiers.alt()); - result.set(keyboard::Modifiers::LOGO, modifiers.logo()); + result.set(keyboard::Modifiers::SHIFT, modifiers.shift_key()); + result.set(keyboard::Modifiers::CTRL, modifiers.control_key()); + result.set(keyboard::Modifiers::ALT, modifiers.alt_key()); + result.set(keyboard::Modifiers::LOGO, modifiers.super_key()); result } @@ -455,179 +463,328 @@ pub fn touch_event( /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 -pub fn key_code( - virtual_keycode: winit::event::VirtualKeyCode, -) -> keyboard::KeyCode { - use keyboard::KeyCode; - - match virtual_keycode { - winit::event::VirtualKeyCode::Key1 => KeyCode::Key1, - winit::event::VirtualKeyCode::Key2 => KeyCode::Key2, - winit::event::VirtualKeyCode::Key3 => KeyCode::Key3, - winit::event::VirtualKeyCode::Key4 => KeyCode::Key4, - winit::event::VirtualKeyCode::Key5 => KeyCode::Key5, - winit::event::VirtualKeyCode::Key6 => KeyCode::Key6, - winit::event::VirtualKeyCode::Key7 => KeyCode::Key7, - winit::event::VirtualKeyCode::Key8 => KeyCode::Key8, - winit::event::VirtualKeyCode::Key9 => KeyCode::Key9, - winit::event::VirtualKeyCode::Key0 => KeyCode::Key0, - winit::event::VirtualKeyCode::A => KeyCode::A, - winit::event::VirtualKeyCode::B => KeyCode::B, - winit::event::VirtualKeyCode::C => KeyCode::C, - winit::event::VirtualKeyCode::D => KeyCode::D, - winit::event::VirtualKeyCode::E => KeyCode::E, - winit::event::VirtualKeyCode::F => KeyCode::F, - winit::event::VirtualKeyCode::G => KeyCode::G, - winit::event::VirtualKeyCode::H => KeyCode::H, - winit::event::VirtualKeyCode::I => KeyCode::I, - winit::event::VirtualKeyCode::J => KeyCode::J, - winit::event::VirtualKeyCode::K => KeyCode::K, - winit::event::VirtualKeyCode::L => KeyCode::L, - winit::event::VirtualKeyCode::M => KeyCode::M, - winit::event::VirtualKeyCode::N => KeyCode::N, - winit::event::VirtualKeyCode::O => KeyCode::O, - winit::event::VirtualKeyCode::P => KeyCode::P, - winit::event::VirtualKeyCode::Q => KeyCode::Q, - winit::event::VirtualKeyCode::R => KeyCode::R, - winit::event::VirtualKeyCode::S => KeyCode::S, - winit::event::VirtualKeyCode::T => KeyCode::T, - winit::event::VirtualKeyCode::U => KeyCode::U, - winit::event::VirtualKeyCode::V => KeyCode::V, - winit::event::VirtualKeyCode::W => KeyCode::W, - winit::event::VirtualKeyCode::X => KeyCode::X, - winit::event::VirtualKeyCode::Y => KeyCode::Y, - winit::event::VirtualKeyCode::Z => KeyCode::Z, - winit::event::VirtualKeyCode::Escape => KeyCode::Escape, - winit::event::VirtualKeyCode::F1 => KeyCode::F1, - winit::event::VirtualKeyCode::F2 => KeyCode::F2, - winit::event::VirtualKeyCode::F3 => KeyCode::F3, - winit::event::VirtualKeyCode::F4 => KeyCode::F4, - winit::event::VirtualKeyCode::F5 => KeyCode::F5, - winit::event::VirtualKeyCode::F6 => KeyCode::F6, - winit::event::VirtualKeyCode::F7 => KeyCode::F7, - winit::event::VirtualKeyCode::F8 => KeyCode::F8, - winit::event::VirtualKeyCode::F9 => KeyCode::F9, - winit::event::VirtualKeyCode::F10 => KeyCode::F10, - winit::event::VirtualKeyCode::F11 => KeyCode::F11, - winit::event::VirtualKeyCode::F12 => KeyCode::F12, - winit::event::VirtualKeyCode::F13 => KeyCode::F13, - winit::event::VirtualKeyCode::F14 => KeyCode::F14, - winit::event::VirtualKeyCode::F15 => KeyCode::F15, - winit::event::VirtualKeyCode::F16 => KeyCode::F16, - winit::event::VirtualKeyCode::F17 => KeyCode::F17, - winit::event::VirtualKeyCode::F18 => KeyCode::F18, - winit::event::VirtualKeyCode::F19 => KeyCode::F19, - winit::event::VirtualKeyCode::F20 => KeyCode::F20, - winit::event::VirtualKeyCode::F21 => KeyCode::F21, - winit::event::VirtualKeyCode::F22 => KeyCode::F22, - winit::event::VirtualKeyCode::F23 => KeyCode::F23, - winit::event::VirtualKeyCode::F24 => KeyCode::F24, - winit::event::VirtualKeyCode::Snapshot => KeyCode::Snapshot, - winit::event::VirtualKeyCode::Scroll => KeyCode::Scroll, - winit::event::VirtualKeyCode::Pause => KeyCode::Pause, - winit::event::VirtualKeyCode::Insert => KeyCode::Insert, - winit::event::VirtualKeyCode::Home => KeyCode::Home, - winit::event::VirtualKeyCode::Delete => KeyCode::Delete, - winit::event::VirtualKeyCode::End => KeyCode::End, - winit::event::VirtualKeyCode::PageDown => KeyCode::PageDown, - winit::event::VirtualKeyCode::PageUp => KeyCode::PageUp, - winit::event::VirtualKeyCode::Left => KeyCode::Left, - winit::event::VirtualKeyCode::Up => KeyCode::Up, - winit::event::VirtualKeyCode::Right => KeyCode::Right, - winit::event::VirtualKeyCode::Down => KeyCode::Down, - winit::event::VirtualKeyCode::Back => KeyCode::Backspace, - winit::event::VirtualKeyCode::Return => KeyCode::Enter, - winit::event::VirtualKeyCode::Space => KeyCode::Space, - winit::event::VirtualKeyCode::Compose => KeyCode::Compose, - winit::event::VirtualKeyCode::Caret => KeyCode::Caret, - winit::event::VirtualKeyCode::Numlock => KeyCode::Numlock, - winit::event::VirtualKeyCode::Numpad0 => KeyCode::Numpad0, - winit::event::VirtualKeyCode::Numpad1 => KeyCode::Numpad1, - winit::event::VirtualKeyCode::Numpad2 => KeyCode::Numpad2, - winit::event::VirtualKeyCode::Numpad3 => KeyCode::Numpad3, - winit::event::VirtualKeyCode::Numpad4 => KeyCode::Numpad4, - winit::event::VirtualKeyCode::Numpad5 => KeyCode::Numpad5, - winit::event::VirtualKeyCode::Numpad6 => KeyCode::Numpad6, - winit::event::VirtualKeyCode::Numpad7 => KeyCode::Numpad7, - winit::event::VirtualKeyCode::Numpad8 => KeyCode::Numpad8, - winit::event::VirtualKeyCode::Numpad9 => KeyCode::Numpad9, - winit::event::VirtualKeyCode::AbntC1 => KeyCode::AbntC1, - winit::event::VirtualKeyCode::AbntC2 => KeyCode::AbntC2, - winit::event::VirtualKeyCode::NumpadAdd => KeyCode::NumpadAdd, - winit::event::VirtualKeyCode::Plus => KeyCode::Plus, - winit::event::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe, - winit::event::VirtualKeyCode::Apps => KeyCode::Apps, - winit::event::VirtualKeyCode::At => KeyCode::At, - winit::event::VirtualKeyCode::Ax => KeyCode::Ax, - winit::event::VirtualKeyCode::Backslash => KeyCode::Backslash, - winit::event::VirtualKeyCode::Calculator => KeyCode::Calculator, - winit::event::VirtualKeyCode::Capital => KeyCode::Capital, - winit::event::VirtualKeyCode::Colon => KeyCode::Colon, - winit::event::VirtualKeyCode::Comma => KeyCode::Comma, - winit::event::VirtualKeyCode::Convert => KeyCode::Convert, - winit::event::VirtualKeyCode::NumpadDecimal => KeyCode::NumpadDecimal, - winit::event::VirtualKeyCode::NumpadDivide => KeyCode::NumpadDivide, - winit::event::VirtualKeyCode::Equals => KeyCode::Equals, - winit::event::VirtualKeyCode::Grave => KeyCode::Grave, - winit::event::VirtualKeyCode::Kana => KeyCode::Kana, - winit::event::VirtualKeyCode::Kanji => KeyCode::Kanji, - winit::event::VirtualKeyCode::LAlt => KeyCode::LAlt, - winit::event::VirtualKeyCode::LBracket => KeyCode::LBracket, - winit::event::VirtualKeyCode::LControl => KeyCode::LControl, - winit::event::VirtualKeyCode::LShift => KeyCode::LShift, - winit::event::VirtualKeyCode::LWin => KeyCode::LWin, - winit::event::VirtualKeyCode::Mail => KeyCode::Mail, - winit::event::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect, - winit::event::VirtualKeyCode::MediaStop => KeyCode::MediaStop, - winit::event::VirtualKeyCode::Minus => KeyCode::Minus, - winit::event::VirtualKeyCode::NumpadMultiply => KeyCode::NumpadMultiply, - winit::event::VirtualKeyCode::Mute => KeyCode::Mute, - winit::event::VirtualKeyCode::MyComputer => KeyCode::MyComputer, - winit::event::VirtualKeyCode::NavigateForward => { - KeyCode::NavigateForward - } - winit::event::VirtualKeyCode::NavigateBackward => { - KeyCode::NavigateBackward +pub fn key(key: winit::keyboard::Key) -> keyboard::Key { + use keyboard::key::Named; + use winit::keyboard::NamedKey; + + match key { + winit::keyboard::Key::Character(c) => keyboard::Key::Character(c), + winit::keyboard::Key::Named(named_key) => { + keyboard::Key::Named(match named_key { + NamedKey::Alt => Named::Alt, + NamedKey::AltGraph => Named::AltGraph, + NamedKey::CapsLock => Named::CapsLock, + NamedKey::Control => Named::Control, + NamedKey::Fn => Named::Fn, + NamedKey::FnLock => Named::FnLock, + NamedKey::NumLock => Named::NumLock, + NamedKey::ScrollLock => Named::ScrollLock, + NamedKey::Shift => Named::Shift, + NamedKey::Symbol => Named::Symbol, + NamedKey::SymbolLock => Named::SymbolLock, + NamedKey::Meta => Named::Meta, + NamedKey::Hyper => Named::Hyper, + NamedKey::Super => Named::Super, + NamedKey::Enter => Named::Enter, + NamedKey::Tab => Named::Tab, + NamedKey::Space => Named::Space, + NamedKey::ArrowDown => Named::ArrowDown, + NamedKey::ArrowLeft => Named::ArrowLeft, + NamedKey::ArrowRight => Named::ArrowRight, + NamedKey::ArrowUp => Named::ArrowUp, + NamedKey::End => Named::End, + NamedKey::Home => Named::Home, + NamedKey::PageDown => Named::PageDown, + NamedKey::PageUp => Named::PageUp, + NamedKey::Backspace => Named::Backspace, + NamedKey::Clear => Named::Clear, + NamedKey::Copy => Named::Copy, + NamedKey::CrSel => Named::CrSel, + NamedKey::Cut => Named::Cut, + NamedKey::Delete => Named::Delete, + NamedKey::EraseEof => Named::EraseEof, + NamedKey::ExSel => Named::ExSel, + NamedKey::Insert => Named::Insert, + NamedKey::Paste => Named::Paste, + NamedKey::Redo => Named::Redo, + NamedKey::Undo => Named::Undo, + NamedKey::Accept => Named::Accept, + NamedKey::Again => Named::Again, + NamedKey::Attn => Named::Attn, + NamedKey::Cancel => Named::Cancel, + NamedKey::ContextMenu => Named::ContextMenu, + NamedKey::Escape => Named::Escape, + NamedKey::Execute => Named::Execute, + NamedKey::Find => Named::Find, + NamedKey::Help => Named::Help, + NamedKey::Pause => Named::Pause, + NamedKey::Play => Named::Play, + NamedKey::Props => Named::Props, + NamedKey::Select => Named::Select, + NamedKey::ZoomIn => Named::ZoomIn, + NamedKey::ZoomOut => Named::ZoomOut, + NamedKey::BrightnessDown => Named::BrightnessDown, + NamedKey::BrightnessUp => Named::BrightnessUp, + NamedKey::Eject => Named::Eject, + NamedKey::LogOff => Named::LogOff, + NamedKey::Power => Named::Power, + NamedKey::PowerOff => Named::PowerOff, + NamedKey::PrintScreen => Named::PrintScreen, + NamedKey::Hibernate => Named::Hibernate, + NamedKey::Standby => Named::Standby, + NamedKey::WakeUp => Named::WakeUp, + NamedKey::AllCandidates => Named::AllCandidates, + NamedKey::Alphanumeric => Named::Alphanumeric, + NamedKey::CodeInput => Named::CodeInput, + NamedKey::Compose => Named::Compose, + NamedKey::Convert => Named::Convert, + NamedKey::FinalMode => Named::FinalMode, + NamedKey::GroupFirst => Named::GroupFirst, + NamedKey::GroupLast => Named::GroupLast, + NamedKey::GroupNext => Named::GroupNext, + NamedKey::GroupPrevious => Named::GroupPrevious, + NamedKey::ModeChange => Named::ModeChange, + NamedKey::NextCandidate => Named::NextCandidate, + NamedKey::NonConvert => Named::NonConvert, + NamedKey::PreviousCandidate => Named::PreviousCandidate, + NamedKey::Process => Named::Process, + NamedKey::SingleCandidate => Named::SingleCandidate, + NamedKey::HangulMode => Named::HangulMode, + NamedKey::HanjaMode => Named::HanjaMode, + NamedKey::JunjaMode => Named::JunjaMode, + NamedKey::Eisu => Named::Eisu, + NamedKey::Hankaku => Named::Hankaku, + NamedKey::Hiragana => Named::Hiragana, + NamedKey::HiraganaKatakana => Named::HiraganaKatakana, + NamedKey::KanaMode => Named::KanaMode, + NamedKey::KanjiMode => Named::KanjiMode, + NamedKey::Katakana => Named::Katakana, + NamedKey::Romaji => Named::Romaji, + NamedKey::Zenkaku => Named::Zenkaku, + NamedKey::ZenkakuHankaku => Named::ZenkakuHankaku, + NamedKey::Soft1 => Named::Soft1, + NamedKey::Soft2 => Named::Soft2, + NamedKey::Soft3 => Named::Soft3, + NamedKey::Soft4 => Named::Soft4, + NamedKey::ChannelDown => Named::ChannelDown, + NamedKey::ChannelUp => Named::ChannelUp, + NamedKey::Close => Named::Close, + NamedKey::MailForward => Named::MailForward, + NamedKey::MailReply => Named::MailReply, + NamedKey::MailSend => Named::MailSend, + NamedKey::MediaClose => Named::MediaClose, + NamedKey::MediaFastForward => Named::MediaFastForward, + NamedKey::MediaPause => Named::MediaPause, + NamedKey::MediaPlay => Named::MediaPlay, + NamedKey::MediaPlayPause => Named::MediaPlayPause, + NamedKey::MediaRecord => Named::MediaRecord, + NamedKey::MediaRewind => Named::MediaRewind, + NamedKey::MediaStop => Named::MediaStop, + NamedKey::MediaTrackNext => Named::MediaTrackNext, + NamedKey::MediaTrackPrevious => Named::MediaTrackPrevious, + NamedKey::New => Named::New, + NamedKey::Open => Named::Open, + NamedKey::Print => Named::Print, + NamedKey::Save => Named::Save, + NamedKey::SpellCheck => Named::SpellCheck, + NamedKey::Key11 => Named::Key11, + NamedKey::Key12 => Named::Key12, + NamedKey::AudioBalanceLeft => Named::AudioBalanceLeft, + NamedKey::AudioBalanceRight => Named::AudioBalanceRight, + NamedKey::AudioBassBoostDown => Named::AudioBassBoostDown, + NamedKey::AudioBassBoostToggle => Named::AudioBassBoostToggle, + NamedKey::AudioBassBoostUp => Named::AudioBassBoostUp, + NamedKey::AudioFaderFront => Named::AudioFaderFront, + NamedKey::AudioFaderRear => Named::AudioFaderRear, + NamedKey::AudioSurroundModeNext => Named::AudioSurroundModeNext, + NamedKey::AudioTrebleDown => Named::AudioTrebleDown, + NamedKey::AudioTrebleUp => Named::AudioTrebleUp, + NamedKey::AudioVolumeDown => Named::AudioVolumeDown, + NamedKey::AudioVolumeUp => Named::AudioVolumeUp, + NamedKey::AudioVolumeMute => Named::AudioVolumeMute, + NamedKey::MicrophoneToggle => Named::MicrophoneToggle, + NamedKey::MicrophoneVolumeDown => Named::MicrophoneVolumeDown, + NamedKey::MicrophoneVolumeUp => Named::MicrophoneVolumeUp, + NamedKey::MicrophoneVolumeMute => Named::MicrophoneVolumeMute, + NamedKey::SpeechCorrectionList => Named::SpeechCorrectionList, + NamedKey::SpeechInputToggle => Named::SpeechInputToggle, + NamedKey::LaunchApplication1 => Named::LaunchApplication1, + NamedKey::LaunchApplication2 => Named::LaunchApplication2, + NamedKey::LaunchCalendar => Named::LaunchCalendar, + NamedKey::LaunchContacts => Named::LaunchContacts, + NamedKey::LaunchMail => Named::LaunchMail, + NamedKey::LaunchMediaPlayer => Named::LaunchMediaPlayer, + NamedKey::LaunchMusicPlayer => Named::LaunchMusicPlayer, + NamedKey::LaunchPhone => Named::LaunchPhone, + NamedKey::LaunchScreenSaver => Named::LaunchScreenSaver, + NamedKey::LaunchSpreadsheet => Named::LaunchSpreadsheet, + NamedKey::LaunchWebBrowser => Named::LaunchWebBrowser, + NamedKey::LaunchWebCam => Named::LaunchWebCam, + NamedKey::LaunchWordProcessor => Named::LaunchWordProcessor, + NamedKey::BrowserBack => Named::BrowserBack, + NamedKey::BrowserFavorites => Named::BrowserFavorites, + NamedKey::BrowserForward => Named::BrowserForward, + NamedKey::BrowserHome => Named::BrowserHome, + NamedKey::BrowserRefresh => Named::BrowserRefresh, + NamedKey::BrowserSearch => Named::BrowserSearch, + NamedKey::BrowserStop => Named::BrowserStop, + NamedKey::AppSwitch => Named::AppSwitch, + NamedKey::Call => Named::Call, + NamedKey::Camera => Named::Camera, + NamedKey::CameraFocus => Named::CameraFocus, + NamedKey::EndCall => Named::EndCall, + NamedKey::GoBack => Named::GoBack, + NamedKey::GoHome => Named::GoHome, + NamedKey::HeadsetHook => Named::HeadsetHook, + NamedKey::LastNumberRedial => Named::LastNumberRedial, + NamedKey::Notification => Named::Notification, + NamedKey::MannerMode => Named::MannerMode, + NamedKey::VoiceDial => Named::VoiceDial, + NamedKey::TV => Named::TV, + NamedKey::TV3DMode => Named::TV3DMode, + NamedKey::TVAntennaCable => Named::TVAntennaCable, + NamedKey::TVAudioDescription => Named::TVAudioDescription, + NamedKey::TVAudioDescriptionMixDown => { + Named::TVAudioDescriptionMixDown + } + NamedKey::TVAudioDescriptionMixUp => { + Named::TVAudioDescriptionMixUp + } + NamedKey::TVContentsMenu => Named::TVContentsMenu, + NamedKey::TVDataService => Named::TVDataService, + NamedKey::TVInput => Named::TVInput, + NamedKey::TVInputComponent1 => Named::TVInputComponent1, + NamedKey::TVInputComponent2 => Named::TVInputComponent2, + NamedKey::TVInputComposite1 => Named::TVInputComposite1, + NamedKey::TVInputComposite2 => Named::TVInputComposite2, + NamedKey::TVInputHDMI1 => Named::TVInputHDMI1, + NamedKey::TVInputHDMI2 => Named::TVInputHDMI2, + NamedKey::TVInputHDMI3 => Named::TVInputHDMI3, + NamedKey::TVInputHDMI4 => Named::TVInputHDMI4, + NamedKey::TVInputVGA1 => Named::TVInputVGA1, + NamedKey::TVMediaContext => Named::TVMediaContext, + NamedKey::TVNetwork => Named::TVNetwork, + NamedKey::TVNumberEntry => Named::TVNumberEntry, + NamedKey::TVPower => Named::TVPower, + NamedKey::TVRadioService => Named::TVRadioService, + NamedKey::TVSatellite => Named::TVSatellite, + NamedKey::TVSatelliteBS => Named::TVSatelliteBS, + NamedKey::TVSatelliteCS => Named::TVSatelliteCS, + NamedKey::TVSatelliteToggle => Named::TVSatelliteToggle, + NamedKey::TVTerrestrialAnalog => Named::TVTerrestrialAnalog, + NamedKey::TVTerrestrialDigital => Named::TVTerrestrialDigital, + NamedKey::TVTimer => Named::TVTimer, + NamedKey::AVRInput => Named::AVRInput, + NamedKey::AVRPower => Named::AVRPower, + NamedKey::ColorF0Red => Named::ColorF0Red, + NamedKey::ColorF1Green => Named::ColorF1Green, + NamedKey::ColorF2Yellow => Named::ColorF2Yellow, + NamedKey::ColorF3Blue => Named::ColorF3Blue, + NamedKey::ColorF4Grey => Named::ColorF4Grey, + NamedKey::ColorF5Brown => Named::ColorF5Brown, + NamedKey::ClosedCaptionToggle => Named::ClosedCaptionToggle, + NamedKey::Dimmer => Named::Dimmer, + NamedKey::DisplaySwap => Named::DisplaySwap, + NamedKey::DVR => Named::DVR, + NamedKey::Exit => Named::Exit, + NamedKey::FavoriteClear0 => Named::FavoriteClear0, + NamedKey::FavoriteClear1 => Named::FavoriteClear1, + NamedKey::FavoriteClear2 => Named::FavoriteClear2, + NamedKey::FavoriteClear3 => Named::FavoriteClear3, + NamedKey::FavoriteRecall0 => Named::FavoriteRecall0, + NamedKey::FavoriteRecall1 => Named::FavoriteRecall1, + NamedKey::FavoriteRecall2 => Named::FavoriteRecall2, + NamedKey::FavoriteRecall3 => Named::FavoriteRecall3, + NamedKey::FavoriteStore0 => Named::FavoriteStore0, + NamedKey::FavoriteStore1 => Named::FavoriteStore1, + NamedKey::FavoriteStore2 => Named::FavoriteStore2, + NamedKey::FavoriteStore3 => Named::FavoriteStore3, + NamedKey::Guide => Named::Guide, + NamedKey::GuideNextDay => Named::GuideNextDay, + NamedKey::GuidePreviousDay => Named::GuidePreviousDay, + NamedKey::Info => Named::Info, + NamedKey::InstantReplay => Named::InstantReplay, + NamedKey::Link => Named::Link, + NamedKey::ListProgram => Named::ListProgram, + NamedKey::LiveContent => Named::LiveContent, + NamedKey::Lock => Named::Lock, + NamedKey::MediaApps => Named::MediaApps, + NamedKey::MediaAudioTrack => Named::MediaAudioTrack, + NamedKey::MediaLast => Named::MediaLast, + NamedKey::MediaSkipBackward => Named::MediaSkipBackward, + NamedKey::MediaSkipForward => Named::MediaSkipForward, + NamedKey::MediaStepBackward => Named::MediaStepBackward, + NamedKey::MediaStepForward => Named::MediaStepForward, + NamedKey::MediaTopMenu => Named::MediaTopMenu, + NamedKey::NavigateIn => Named::NavigateIn, + NamedKey::NavigateNext => Named::NavigateNext, + NamedKey::NavigateOut => Named::NavigateOut, + NamedKey::NavigatePrevious => Named::NavigatePrevious, + NamedKey::NextFavoriteChannel => Named::NextFavoriteChannel, + NamedKey::NextUserProfile => Named::NextUserProfile, + NamedKey::OnDemand => Named::OnDemand, + NamedKey::Pairing => Named::Pairing, + NamedKey::PinPDown => Named::PinPDown, + NamedKey::PinPMove => Named::PinPMove, + NamedKey::PinPToggle => Named::PinPToggle, + NamedKey::PinPUp => Named::PinPUp, + NamedKey::PlaySpeedDown => Named::PlaySpeedDown, + NamedKey::PlaySpeedReset => Named::PlaySpeedReset, + NamedKey::PlaySpeedUp => Named::PlaySpeedUp, + NamedKey::RandomToggle => Named::RandomToggle, + NamedKey::RcLowBattery => Named::RcLowBattery, + NamedKey::RecordSpeedNext => Named::RecordSpeedNext, + NamedKey::RfBypass => Named::RfBypass, + NamedKey::ScanChannelsToggle => Named::ScanChannelsToggle, + NamedKey::ScreenModeNext => Named::ScreenModeNext, + NamedKey::Settings => Named::Settings, + NamedKey::SplitScreenToggle => Named::SplitScreenToggle, + NamedKey::STBInput => Named::STBInput, + NamedKey::STBPower => Named::STBPower, + NamedKey::Subtitle => Named::Subtitle, + NamedKey::Teletext => Named::Teletext, + NamedKey::VideoModeNext => Named::VideoModeNext, + NamedKey::Wink => Named::Wink, + NamedKey::ZoomToggle => Named::ZoomToggle, + NamedKey::F1 => Named::F1, + NamedKey::F2 => Named::F2, + NamedKey::F3 => Named::F3, + NamedKey::F4 => Named::F4, + NamedKey::F5 => Named::F5, + NamedKey::F6 => Named::F6, + NamedKey::F7 => Named::F7, + NamedKey::F8 => Named::F8, + NamedKey::F9 => Named::F9, + NamedKey::F10 => Named::F10, + NamedKey::F11 => Named::F11, + NamedKey::F12 => Named::F12, + NamedKey::F13 => Named::F13, + NamedKey::F14 => Named::F14, + NamedKey::F15 => Named::F15, + NamedKey::F16 => Named::F16, + NamedKey::F17 => Named::F17, + NamedKey::F18 => Named::F18, + NamedKey::F19 => Named::F19, + NamedKey::F20 => Named::F20, + NamedKey::F21 => Named::F21, + NamedKey::F22 => Named::F22, + NamedKey::F23 => Named::F23, + NamedKey::F24 => Named::F24, + NamedKey::F25 => Named::F25, + NamedKey::F26 => Named::F26, + NamedKey::F27 => Named::F27, + NamedKey::F28 => Named::F28, + NamedKey::F29 => Named::F29, + NamedKey::F30 => Named::F30, + NamedKey::F31 => Named::F31, + NamedKey::F32 => Named::F32, + NamedKey::F33 => Named::F33, + NamedKey::F34 => Named::F34, + NamedKey::F35 => Named::F35, + _ => return keyboard::Key::Unidentified, + }) } - winit::event::VirtualKeyCode::NextTrack => KeyCode::NextTrack, - winit::event::VirtualKeyCode::NoConvert => KeyCode::NoConvert, - winit::event::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma, - winit::event::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter, - winit::event::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals, - winit::event::VirtualKeyCode::OEM102 => KeyCode::OEM102, - winit::event::VirtualKeyCode::Period => KeyCode::Period, - winit::event::VirtualKeyCode::PlayPause => KeyCode::PlayPause, - winit::event::VirtualKeyCode::Power => KeyCode::Power, - winit::event::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack, - winit::event::VirtualKeyCode::RAlt => KeyCode::RAlt, - winit::event::VirtualKeyCode::RBracket => KeyCode::RBracket, - winit::event::VirtualKeyCode::RControl => KeyCode::RControl, - winit::event::VirtualKeyCode::RShift => KeyCode::RShift, - winit::event::VirtualKeyCode::RWin => KeyCode::RWin, - winit::event::VirtualKeyCode::Semicolon => KeyCode::Semicolon, - winit::event::VirtualKeyCode::Slash => KeyCode::Slash, - winit::event::VirtualKeyCode::Sleep => KeyCode::Sleep, - winit::event::VirtualKeyCode::Stop => KeyCode::Stop, - winit::event::VirtualKeyCode::NumpadSubtract => KeyCode::NumpadSubtract, - winit::event::VirtualKeyCode::Sysrq => KeyCode::Sysrq, - winit::event::VirtualKeyCode::Tab => KeyCode::Tab, - winit::event::VirtualKeyCode::Underline => KeyCode::Underline, - winit::event::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled, - winit::event::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown, - winit::event::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp, - winit::event::VirtualKeyCode::Wake => KeyCode::Wake, - winit::event::VirtualKeyCode::WebBack => KeyCode::WebBack, - winit::event::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites, - winit::event::VirtualKeyCode::WebForward => KeyCode::WebForward, - winit::event::VirtualKeyCode::WebHome => KeyCode::WebHome, - winit::event::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh, - winit::event::VirtualKeyCode::WebSearch => KeyCode::WebSearch, - winit::event::VirtualKeyCode::WebStop => KeyCode::WebStop, - winit::event::VirtualKeyCode::Yen => KeyCode::Yen, - winit::event::VirtualKeyCode::Copy => KeyCode::Copy, - winit::event::VirtualKeyCode::Paste => KeyCode::Paste, - winit::event::VirtualKeyCode::Cut => KeyCode::Cut, - winit::event::VirtualKeyCode::Asterisk => KeyCode::Asterisk, + _ => keyboard::Key::Unidentified, } } @@ -655,13 +812,3 @@ pub fn icon(icon: window::Icon) -> Option<winit::window::Icon> { winit::window::Icon::from_rgba(pixels, size.width, size.height).ok() } - -// As defined in: http://www.unicode.org/faq/private_use.html -pub(crate) fn is_private_use_character(c: char) -> bool { - matches!( - c, - '\u{E000}'..='\u{F8FF}' - | '\u{F0000}'..='\u{FFFFD}' - | '\u{100000}'..='\u{10FFFD}' - ) -} diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 1550b94b..84c81bea 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -118,7 +118,10 @@ where let mut debug = Debug::new(); debug.startup_started(); - let event_loop = EventLoopBuilder::with_user_event().build(); + let event_loop = EventLoopBuilder::with_user_event() + .build() + .expect("Create event loop"); + let proxy = event_loop.create_proxy(); let runtime = { @@ -210,78 +213,78 @@ where let mut context = task::Context::from_waker(task::noop_waker_ref()); - platform::run(event_loop, move |event, window_target, control_flow| { - use winit::event_loop::ControlFlow; - - if let ControlFlow::ExitWithCode(_) = control_flow { + let _ = event_loop.run(move |event, event_loop| { + if event_loop.exiting() { return; } - let event = match event { - winit::event::Event::WindowEvent { - event: - winit::event::WindowEvent::ScaleFactorChanged { - new_inner_size, - .. - }, - window_id, - } => Some(winit::event::Event::WindowEvent { - event: winit::event::WindowEvent::Resized(*new_inner_size), - window_id, - }), - _ => event.to_static(), - }; - - if let Some(event) = event { - event_sender - .start_send(Event::EventLoopAwakened(event)) - .expect("Send event"); - - loop { - let poll = instance.as_mut().poll(&mut context); - - match poll { - task::Poll::Pending => match control_receiver.try_next() { - Ok(Some(control)) => match control { - Control::ChangeFlow(flow) => { - *control_flow = flow; - } - Control::CreateWindow { - id, - settings, - title, - monitor, - } => { - let exit_on_close_request = - settings.exit_on_close_request; - - let window = conversion::window_settings( - settings, &title, monitor, None, - ) - .build(window_target) - .expect("Failed to build window"); - - event_sender - .start_send(Event::WindowCreated { - id, - window, - exit_on_close_request, - }) - .expect("Send event"); + event_sender + .start_send(Event::EventLoopAwakened(event)) + .expect("Send event"); + + loop { + let poll = instance.as_mut().poll(&mut context); + + match poll { + task::Poll::Pending => match control_receiver.try_next() { + Ok(Some(control)) => match control { + Control::ChangeFlow(flow) => { + use winit::event_loop::ControlFlow; + + match (event_loop.control_flow(), flow) { + ( + ControlFlow::WaitUntil(current), + ControlFlow::WaitUntil(new), + ) if new < current => {} + ( + ControlFlow::WaitUntil(target), + ControlFlow::Wait, + ) if target > Instant::now() => {} + _ => { + event_loop.set_control_flow(flow); + } } - }, - _ => { - break; + } + Control::CreateWindow { + id, + settings, + title, + monitor, + } => { + let exit_on_close_request = + settings.exit_on_close_request; + + let window = conversion::window_settings( + settings, &title, monitor, None, + ) + .build(event_loop) + .expect("Failed to build window"); + + event_sender + .start_send(Event::WindowCreated { + id, + window, + exit_on_close_request, + }) + .expect("Send event"); + } + Control::Exit => { + event_loop.exit(); } }, - task::Poll::Ready(_) => { - *control_flow = ControlFlow::Exit; + _ => { break; } - }; - } + }, + task::Poll::Ready(_) => { + event_loop.exit(); + break; + } + }; } - }) + }); + + Ok(()) } enum Event<Message: 'static> { @@ -290,11 +293,12 @@ enum Event<Message: 'static> { window: winit::window::Window, exit_on_close_request: bool, }, - EventLoopAwakened(winit::event::Event<'static, Message>), + EventLoopAwakened(winit::event::Event<Message>), } enum Control { ChangeFlow(winit::event_loop::ControlFlow), + Exit, CreateWindow { id: window::Id, settings: window::Settings, @@ -372,7 +376,6 @@ async fn run_instance<A, E, C>( runtime.track(application.subscription().into_recipes()); let mut messages = Vec::new(); - let mut redraw_pending = false; debug.startup_finished(); @@ -419,191 +422,15 @@ async fn run_instance<A, E, C>( } Event::EventLoopAwakened(event) => { match event { - event::Event::NewEvents(start_cause) => { - redraw_pending = matches!( - start_cause, - event::StartCause::Init - | event::StartCause::Poll - | event::StartCause::ResumeTimeReached { .. } - ); - } - event::Event::MainEventsCleared => { - debug.event_processing_started(); - let mut uis_stale = false; - - for (id, window) in window_manager.iter_mut() { - let mut window_events = vec![]; - - events.retain(|(window_id, event)| { - if *window_id == Some(id) || window_id.is_none() - { - window_events.push(event.clone()); - false - } else { - true - } - }); - - if !redraw_pending - && window_events.is_empty() - && messages.is_empty() - { - continue; - } - - let (ui_state, statuses) = user_interfaces - .get_mut(&id) - .expect("Get user interface") - .update( - &window_events, - window.state.cursor(), - &mut window.renderer, - &mut clipboard, - &mut messages, - ); - - if !uis_stale { - uis_stale = matches!( - ui_state, - user_interface::State::Outdated - ); - } - - for (event, status) in window_events - .into_iter() - .zip(statuses.into_iter()) - { - runtime.broadcast(event, status); - } - } - - debug.event_processing_finished(); - - // TODO mw application update returns which window IDs to update - if !messages.is_empty() || uis_stale { - let mut cached_interfaces: HashMap< - window::Id, - user_interface::Cache, - > = ManuallyDrop::into_inner(user_interfaces) - .drain() - .map(|(id, ui)| (id, ui.into_cache())) - .collect(); - - // Update application - update( - &mut application, - &mut compositor, - &mut runtime, - &mut clipboard, - &mut control_sender, - &mut proxy, - &mut debug, - &mut messages, - &mut window_manager, - &mut cached_interfaces, - ); - - // we must synchronize all window states with application state after an - // application update since we don't know what changed - for (id, window) in window_manager.iter_mut() { - window.state.synchronize( - &application, - id, - &window.raw, - ); - } - - // rebuild UIs with the synchronized states - user_interfaces = - ManuallyDrop::new(build_user_interfaces( - &application, - &mut debug, - &mut window_manager, - cached_interfaces, - )); - } - - debug.draw_started(); - - for (id, window) in window_manager.iter_mut() { - // TODO: Avoid redrawing all the time by forcing widgets to - // request redraws on state changes - // - // Then, we can use the `interface_state` here to decide if a redraw - // is needed right away, or simply wait until a specific time. - let redraw_event = core::Event::Window( - id, - window::Event::RedrawRequested(Instant::now()), - ); - - let cursor = window.state.cursor(); - - let ui = user_interfaces - .get_mut(&id) - .expect("Get user interface"); - - let (ui_state, _) = ui.update( - &[redraw_event.clone()], - cursor, - &mut window.renderer, - &mut clipboard, - &mut messages, - ); - - let new_mouse_interaction = { - let state = &window.state; - - ui.draw( - &mut window.renderer, - state.theme(), - &renderer::Style { - text_color: state.text_color(), - }, - cursor, - ) - }; - - if new_mouse_interaction != window.mouse_interaction - { - window.raw.set_cursor_icon( - conversion::mouse_interaction( - new_mouse_interaction, - ), - ); - - window.mouse_interaction = - new_mouse_interaction; - } - + event::Event::NewEvents( + event::StartCause::Init + | event::StartCause::ResumeTimeReached { .. }, + ) => { + for (_id, window) in window_manager.iter_mut() { // TODO once widgets can request to be redrawn, we can avoid always requesting a // redraw window.raw.request_redraw(); - - runtime.broadcast( - redraw_event.clone(), - core::event::Status::Ignored, - ); - - let _ = control_sender.start_send( - Control::ChangeFlow(match ui_state { - user_interface::State::Updated { - redraw_request: Some(redraw_request), - } => match redraw_request { - window::RedrawRequest::NextFrame => { - ControlFlow::Poll - } - window::RedrawRequest::At(at) => { - ControlFlow::WaitUntil(at) - } - }, - _ => ControlFlow::Wait, - }), - ); } - - redraw_pending = false; - - debug.draw_finished(); } event::Event::PlatformSpecific( event::PlatformSpecific::MacOS( @@ -624,13 +451,85 @@ async fn run_instance<A, E, C>( event::Event::UserEvent(message) => { messages.push(message); } - event::Event::RedrawRequested(id) => { + event::Event::WindowEvent { + window_id: id, + event: event::WindowEvent::RedrawRequested, + .. + } => { let Some((id, window)) = window_manager.get_mut_alias(id) else { continue; }; + // TODO: Avoid redrawing all the time by forcing widgets to + // request redraws on state changes + // + // Then, we can use the `interface_state` here to decide if a redraw + // is needed right away, or simply wait until a specific time. + let redraw_event = core::Event::Window( + id, + window::Event::RedrawRequested(Instant::now()), + ); + + let cursor = window.state.cursor(); + + let ui = user_interfaces + .get_mut(&id) + .expect("Get user interface"); + + let (ui_state, _) = ui.update( + &[redraw_event.clone()], + cursor, + &mut window.renderer, + &mut clipboard, + &mut messages, + ); + + debug.draw_started(); + let new_mouse_interaction = ui.draw( + &mut window.renderer, + window.state.theme(), + &renderer::Style { + text_color: window.state.text_color(), + }, + cursor, + ); + debug.draw_finished(); + + if new_mouse_interaction != window.mouse_interaction { + window.raw.set_cursor_icon( + conversion::mouse_interaction( + new_mouse_interaction, + ), + ); + + window.mouse_interaction = new_mouse_interaction; + } + + runtime.broadcast( + redraw_event.clone(), + core::event::Status::Ignored, + ); + + let _ = control_sender.start_send(Control::ChangeFlow( + match ui_state { + user_interface::State::Updated { + redraw_request: Some(redraw_request), + } => match redraw_request { + window::RedrawRequest::NextFrame => { + window.raw.request_redraw(); + + ControlFlow::Wait + } + window::RedrawRequest::At(at) => { + ControlFlow::WaitUntil(at) + } + }, + _ => ControlFlow::Wait, + }, + )); + let physical_size = window.state.physical_size(); if physical_size.width == 0 || physical_size.height == 0 @@ -638,14 +537,12 @@ async fn run_instance<A, E, C>( continue; } - debug.render_started(); if window.viewport_version != window.state.viewport_version() { let logical_size = window.state.logical_size(); debug.layout_started(); - let ui = user_interfaces .remove(&id) .expect("Remove user interface"); @@ -654,7 +551,6 @@ async fn run_instance<A, E, C>( id, ui.relayout(logical_size, &mut window.renderer), ); - debug.layout_finished(); debug.draw_started(); @@ -669,6 +565,7 @@ async fn run_instance<A, E, C>( }, window.state.cursor(), ); + debug.draw_finished(); if new_mouse_interaction != window.mouse_interaction { @@ -681,7 +578,6 @@ async fn run_instance<A, E, C>( window.mouse_interaction = new_mouse_interaction; } - debug.draw_finished(); compositor.configure_surface( &mut window.surface, @@ -693,6 +589,7 @@ async fn run_instance<A, E, C>( window.state.viewport_version(); } + debug.render_started(); match compositor.present( &mut window.renderer, &mut window.surface, @@ -713,9 +610,11 @@ async fn run_instance<A, E, C>( } _ => { debug.render_finished(); + log::error!( - "Error {error:?} when presenting surface." - ); + "Error {error:?} when \ + presenting surface." + ); // Try rendering all windows again next frame. for (_id, window) in @@ -763,7 +662,7 @@ async fn run_instance<A, E, C>( if let Some(event) = conversion::window_event( id, - &window_event, + window_event, window.state.scale_factor(), window.state.modifiers(), ) { @@ -771,6 +670,109 @@ async fn run_instance<A, E, C>( } } } + event::Event::AboutToWait => { + if events.is_empty() && messages.is_empty() { + continue; + } + + debug.event_processing_started(); + let mut uis_stale = false; + + for (id, window) in window_manager.iter_mut() { + let mut window_events = vec![]; + + events.retain(|(window_id, event)| { + if *window_id == Some(id) || window_id.is_none() + { + window_events.push(event.clone()); + false + } else { + true + } + }); + + if window_events.is_empty() && messages.is_empty() { + continue; + } + + let (ui_state, statuses) = user_interfaces + .get_mut(&id) + .expect("Get user interface") + .update( + &window_events, + window.state.cursor(), + &mut window.renderer, + &mut clipboard, + &mut messages, + ); + + window.raw.request_redraw(); + + if !uis_stale { + uis_stale = matches!( + ui_state, + user_interface::State::Outdated + ); + } + + for (event, status) in window_events + .into_iter() + .zip(statuses.into_iter()) + { + runtime.broadcast(event, status); + } + } + + debug.event_processing_finished(); + + // TODO mw application update returns which window IDs to update + if !messages.is_empty() || uis_stale { + let mut cached_interfaces: HashMap< + window::Id, + user_interface::Cache, + > = ManuallyDrop::into_inner(user_interfaces) + .drain() + .map(|(id, ui)| (id, ui.into_cache())) + .collect(); + + // Update application + update( + &mut application, + &mut compositor, + &mut runtime, + &mut clipboard, + &mut control_sender, + &mut proxy, + &mut debug, + &mut messages, + &mut window_manager, + &mut cached_interfaces, + ); + + // we must synchronize all window states with application state after an + // application update since we don't know what changed + for (id, window) in window_manager.iter_mut() { + window.state.synchronize( + &application, + id, + &window.raw, + ); + + // TODO once widgets can request to be redrawn, we can avoid always requesting a + // redraw + window.raw.request_redraw(); + } + + // rebuild UIs with the synchronized states + user_interfaces = + ManuallyDrop::new(build_user_interfaces( + &application, + &mut debug, + &mut window_manager, + cached_interfaces, + )); + } + } _ => {} } } @@ -901,16 +903,12 @@ fn run_command<A, C, E>( .expect("Send control action"); } window::Action::Close(id) => { - use winit::event_loop::ControlFlow; - let _ = window_manager.remove(id); let _ = ui_caches.remove(&id); if window_manager.is_empty() { control_sender - .start_send(Control::ChangeFlow( - ControlFlow::ExitWithCode(0), - )) + .start_send(Control::Exit) .expect("Send control action"); } } @@ -921,10 +919,12 @@ fn run_command<A, C, E>( } window::Action::Resize(id, size) => { if let Some(window) = window_manager.get_mut(id) { - window.raw.set_inner_size(winit::dpi::LogicalSize { - width: size.width, - height: size.height, - }); + let _ = window.raw.request_inner_size( + winit::dpi::LogicalSize { + width: size.width, + height: size.height, + }, + ); } } window::Action::FetchSize(id, callback) => { @@ -1167,60 +1167,20 @@ where /// Returns true if the provided event should cause an [`Application`] to /// exit. pub fn user_force_quit( - event: &winit::event::WindowEvent<'_>, - _modifiers: winit::event::ModifiersState, + event: &winit::event::WindowEvent, + _modifiers: winit::keyboard::ModifiersState, ) -> bool { match event { #[cfg(target_os = "macos")] winit::event::WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(winit::event::VirtualKeyCode::Q), + event: + winit::event::KeyEvent { + logical_key: winit::keyboard::Key::Character(c), state: winit::event::ElementState::Pressed, .. }, .. - } if _modifiers.logo() => true, + } if c == "q" && _modifiers.super_key() => true, _ => false, } } - -#[cfg(not(target_arch = "wasm32"))] -mod platform { - pub fn run<T, F>( - mut event_loop: winit::event_loop::EventLoop<T>, - event_handler: F, - ) -> Result<(), super::Error> - where - F: 'static - + FnMut( - winit::event::Event<'_, T>, - &winit::event_loop::EventLoopWindowTarget<T>, - &mut winit::event_loop::ControlFlow, - ), - { - use winit::platform::run_return::EventLoopExtRunReturn; - - let _ = event_loop.run_return(event_handler); - - Ok(()) - } -} - -#[cfg(target_arch = "wasm32")] -mod platform { - pub fn run<T, F>( - event_loop: winit::event_loop::EventLoop<T>, - event_handler: F, - ) -> ! - where - F: 'static - + FnMut( - winit::event::Event<'_, T>, - &winit::event_loop::EventLoopWindowTarget<T>, - &mut winit::event_loop::ControlFlow, - ), - { - event_loop.run(event_handler) - } -} diff --git a/winit/src/multi_window/state.rs b/winit/src/multi_window/state.rs index 03da5ad7..235771f4 100644 --- a/winit/src/multi_window/state.rs +++ b/winit/src/multi_window/state.rs @@ -21,7 +21,7 @@ where viewport: Viewport, viewport_version: u64, cursor_position: Option<winit::dpi::PhysicalPosition<f64>>, - modifiers: winit::event::ModifiersState, + modifiers: winit::keyboard::ModifiersState, theme: <A::Renderer as core::Renderer>::Theme, appearance: application::Appearance, } @@ -72,7 +72,7 @@ where viewport, viewport_version: 0, cursor_position: None, - modifiers: winit::event::ModifiersState::default(), + modifiers: winit::keyboard::ModifiersState::default(), theme, appearance, } @@ -119,7 +119,7 @@ where } /// Returns the current keyboard modifiers of the [`State`]. - pub fn modifiers(&self) -> winit::event::ModifiersState { + pub fn modifiers(&self) -> winit::keyboard::ModifiersState { self.modifiers } @@ -142,7 +142,7 @@ where pub fn update( &mut self, window: &Window, - event: &WindowEvent<'_>, + event: &WindowEvent, _debug: &mut crate::runtime::Debug, ) { match event { @@ -158,10 +158,9 @@ where } WindowEvent::ScaleFactorChanged { scale_factor: new_scale_factor, - new_inner_size, + .. } => { - let size = - Size::new(new_inner_size.width, new_inner_size.height); + let size = self.viewport.physical_size(); self.viewport = Viewport::with_physical_size( size, @@ -180,13 +179,16 @@ where self.cursor_position = None; } WindowEvent::ModifiersChanged(new_modifiers) => { - self.modifiers = *new_modifiers; + self.modifiers = new_modifiers.state(); } #[cfg(feature = "debug")] WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(winit::event::VirtualKeyCode::F12), + event: + winit::event::KeyEvent { + logical_key: + winit::keyboard::Key::Named( + winit::keyboard::NamedKey::F12, + ), state: winit::event::ElementState::Pressed, .. }, |