winit 0.29

This commit is contained in:
Roland Fredenhagen 2023-09-02 15:31:43 +02:00
parent 5c70f99d95
commit e7d01c02bb
No known key found for this signature in database
GPG key ID: 094AF99241035EB6
5 changed files with 550 additions and 297 deletions

654
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -5,5 +5,5 @@ edition = "2021"
[dependencies]
winit = "0.28.6"
winit = "0.29.1-beta"
raw-window-handle = "0.5.1"

View file

@ -15,6 +15,7 @@ use winit::error::OsError;
use winit::window::WindowId;
use std::collections::HashMap;
use std::process::exit;
use std::sync::{mpsc, Arc, Mutex, PoisonError};
use winit::event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget};
use winit::{event::Event, event_loop::EventLoop};
@ -64,7 +65,9 @@ where
event_callback: impl FnMut(AppMessage, &Windows<AppMessage::Window>) -> AppMessage::Response
+ 'static,
) -> Self {
let event_loop = EventLoopBuilder::with_user_event().build();
let event_loop = EventLoopBuilder::with_user_event()
.build()
.expect("should be able to create an EventLoop");
let proxy = event_loop.create_proxy();
Self {
event_loop,
@ -80,54 +83,57 @@ where
///
/// Internally this runs the [`EventLoop`].
pub fn run(mut self) -> ! {
self.event_loop.run(move |event, target, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent { window_id, event } => {
let event = WindowEvent::from(event);
self.running
.windows
.send(window_id, WindowMessage::Event(event));
}
Event::RedrawRequested(window_id) => {
self.running.windows.send(window_id, WindowMessage::Redraw);
}
Event::UserEvent(message) => match message {
EventLoopMessage::CloseWindow(window_id) => {
if self.running.windows.close(window_id) {
*control_flow = ControlFlow::ExitWithCode(0);
self.event_loop
.run(move |event, target, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent { window_id, event } => {
let event = WindowEvent::from(event);
self.running
.windows
.send(window_id, WindowMessage::Event(event));
}
Event::RedrawRequested(window_id) => {
self.running.windows.send(window_id, WindowMessage::Redraw);
}
Event::UserEvent(message) => match message {
EventLoopMessage::CloseWindow(window_id) => {
if self.running.windows.close(window_id) {
*control_flow = ControlFlow::ExitWithCode(0);
}
}
}
EventLoopMessage::WindowPanic(window_id) => {
if self.running.windows.close(window_id) {
*control_flow = ControlFlow::ExitWithCode(1);
EventLoopMessage::WindowPanic(window_id) => {
if self.running.windows.close(window_id) {
*control_flow = ControlFlow::ExitWithCode(1);
}
}
}
EventLoopMessage::OpenWindow {
attrs,
sender,
open_sender,
} => {
let result = self.running.windows.open(target, attrs, sender);
let _result = open_sender.send(result);
}
EventLoopMessage::User {
message,
response_sender,
} => {
let _result = response_sender
.send((self.message_callback)(message, &self.running.windows));
}
},
Event::NewEvents(_)
| Event::DeviceEvent { .. }
| Event::Suspended
| Event::Resumed
| Event::MainEventsCleared
| Event::RedrawEventsCleared
| Event::LoopDestroyed => {}
}
});
EventLoopMessage::OpenWindow {
attrs,
sender,
open_sender,
} => {
let result = self.running.windows.open(target, attrs, sender);
let _result = open_sender.send(result);
}
EventLoopMessage::User {
message,
response_sender,
} => {
let _result = response_sender
.send((self.message_callback)(message, &self.running.windows));
}
},
Event::NewEvents(_)
| Event::DeviceEvent { .. }
| Event::Suspended
| Event::Resumed
| Event::LoopExiting
| Event::AboutToWait => {}
}
})
.unwrap();
// TODO do we want to forward the change to a result
exit(0);
}
}

View file

