Update winit to 0.29.4

This commit is contained in:
Héctor Ramón Jiménez 2023-12-15 13:15:44 +01:00
parent dd249a1d11
commit e819c2390b
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
19 changed files with 654 additions and 846 deletions

View file

@ -130,7 +130,6 @@ glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "2caa9fc5e592
guillotiere = "0.6"
half = "2.2"
image = "0.24"
instant = "0.1"
kamadak-exif = "0.5"
kurbo = "0.9"
log = "0.4"
@ -157,7 +156,8 @@ unicode-segmentation = "1.0"
wasm-bindgen-futures = "0.4"
wasm-timer = "0.2"
web-sys = "0.3"
web-time = "0.2"
wgpu = "0.18"
winapi = "0.3"
window_clipboard = "0.3"
winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false }
winit = { git = "https://github.com/iced-rs/winit.git", rev = "3bcdb9abcd7459978ec689523bc21943d38da0f9", default-features = false, features = ["rwh_05", "x11", "wayland"] }

View file

@ -16,13 +16,11 @@ log.workspace = true
thiserror.workspace = true
xxhash-rust.workspace = true
num-traits.workspace = true
web-time.workspace = true
palette.workspace = true
palette.optional = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
instant.workspace = true
[target.'cfg(windows)'.dependencies]
raw-window-handle.workspace = true

View file

@ -6,7 +6,7 @@ use super::{KeyCode, Modifiers};
/// additional events, feel free to [open an issue] and share your use case!_
///
/// [open an issue]: https://github.com/iced-rs/iced/issues
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
/// A keyboard key was pressed.
KeyPressed {
@ -15,6 +15,9 @@ pub enum Event {
/// The state of the modifier keys
modifiers: Modifiers,
/// The text produced by the key press, if any.
text: Option<String>,
},
/// A keyboard key was released.
@ -26,9 +29,6 @@ pub enum Event {
modifiers: Modifiers,
},
/// A unicode character was received.
CharacterReceived(char),
/// The keyboard modifiers have changed.
ModifiersChanged(Modifiers),
}

View file

@ -10,6 +10,12 @@ pub enum Button {
/// The middle (wheel) button.
Middle,
/// The back mouse button.
Back,
/// The forward mouse button.
Forward,
/// Some other button.
Other(u16),
}

View file

@ -1,13 +1,4 @@
//! Keep track of time, both in native and web platforms!
#[cfg(target_arch = "wasm32")]
pub use instant::Instant;
#[cfg(target_arch = "wasm32")]
pub use instant::Duration;
#[cfg(not(target_arch = "wasm32"))]
pub use std::time::Instant;
#[cfg(not(target_arch = "wasm32"))]
pub use std::time::Duration;
pub use web_time::Duration;
pub use web_time::Instant;

View file

@ -19,8 +19,9 @@ use iced_winit::winit;
use iced_winit::Clipboard;
use winit::{
event::{Event, ModifiersState, WindowEvent},
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
keyboard::ModifiersState,
};
#[cfg(target_arch = "wasm32")]
@ -48,7 +49,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
// Initialize winit
let event_loop = EventLoop::new();
let event_loop = EventLoop::new()?;
#[cfg(target_arch = "wasm32")]
let window = winit::window::WindowBuilder::new()
@ -160,67 +161,15 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
);
// Run event loop
event_loop.run(move |event, _, control_flow| {
event_loop.run(move |event, window_target| {
// You should change this if you want to render continuosly
*control_flow = ControlFlow::Wait;
window_target.set_control_flow(ControlFlow::Wait);
match event {
Event::WindowEvent { event, .. } => {
match event {
WindowEvent::CursorMoved { position, .. } => {
cursor_position = Some(position);
}
WindowEvent::ModifiersChanged(new_modifiers) => {
modifiers = new_modifiers;
}
WindowEvent::Resized(_) => {
resized = true;
}
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
_ => {}
}
// Map window event to iced event
if let Some(event) = iced_winit::conversion::window_event(
window::Id::MAIN,
&event,
window.scale_factor(),
modifiers,
) {
state.queue_event(event);
}
}
Event::MainEventsCleared => {
// If there are events pending
if !state.is_queue_empty() {
// We update iced
let _ = state.update(
viewport.logical_size(),
cursor_position
.map(|p| {
conversion::cursor_position(
p,
viewport.scale_factor(),
)
})
.map(mouse::Cursor::Available)
.unwrap_or(mouse::Cursor::Unavailable),
&mut renderer,
&Theme::Dark,
&renderer::Style {
text_color: Color::WHITE,
},
&mut clipboard,
&mut debug,
);
// and request a redraw
window.request_redraw();
}
}
Event::RedrawRequested(_) => {
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
if resized {
let size = window.inner_size();
@ -309,7 +258,60 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
},
}
}
Event::WindowEvent { event, .. } => {
match event {
WindowEvent::CursorMoved { position, .. } => {
cursor_position = Some(position);
}
WindowEvent::ModifiersChanged(new_modifiers) => {
modifiers = new_modifiers.state();
}
WindowEvent::Resized(_) => {
resized = true;
}
WindowEvent::CloseRequested => {
window_target.exit();
}
_ => {}
}
// Map window event to iced event
if let Some(event) = iced_winit::conversion::window_event(
window::Id::MAIN,
&event,
window.scale_factor(),
modifiers,
) {
state.queue_event(event);
}
}
_ => {}
}
})
// If there are events pending
if !state.is_queue_empty() {
// We update iced
let _ = state.update(
viewport.logical_size(),
cursor_position
.map(|p| {
conversion::cursor_position(p, viewport.scale_factor())
})
.map(mouse::Cursor::Available)
.unwrap_or(mouse::Cursor::Unavailable),
&mut renderer,
&Theme::Dark,
&renderer::Style {
text_color: Color::WHITE,
},
&mut clipboard,
&mut debug,
);
// and request a redraw
window.request_redraw();
}
})?;
Ok(())
}

