diff options
Diffstat (limited to 'winit')
| -rw-r--r-- | winit/src/application.rs | 341 | ||||
| -rw-r--r-- | winit/src/application/state.rs | 24 | ||||
| -rw-r--r-- | winit/src/conversion.rs | 352 | ||||
| -rw-r--r-- | winit/src/multi_window.rs | 527 | ||||
| -rw-r--r-- | winit/src/multi_window/state.rs | 24 | 
5 files changed, 537 insertions, 731 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs index d9700075..ed6ba9eb 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>, @@ -335,89 +320,24 @@ async fn run_instance<A, E, C>(                          | event::StartCause::ResumeTimeReached { .. }                  );              } -            event::Event::MainEventsCleared => { -                if !redraw_pending && 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, -                        &state, -                        &mut renderer, -                        &mut runtime, -                        &mut clipboard, -                        &mut should_exit, -                        &mut proxy, -                        &mut debug, -                        &mut messages, -                        &window, -                    ); - -                    // 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; -                    } -                } - -                // 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 = Event::Window( -                    window::Id::MAIN, -                    window::Event::RedrawRequested(Instant::now()), -                ); - -                let (interface_state, _) = user_interface.update( -                    &[redraw_event.clone()], -                    state.cursor(), -                    &mut renderer, -                    &mut clipboard, -                    &mut messages, -                ); +            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::WindowEvent { +                event: event::WindowEvent::RedrawRequested { .. }, +                .. +            } => {                  debug.draw_started();                  let new_mouse_interaction = user_interface.draw(                      &mut renderer, @@ -437,38 +357,6 @@ 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 { @@ -566,6 +454,98 @@ async fn run_instance<A, E, C>(              }              _ => {}          } + +        if !redraw_pending && 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, +                &state, +                &mut renderer, +                &mut runtime, +                &mut clipboard, +                &mut should_exit, +                &mut proxy, +                &mut debug, +                &mut messages, +                &window, +            ); + +            // 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; +            } +        } + +        // 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 = Event::Window( +            window::Id::MAIN, +            window::Event::RedrawRequested(Instant::now()), +        ); + +        let (interface_state, _) = user_interface.update( +            &[redraw_event.clone()], +            state.cursor(), +            &mut renderer, +            &mut clipboard, +            &mut messages, +        ); + +        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;      }      // Manually drop the user interface @@ -575,8 +555,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 +564,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,      }  } @@ -726,10 +706,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 = @@ -878,43 +859,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..ecc34320 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))          } @@ -203,19 +192,17 @@ 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,                      ..                  },              ..          } => Some(Event::Keyboard({ -            let key_code = key_code(*virtual_keycode); +            let key_code = key_code(logical_key);              let modifiers = self::modifiers(modifiers);              match state { @@ -223,6 +210,9 @@ pub fn window_event(                      keyboard::Event::KeyPressed {                          key_code,                          modifiers, +                        text: text +                            .as_ref() +                            .map(winit::keyboard::SmolStr::to_string),                      }                  }                  winit::event::ElementState::Released => { @@ -233,9 +223,11 @@ pub fn window_event(                  }              }          })), -        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 { @@ -365,7 +357,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 +380,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 +392,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 +449,125 @@ 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 { +pub fn key_code(key: &winit::keyboard::Key) -> 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 -        } -        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, +    use winit::keyboard::NamedKey; + +    match key { +        winit::keyboard::Key::Character(c) => match c.as_str() { +            "1" => KeyCode::Key1, +            "2" => KeyCode::Key2, +            "3" => KeyCode::Key3, +            "4" => KeyCode::Key4, +            "5" => KeyCode::Key5, +            "6" => KeyCode::Key6, +            "7" => KeyCode::Key7, +            "8" => KeyCode::Key8, +            "9" => KeyCode::Key9, +            "0" => KeyCode::Key0, +            "A" => KeyCode::A, +            "B" => KeyCode::B, +            "C" => KeyCode::C, +            "D" => KeyCode::D, +            "E" => KeyCode::E, +            "F" => KeyCode::F, +            "G" => KeyCode::G, +            "H" => KeyCode::H, +            "I" => KeyCode::I, +            "J" => KeyCode::J, +            "K" => KeyCode::K, +            "L" => KeyCode::L, +            "M" => KeyCode::M, +            "N" => KeyCode::N, +            "O" => KeyCode::O, +            "P" => KeyCode::P, +            "Q" => KeyCode::Q, +            "R" => KeyCode::R, +            "S" => KeyCode::S, +            "T" => KeyCode::T, +            "U" => KeyCode::U, +            "V" => KeyCode::V, +            "W" => KeyCode::W, +            "X" => KeyCode::X, +            "Y" => KeyCode::Y, +            "Z" => KeyCode::Z, +            _ => KeyCode::Unlabeled, +        }, +        winit::keyboard::Key::Named(named_key) => match named_key { +            NamedKey::Escape => KeyCode::Escape, +            NamedKey::F1 => KeyCode::F1, +            NamedKey::F2 => KeyCode::F2, +            NamedKey::F3 => KeyCode::F3, +            NamedKey::F4 => KeyCode::F4, +            NamedKey::F5 => KeyCode::F5, +            NamedKey::F6 => KeyCode::F6, +            NamedKey::F7 => KeyCode::F7, +            NamedKey::F8 => KeyCode::F8, +            NamedKey::F9 => KeyCode::F9, +            NamedKey::F10 => KeyCode::F10, +            NamedKey::F11 => KeyCode::F11, +            NamedKey::F12 => KeyCode::F12, +            NamedKey::F13 => KeyCode::F13, +            NamedKey::F14 => KeyCode::F14, +            NamedKey::F15 => KeyCode::F15, +            NamedKey::F16 => KeyCode::F16, +            NamedKey::F17 => KeyCode::F17, +            NamedKey::F18 => KeyCode::F18, +            NamedKey::F19 => KeyCode::F19, +            NamedKey::F20 => KeyCode::F20, +            NamedKey::F21 => KeyCode::F21, +            NamedKey::F22 => KeyCode::F22, +            NamedKey::F23 => KeyCode::F23, +            NamedKey::F24 => KeyCode::F24, +            NamedKey::PrintScreen => KeyCode::Snapshot, +            NamedKey::ScrollLock => KeyCode::Scroll, +            NamedKey::Pause => KeyCode::Pause, +            NamedKey::Insert => KeyCode::Insert, +            NamedKey::Home => KeyCode::Home, +            NamedKey::Delete => KeyCode::Delete, +            NamedKey::End => KeyCode::End, +            NamedKey::PageDown => KeyCode::PageDown, +            NamedKey::PageUp => KeyCode::PageUp, +            NamedKey::ArrowLeft => KeyCode::Left, +            NamedKey::ArrowUp => KeyCode::Up, +            NamedKey::ArrowRight => KeyCode::Right, +            NamedKey::ArrowDown => KeyCode::Down, +            NamedKey::Backspace => KeyCode::Backspace, +            NamedKey::Enter => KeyCode::Enter, +            NamedKey::Space => KeyCode::Space, +            NamedKey::Compose => KeyCode::Compose, +            NamedKey::NumLock => KeyCode::Numlock, +            NamedKey::AppSwitch => KeyCode::Apps, +            NamedKey::Convert => KeyCode::Convert, +            NamedKey::LaunchMail => KeyCode::Mail, +            NamedKey::MediaApps => KeyCode::MediaSelect, +            NamedKey::MediaStop => KeyCode::MediaStop, +            NamedKey::AudioVolumeMute => KeyCode::Mute, +            NamedKey::MediaStepForward => KeyCode::NavigateForward, +            NamedKey::MediaStepBackward => KeyCode::NavigateBackward, +            NamedKey::MediaSkipForward => KeyCode::NextTrack, +            NamedKey::NonConvert => KeyCode::NoConvert, +            NamedKey::MediaPlayPause => KeyCode::PlayPause, +            NamedKey::Power => KeyCode::Power, +            NamedKey::MediaSkipBackward => KeyCode::PrevTrack, +            NamedKey::PowerOff => KeyCode::Sleep, +            NamedKey::Tab => KeyCode::Tab, +            NamedKey::AudioVolumeDown => KeyCode::VolumeDown, +            NamedKey::AudioVolumeUp => KeyCode::VolumeUp, +            NamedKey::WakeUp => KeyCode::Wake, +            NamedKey::BrowserBack => KeyCode::WebBack, +            NamedKey::BrowserFavorites => KeyCode::WebFavorites, +            NamedKey::BrowserForward => KeyCode::WebForward, +            NamedKey::BrowserHome => KeyCode::WebHome, +            NamedKey::BrowserRefresh => KeyCode::WebRefresh, +            NamedKey::BrowserSearch => KeyCode::WebSearch, +            NamedKey::BrowserStop => KeyCode::WebStop, +            NamedKey::Copy => KeyCode::Copy, +            NamedKey::Paste => KeyCode::Paste, +            NamedKey::Cut => KeyCode::Cut, +            _ => KeyCode::Unlabeled, +        }, +        _ => KeyCode::Unlabeled,      }  } @@ -655,13 +595,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 84651d40..16b41e7d 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,64 @@ 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(), -        }; +        event_sender +            .start_send(Event::EventLoopAwakened(event)) +            .expect("Send event"); -        if let Some(event) = event { -            event_sender -                .start_send(Event::EventLoopAwakened(event)) -                .expect("Send event"); +        loop { +            let poll = instance.as_mut().poll(&mut context); -            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"); -                            } -                        }, -                        _ => { -                            break; +            match poll { +                task::Poll::Pending => match control_receiver.try_next() { +                    Ok(Some(control)) => match control { +                        Control::ChangeFlow(flow) => { +                            event_loop.set_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(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 +279,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, @@ -427,184 +417,6 @@ async fn run_instance<A, E, C>(                                  | 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; -                            } - -                            // 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(                              event::MacOS::ReceivedUrl(url), @@ -624,7 +436,11 @@ 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 { @@ -775,6 +591,163 @@ async fn run_instance<A, E, C>(                  }              }          } + +        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; +            } + +            // 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();      }      let _ = ManuallyDrop::into_inner(user_interfaces); @@ -901,16 +874,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 +890,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) => { @@ -1153,60 +1124,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,                          ..                      },  | 