@ -4,10 +4,11 @@ use std::sync::{mpsc, Arc};
use winit::dpi::{PhysicalPosition, PhysicalSize};
use winit::error::OsError;
use winit::event::{
AxisId, DeviceId, ElementState, Ime, KeyboardInput, ModifiersState, MouseButton,
AxisId, DeviceId, ElementState, Ime, InnerSizeWriter, KeyEvent, Modifiers, MouseButton,
MouseScrollDelta, Touch, TouchPhase,
};
use winit::window::{Theme, WindowId};
use winit::event_loop::AsyncRequestSerial;
use winit::window::{ActivationToken, Theme, WindowId};
use crate::window::WindowAttributes;
use crate::Message;
@ -96,7 +97,7 @@ pub enum WindowEvent {
/// An event from the keyboard has been received.
KeyboardInput {
device_id: DeviceId,
input: KeyboardInput,
event: KeyEvent,
/// If `true`, the event was generated synthetically by winit
/// in one of the following circumstances:
///
@ -115,7 +116,7 @@ pub enum WindowEvent {
///
/// - **Web:** This API is currently unimplemented on the web. This isn't by design - it's an
/// issue, and it should get fixed - but it's the current state of the API.
ModifiersChanged(ModifiersState),
ModifiersChanged(Modifiers),
/// An event from an input method.
///
@ -196,7 +197,7 @@ pub enum WindowEvent {
/// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
ScaleFactorChanged {
scale_factor: f64,
new_inner_size: PhysicalSize<u32>,
inner_size_writer: InnerSizeWriter,
},
/// The system window theme has changed.
@ -231,11 +232,18 @@ pub enum WindowEvent {
delta: f32,
phase: TouchPhase,
},
/// The activation token was delivered back and now could be used.
///
/// Delivered in response to [`request_activation_token`].
ActivationTokenDone {
serial: AsyncRequestSerial,
token: ActivationToken,
},
}
impl<'a> From<winit::event::WindowEvent<'a>> for WindowEvent {
impl From<winit::event::WindowEvent> for WindowEvent {
#[allow(clippy::too_many_lines)] // it's a match statement
fn from(event: winit::event::WindowEvent<'a>) -> Self {
fn from(event: winit::event::WindowEvent) -> Self {
match event {
winit::event::WindowEvent::Resized(size) => Self::Resized(size),
winit::event::WindowEvent::Moved(pos) => Self::Moved(pos),
@ -244,15 +252,14 @@ impl<'a> From<winit::event::WindowEvent<'a>> for WindowEvent {
winit::event::WindowEvent::DroppedFile(path) => Self::DroppedFile(path),
winit::event::WindowEvent::HoveredFile(path) => Self::HoveredFile(path),
winit::event::WindowEvent::HoveredFileCancelled => Self::HoveredFileCancelled,
winit::event::WindowEvent::ReceivedCharacter(ch) => Self::ReceivedCharacter(ch),
winit::event::WindowEvent::Focused(focused) => Self::Focused(focused),
winit::event::WindowEvent::KeyboardInput {
device_id,
input,
event,
is_synthetic,
} => Self::KeyboardInput {
device_id,
input,
event,
is_synthetic,
},
@ -313,10 +320,10 @@ impl<'a> From<winit::event::WindowEvent<'a>> for WindowEvent {
winit::event::WindowEvent::Touch(touch) => Self::Touch(touch),
winit::event::WindowEvent::ScaleFactorChanged {
scale_factor,
new_inner_size,
inner_size_writer,
} => Self::ScaleFactorChanged {
scale_factor,
new_inner_size: *new_inner_size,
inner_size_writer,
},
winit::event::WindowEvent::ThemeChanged(theme) => Self::ThemeChanged(theme),
winit::event::WindowEvent::Occluded(occluded) => Self::Occluded(occluded),
@ -341,6 +348,9 @@ impl<'a> From<winit::event::WindowEvent<'a>> for WindowEvent {
delta,
phase,
},
winit::event::WindowEvent::ActivationTokenDone { serial, token } => {
Self::ActivationTokenDone { serial, token }
}
}
}
}

View file

@ -9,9 +9,10 @@ use std::time::{Duration, Instant};
use winit::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
use winit::error::OsError;
use winit::event::{
AxisId, DeviceId, ElementState, Ime, KeyboardInput, ModifiersState, MouseButton,
MouseScrollDelta, Touch, TouchPhase, VirtualKeyCode,
AxisId, DeviceId, ElementState, Ime, KeyEvent, Modifiers, MouseButton, MouseScrollDelta, Touch,
TouchPhase,
};
use winit::keyboard::KeyCode;
use winit::window::{Fullscreen, Icon, Theme, WindowButtons, WindowId, WindowLevel};
use crate::private::{self, WindowEvent};
@ -215,7 +216,7 @@ where
window: winit,
next_redraw_target: None,
close: false,
modifiers: ModifiersState::default(),
modifiers: Modifiers::default(),
cursor_position: None,
mouse_buttons: HashSet::default(),
keys: HashSet::default(),
@ -243,13 +244,13 @@ where
position: PhysicalPosition<i32>,
cursor_position: Option<PhysicalPosition<f64>>,
mouse_buttons: HashSet<MouseButton>,
keys: HashSet<VirtualKeyCode>,
keys: HashSet<KeyCode>,
scale: f64,
close: bool,
occluded: bool,
focused: bool,
theme: Theme,
modifiers: ModifiersState,
modifiers: Modifiers,
}
impl<AppMessage> RunningWindow<AppMessage>
@ -328,7 +329,9 @@ where
/// Sets the inner size of the window, in pixels.
pub fn set_inner_size(&self, new_size: PhysicalSize<u32>) {
self.window.set_inner_size(new_size);
// TODO not sure if this is reasonable
self.window.set_min_inner_size(Some(new_size));
self.window.set_max_inner_size(Some(new_size));
}
/// Returns the current locpositionation of the window, in pixels.
@ -376,7 +379,7 @@ where
/// Returns the current state of the keyboard modifier keys.
#[must_use]
pub const fn modifiers(&self) -> ModifiersState {
pub const fn modifiers(&self) -> Modifiers {
self.modifiers
}
@ -473,17 +476,18 @@ where
}
WindowEvent::ScaleFactorChanged {
scale_factor,
new_inner_size,
inner_size_writer: _,
} => {
// Ensure both values are updated before any behavior
// callbacks are invoked.
self.scale = scale_factor;
let inner_size_changed = self.inner_size != new_inner_size;
self.inner_size = new_inner_size;
behavior.scale_factor_changed(self);
if inner_size_changed {
behavior.resized(self);
}
// TODO not sure how to implement now
// let inner_size_changed = self.inner_size != new_inner_size;
// self.inner_size = new_inner_size;
// behavior.scale_factor_changed(self);
// if inner_size_changed {
// behavior.resized(self);
// }
}
WindowEvent::Resized(new_inner_size) => {
if self.inner_size != new_inner_size {
@ -515,20 +519,18 @@ where
}
WindowEvent::KeyboardInput {
device_id,
input,
event,
is_synthetic,
} => {
if let Some(keycode) = input.virtual_keycode {
match input.state {
ElementState::Pressed => {
self.keys.insert(keycode);
}
ElementState::Released => {
self.keys.remove(&keycode);
}
match event.state {
ElementState::Pressed => {
self.keys.insert(event.physical_key);
}
ElementState::Released => {
self.keys.remove(&event.physical_key);
}
}
behavior.keyboard_input(self, device_id, input, is_synthetic);
behavior.keyboard_input(self, device_id, event, is_synthetic);
}
WindowEvent::ModifiersChanged(modifiers) => {
self.modifiers = modifiers;
@ -607,6 +609,7 @@ where
} => {
behavior.touchpad_rotate(self, device_id, delta, phase);
}
WindowEvent::ActivationTokenDone { .. } => todo!(),
},
}
@ -622,13 +625,13 @@ where
/// Returns an iterator of the currently pressed keys.
///
/// This iterator does not guarantee any specific order.
pub fn pressed_keys(&self) -> impl Iterator<Item = VirtualKeyCode> + '_ {
pub fn pressed_keys(&self) -> impl Iterator<Item = KeyCode> + '_ {
self.keys.iter().copied()
}
/// Returns true if the given key code is currently pressed.
#[must_use]
pub fn key_pressed(&self, keycode: &VirtualKeyCode) -> bool {
pub fn key_pressed(&self, keycode: &KeyCode) -> bool {
self.keys.contains(keycode)
}
@ -900,7 +903,7 @@ where
&mut self,
window: &mut RunningWindow<AppMessage>,
device_id: DeviceId,
input: KeyboardInput,
event: KeyEvent,
is_synthetic: bool,
) {
}