View file

@ -87,6 +87,7 @@ impl Application for App {
Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
modifiers,
..
}) => {
if modifiers.shift() {
widget::focus_previous()

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["image", "debug", "tokio"]
iced.features = ["image", "debug", "tokio", "webgl"]
serde_json = "1.0"

View file

@ -95,6 +95,7 @@ impl Application for App {
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
modifiers,
..
})) if modifiers.shift() => widget::focus_previous(),
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,

View file

@ -24,6 +24,7 @@ where
core::Event::Keyboard(Event::KeyPressed {
key_code,
modifiers,
..
}),
core::event::Status::Ignored,
) => f(key_code, modifiers),

View file

@ -8,7 +8,7 @@ pub use crate::core::event::Status;
/// A [`Canvas`] event.
///
/// [`Canvas`]: crate::Canvas
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Event {
/// A mouse event.
Mouse(mouse::Event),

View file

@ -9,7 +9,7 @@ pub use crate::core::event::Status;
/// A [`Shader`] event.
///
/// [`Shader`]: crate::Shader
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Event {
/// A mouse event.
Mouse(mouse::Event),

View file

@ -649,6 +649,7 @@ impl Update {
keyboard::Event::KeyPressed {
key_code,
modifiers,
text,
} if state.is_focused => {
if let Some(motion) = motion(key_code) {
let motion =
@ -678,12 +679,15 @@ impl Update {
{
Some(Self::Paste)
}
_ => None,
_ => {
let text = text?;
edit(Edit::Insert(
text.chars().next().unwrap_or_default(),
))
}
}
}
keyboard::Event::CharacterReceived(c) if state.is_focused => {
edit(Edit::Insert(c))
}
_ => None,
},
_ => None,

View file

@ -752,34 +752,9 @@ where
return event::Status::Captured;
}
}
Event::Keyboard(keyboard::Event::CharacterReceived(c)) => {
let state = state();
if let Some(focus) = &mut state.is_focused {
let Some(on_input) = on_input else {
return event::Status::Ignored;
};
if state.is_pasting.is_none()
&& !state.keyboard_modifiers.command()
&& !c.is_control()
{
let mut editor = Editor::new(value, &mut state.cursor);
editor.insert(c);
let message = (on_input)(editor.contents());
shell.publish(message);
focus.updated_at = Instant::now();
update_cache(state, value);
return event::Status::Captured;
}
}
}
Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. }) => {
Event::Keyboard(keyboard::Event::KeyPressed {
key_code, text, ..
}) => {
let state = state();
if let Some(focus) = &mut state.is_focused {
@ -971,7 +946,30 @@ where
| keyboard::KeyCode::Down => {
return event::Status::Ignored;
}
_ => {}
_ => {
if let Some(text) = text {
let c = text.chars().next().unwrap_or_default();
if state.is_pasting.is_none()
&& !state.keyboard_modifiers.command()
&& !c.is_control()
{
let mut editor =
Editor::new(value, &mut state.cursor);
editor.insert(c);
let message = (on_input)(editor.contents());
shell.publish(message);
focus.updated_at = Instant::now();
update_cache(state, value);
return event::Status::Captured;
}
}
}
}
return event::Status::Captured;

View file

@ -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(),
event_sender.start_send(event).expect("Send event");
let poll = instance.as_mut().poll(&mut context);
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();
}
};
});
if let Some(event) = event {
event_sender.start_send(event).expect("Send event");
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;
}
};
}
})
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)
}
}

View file

@ -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,
..
},

View file

@ -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;
use winit::keyboard::NamedKey;
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,
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}'
)
}

View file

@ -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) => {
event_loop.set_control_flow(flow);
}
Control::CreateWindow {
id,
settings,
title,
monitor,
} => {
let exit_on_close_request =
settings.exit_on_close_request;
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(event_loop)
.expect("Failed to build window");
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;
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)
}
}

View file

@ -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,
..
},