mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-26 22:53:15 -04:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5609729cc | ||
|
|
1f24a09570 | ||
|
|
a8e777a5df | ||
|
|
0bc58f695b | ||
|
|
28023d9f5b | ||
|
|
c2aed1979d | ||
|
|
7e04273719 | ||
|
|
0683bdcd42 | ||
|
|
29ab0bb629 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,4 +1,12 @@
|
||||
# 0.22.0 (2020-03-07)
|
||||
# Unreleased
|
||||
|
||||
# 0.22.1 (2020-04-16)
|
||||
|
||||
- On X11, fix `ResumeTimeReached` being fired too early.
|
||||
- On Web, replaced zero timeout for `ControlFlow::Poll` with `requestAnimationFrame`
|
||||
- On Web, fix a possible panic during event handling
|
||||
|
||||
# 0.22.0 (2020-03-09)
|
||||
|
||||
- On Windows, fix minor timing issue in wait_until_time_or_msg
|
||||
- On Windows, rework handling of request_redraw() to address panics.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "winit"
|
||||
version = "0.22.0"
|
||||
version = "0.22.1"
|
||||
authors = ["The winit contributors", "Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||
description = "Cross-platform window creation library."
|
||||
edition = "2018"
|
||||
@@ -78,7 +78,7 @@ wayland-client = { version = "0.23.0", features = [ "dlopen", "egl", "cursor", "
|
||||
mio = "0.6"
|
||||
mio-extras = "2.0"
|
||||
smithay-client-toolkit = "^0.6.6"
|
||||
x11-dl = "2.18.3"
|
||||
x11-dl = "2.18.5"
|
||||
percent-encoding = "2.0"
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "windows"))'.dependencies.parking_lot]
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
[](https://crates.io/crates/winit)
|
||||
[](https://docs.rs/winit)
|
||||
[](https://travis-ci.org/rust-windowing/winit)
|
||||
[](https://ci.appveyor.com/project/Osspial/winit/branch/master)
|
||||
[](https://github.com/rust-windowing/winit/actions)
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
winit = "0.22.0"
|
||||
winit = "0.22.1"
|
||||
```
|
||||
|
||||
## [Documentation](https://docs.rs/winit)
|
||||
|
||||
@@ -72,7 +72,8 @@ impl<T> fmt::Debug for EventLoopWindowTarget<T> {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ControlFlow {
|
||||
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
|
||||
/// whether or not new events are available to process.
|
||||
/// whether or not new events are available to process. For web, events are sent when
|
||||
/// `requestAnimationFrame` fires.
|
||||
Poll,
|
||||
/// When the current loop iteration finishes, suspend the thread until another event arrives.
|
||||
Wait,
|
||||
|
||||
@@ -63,7 +63,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||
|
||||
lazy_static! {
|
||||
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> =
|
||||
{ Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)) };
|
||||
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new));
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@@ -268,14 +268,16 @@ impl<T: 'static> EventLoop<T> {
|
||||
{
|
||||
let mut control_flow = ControlFlow::default();
|
||||
let mut events = Events::with_capacity(8);
|
||||
|
||||
callback(
|
||||
crate::event::Event::NewEvents(crate::event::StartCause::Init),
|
||||
&self.target,
|
||||
&mut control_flow,
|
||||
);
|
||||
let mut cause = StartCause::Init;
|
||||
|
||||
loop {
|
||||
sticky_exit_callback(
|
||||
crate::event::Event::NewEvents(cause),
|
||||
&self.target,
|
||||
&mut control_flow,
|
||||
&mut callback,
|
||||
);
|
||||
|
||||
// Process all pending events
|
||||
self.drain_events(&mut callback, &mut control_flow);
|
||||
|
||||
@@ -326,7 +328,7 @@ impl<T: 'static> EventLoop<T> {
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
let (mut cause, deadline, timeout);
|
||||
let (deadline, timeout);
|
||||
|
||||
match control_flow {
|
||||
ControlFlow::Exit => break,
|
||||
@@ -357,38 +359,20 @@ impl<T: 'static> EventLoop<T> {
|
||||
}
|
||||
}
|
||||
|
||||
if self.event_processor.poll() {
|
||||
// If the XConnection already contains buffered events, we don't
|
||||
// need to wait for data on the socket.
|
||||
// However, we still need to check for user events.
|
||||
self.poll
|
||||
.poll(&mut events, Some(Duration::from_millis(0)))
|
||||
.unwrap();
|
||||
events.clear();
|
||||
|
||||
callback(
|
||||
crate::event::Event::NewEvents(cause),
|
||||
&self.target,
|
||||
&mut control_flow,
|
||||
);
|
||||
} else {
|
||||
// If the XConnection already contains buffered events, we don't
|
||||
// need to wait for data on the socket.
|
||||
if !self.event_processor.poll() {
|
||||
self.poll.poll(&mut events, timeout).unwrap();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
let wait_cancelled = deadline.map_or(false, |deadline| Instant::now() < deadline);
|
||||
let wait_cancelled = deadline.map_or(false, |deadline| Instant::now() < deadline);
|
||||
|
||||
if wait_cancelled {
|
||||
cause = StartCause::WaitCancelled {
|
||||
start,
|
||||
requested_resume: deadline,
|
||||
};
|
||||
}
|
||||
|
||||
callback(
|
||||
crate::event::Event::NewEvents(cause),
|
||||
&self.target,
|
||||
&mut control_flow,
|
||||
);
|
||||
if wait_cancelled {
|
||||
cause = StartCause::WaitCancelled {
|
||||
start,
|
||||
requested_resume: deadline,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,6 @@ impl<T: 'static> Shared<T> {
|
||||
// It should only ever be called from send_event
|
||||
fn handle_event(&self, event: Event<'static, T>, control: &mut root::ControlFlow) {
|
||||
let is_closed = self.is_closed();
|
||||
|
||||
match *self.0.runner.borrow_mut() {
|
||||
Some(ref mut runner) => {
|
||||
// An event is being processed, so the runner should be marked busy
|
||||
@@ -227,7 +226,9 @@ impl<T: 'static> Shared<T> {
|
||||
// If the runner doesn't exist and this method recurses, it will recurse infinitely
|
||||
if !is_closed && self.0.runner.borrow().is_some() {
|
||||
// Take an event out of the queue and handle it
|
||||
if let Some(event) = self.0.events.borrow_mut().pop_front() {
|
||||
// Make sure not to let the borrow_mut live during the next handle_event
|
||||
let event = { self.0.events.borrow_mut().pop_front() };
|
||||
if let Some(event) = event {
|
||||
self.handle_event(event, control);
|
||||
}
|
||||
}
|
||||
@@ -240,7 +241,7 @@ impl<T: 'static> Shared<T> {
|
||||
root::ControlFlow::Poll => {
|
||||
let cloned = self.clone();
|
||||
State::Poll {
|
||||
timeout: backend::Timeout::new(move || cloned.poll(), Duration::from_millis(0)),
|
||||
request: backend::AnimationFrameRequest::new(move || cloned.poll()),
|
||||
}
|
||||
}
|
||||
root::ControlFlow::Wait => State::Wait {
|
||||
|
||||
@@ -15,7 +15,7 @@ pub enum State {
|
||||
start: Instant,
|
||||
},
|
||||
Poll {
|
||||
timeout: backend::Timeout,
|
||||
request: backend::AnimationFrameRequest,
|
||||
},
|
||||
Exit,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ mod event;
|
||||
mod timeout;
|
||||
|
||||
pub use self::canvas::Canvas;
|
||||
pub use self::timeout::Timeout;
|
||||
pub use self::timeout::{AnimationFrameRequest, Timeout};
|
||||
|
||||
use crate::dpi::{LogicalSize, Size};
|
||||
use crate::platform::web::WindowExtStdweb;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use stdweb::web::{window, IWindowOrWorker, TimeoutHandle};
|
||||
use stdweb::web::{window, IWindowOrWorker, RequestAnimationFrameHandle, TimeoutHandle};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Timeout {
|
||||
@@ -23,3 +25,39 @@ impl Drop for Timeout {
|
||||
handle.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnimationFrameRequest {
|
||||
handle: Option<RequestAnimationFrameHandle>,
|
||||
// track callback state, because `cancelAnimationFrame` is slow
|
||||
fired: Rc<Cell<bool>>,
|
||||
}
|
||||
|
||||
impl AnimationFrameRequest {
|
||||
pub fn new<F>(mut f: F) -> AnimationFrameRequest
|
||||
where
|
||||
F: 'static + FnMut(),
|
||||
{
|
||||
let fired = Rc::new(Cell::new(false));
|
||||
let c_fired = fired.clone();
|
||||
let handle = window().request_animation_frame(move |_| {
|
||||
(*c_fired).set(true);
|
||||
f();
|
||||
});
|
||||
|
||||
AnimationFrameRequest {
|
||||
handle: Some(handle),
|
||||
fired,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AnimationFrameRequest {
|
||||
fn drop(&mut self) {
|
||||
if !(*self.fired).get() {
|
||||
if let Some(handle) = self.handle.take() {
|
||||
handle.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ mod event;
|
||||
mod timeout;
|
||||
|
||||
pub use self::canvas::Canvas;
|
||||
pub use self::timeout::Timeout;
|
||||
pub use self::timeout::{AnimationFrameRequest, Timeout};
|
||||
|
||||
use crate::dpi::{LogicalSize, Size};
|
||||
use crate::platform::web::WindowExtWebSys;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen::closure::Closure;
|
||||
use wasm_bindgen::JsCast;
|
||||
@@ -38,3 +40,48 @@ impl Drop for Timeout {
|
||||
window.clear_timeout_with_handle(self.handle);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnimationFrameRequest {
|
||||
handle: i32,
|
||||
// track callback state, because `cancelAnimationFrame` is slow
|
||||
fired: Rc<Cell<bool>>,
|
||||
_closure: Closure<dyn FnMut()>,
|
||||
}
|
||||
|
||||
impl AnimationFrameRequest {
|
||||
pub fn new<F>(mut f: F) -> AnimationFrameRequest
|
||||
where
|
||||
F: 'static + FnMut(),
|
||||
{
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
|
||||
let fired = Rc::new(Cell::new(false));
|
||||
let c_fired = fired.clone();
|
||||
let closure = Closure::wrap(Box::new(move || {
|
||||
(*c_fired).set(true);
|
||||
f();
|
||||
}) as Box<dyn FnMut()>);
|
||||
|
||||
let handle = window
|
||||
.request_animation_frame(&closure.as_ref().unchecked_ref())
|
||||
.expect("Failed to request animation frame");
|
||||
|
||||
AnimationFrameRequest {
|
||||
handle,
|
||||
fired,
|
||||
_closure: closure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AnimationFrameRequest {
|
||||
fn drop(&mut self) {
|
||||
if !(*self.fired).get() {
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
window
|
||||
.cancel_animation_frame(self.handle)
|
||||
.expect("Failed to cancel animation frame");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user