Skip to content

Commit

Permalink
Implement changes to RedrawRequested event (rust-windowing#1062)
Browse files Browse the repository at this point in the history
* Implement changes to `RedrawRequested` event

Implements the changes described in rust-windowing#1041 for the X11 platform and for
platform-independent public-facing code.

* Fix `request_redraw` example

* Fix examples in lib docs

* Only issue `RedrawRequested` on final `Expose` event
  • Loading branch information
murarth authored and hecrj committed Aug 31, 2019
1 parent 7b707e7 commit 7f1d244
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 37 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
- On iOS, add touch pressure information for touch events.
- Implement `raw_window_handle::HasRawWindowHandle` for `Window` type on all supported platforms.
- On macOS, fix the signature of `-[NSView drawRect:]`.
- Changes to the `RedrawRequested` event (#1041):
- `RedrawRequested` has been moved from `WindowEvent` to `Event`.
- `EventsCleared` has been renamed to `MainEventsCleared`.
- `RedrawRequested` is now issued only after `MainEventsCleared`.
- `RedrawEventsCleared` is issued after each set of `RedrawRequested` events.

# 0.20.0 Alpha 2 (2019-07-09)

Expand Down
7 changes: 2 additions & 5 deletions examples/request_redraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@ fn main() {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
Event::EventsCleared => {
Event::MainEventsCleared => {
window.request_redraw();
*control_flow = ControlFlow::WaitUntil(Instant::now() + Duration::new(1, 0))
}
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
Event::RedrawRequested(_) => {
println!("{:?}", event);
}
_ => (),
Expand Down
26 changes: 19 additions & 7 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,22 @@ pub enum Event<T> {
UserEvent(T),
/// Emitted when new events arrive from the OS to be processed.
NewEvents(StartCause),
/// Emitted when all of the event loop's events have been processed and control flow is about
/// to be taken away from the program.
EventsCleared,
/// Emitted when all events (except for `RedrawRequested`) have been reported.
///
/// This event is followed by zero or more instances of `RedrawRequested`
/// and, finally, `RedrawEventsCleared`.
MainEventsCleared,

/// The OS or application has requested that a window be redrawn.
///
/// Emitted only after `MainEventsCleared`.
RedrawRequested(WindowId),

/// Emitted after any `RedrawRequested` events.
///
/// If there are no `RedrawRequested` events, it is reported immediately after
/// `MainEventsCleared`.
RedrawEventsCleared,

/// Emitted when the event loop is being shut down. This is irreversable - if this event is
/// emitted, it is guaranteed to be the last event emitted.
Expand All @@ -52,7 +65,9 @@ impl<T> Event<T> {
WindowEvent { window_id, event } => Ok(WindowEvent { window_id, event }),
DeviceEvent { device_id, event } => Ok(DeviceEvent { device_id, event }),
NewEvents(cause) => Ok(NewEvents(cause)),
EventsCleared => Ok(EventsCleared),
MainEventsCleared => Ok(MainEventsCleared),
RedrawRequested(wid) => Ok(RedrawRequested(wid)),
RedrawEventsCleared => Ok(RedrawEventsCleared),
LoopDestroyed => Ok(LoopDestroyed),
Suspended => Ok(Suspended),
Resumed => Ok(Resumed),
Expand Down Expand Up @@ -184,9 +199,6 @@ pub enum WindowEvent {
value: f64,
},

/// The OS or application has requested that the window be redrawn.
RedrawRequested,

/// Touch event has been received
Touch(Touch),

Expand Down
9 changes: 3 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,16 @@
//!
//! event_loop.run(move |event, _, control_flow| {
//! match event {
//! Event::EventsCleared => {
//! Event::MainEventsCleared => {
//! // Application update code.
//!
//! // Queue a RedrawRequested event.
//! window.request_redraw();
//! },
//! Event::WindowEvent {
//! event: WindowEvent::RedrawRequested,
//! ..
//! } => {
//! Event::RedrawRequested(_) => {
//! // Redraw the application.
//! //
//! // It's preferrable to render in this event rather than in EventsCleared, since
//! // It's preferrable to render in this event rather than in MainEventsCleared, since
//! // rendering in here allows the program to gracefully handle redraws requested
//! // by the OS.
//! },
Expand Down
5 changes: 3 additions & 2 deletions src/platform_impl/linux/wayland/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ impl<T: 'static> EventLoop<T> {
// send Events cleared
{
sticky_exit_callback(
crate::event::Event::EventsCleared,
crate::event::Event::MainEventsCleared,
&self.window_target,
&mut control_flow,
&mut callback,
Expand Down Expand Up @@ -450,7 +450,8 @@ impl<T> EventLoop<T> {
);
}
if refresh {
sink.send_window_event(crate::event::WindowEvent::RedrawRequested, wid);
unimplemented!()
//sink.send_window_event(crate::event::WindowEvent::RedrawRequested, wid);
}
if closed {
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
Expand Down
13 changes: 7 additions & 6 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,13 +482,14 @@ impl<T: 'static> EventProcessor<T> {
ffi::Expose => {
let xev: &ffi::XExposeEvent = xev.as_ref();

let window = xev.window;
let window_id = mkwid(window);
// Multiple Expose events may be received for subareas of a window.
// We issue `RedrawRequested` only for the last event of such a series.
if xev.count == 0 {
let window = xev.window;
let window_id = mkwid(window);

callback(Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
});
callback(Event::RedrawRequested(window_id));
}
}

ffi::KeyPress | ffi::KeyRelease => {
Expand Down
39 changes: 28 additions & 11 deletions src/platform_impl/linux/x11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use self::{
};
use crate::{
error::OsError as RootOsError,
event::{Event, WindowEvent},
event::Event,
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
platform_impl::{platform::sticky_exit_callback, PlatformSpecificWindowBuilderAttributes},
window::WindowAttributes,
Expand Down Expand Up @@ -143,6 +143,8 @@ impl<T: 'static> EventLoop<T> {

xconn.update_cached_wm_info(root);

let pending_redraws: Arc<Mutex<HashSet<WindowId>>> = Default::default();

let target = Rc::new(RootELW {
p: super::EventLoopWindowTarget::X(EventLoopWindowTarget {
ime,
Expand All @@ -153,7 +155,7 @@ impl<T: 'static> EventLoop<T> {
xconn,
wm_delete_window,
net_wm_ping,
pending_redraws: Default::default(),
pending_redraws: pending_redraws.clone(),
}),
_marker: ::std::marker::PhantomData,
});
Expand Down Expand Up @@ -212,7 +214,9 @@ impl<T: 'static> EventLoop<T> {
if evt.readiness.is_readable() {
let mut processor = processor.borrow_mut();
let mut pending_events = pending_events.borrow_mut();
drain_events(&mut processor, &mut pending_events);
let mut pending_redraws = pending_redraws.lock().unwrap();

drain_events(&mut processor, &mut pending_events, &mut pending_redraws);
}
}
})
Expand Down Expand Up @@ -276,27 +280,33 @@ impl<T: 'static> EventLoop<T> {
);
}
}
// send MainEventsCleared
{
sticky_exit_callback(
crate::event::Event::MainEventsCleared,
&self.target,
&mut control_flow,
&mut callback,
);
}
// Empty the redraw requests
{
// Release the lock to prevent deadlock
let windows: Vec<_> = wt.pending_redraws.lock().unwrap().drain().collect();

for wid in windows {
sticky_exit_callback(
Event::WindowEvent {
window_id: crate::window::WindowId(super::WindowId::X(wid)),
event: WindowEvent::RedrawRequested,
},
Event::RedrawRequested(crate::window::WindowId(super::WindowId::X(wid))),
&self.target,
&mut control_flow,
&mut callback,
);
}
}
// send Events cleared
// send RedrawEventsCleared
{
sticky_exit_callback(
crate::event::Event::EventsCleared,
crate::event::Event::RedrawEventsCleared,
&self.target,
&mut control_flow,
&mut callback,
Expand Down Expand Up @@ -386,17 +396,24 @@ impl<T: 'static> EventLoop<T> {
fn drain_events(&self) {
let mut processor = self.event_processor.borrow_mut();
let mut pending_events = self.pending_events.borrow_mut();
let wt = get_xtarget(&self.target);
let mut pending_redraws = wt.pending_redraws.lock().unwrap();

drain_events(&mut processor, &mut pending_events);
drain_events(&mut processor, &mut pending_events, &mut pending_redraws);
}
}

fn drain_events<T: 'static>(
processor: &mut EventProcessor<T>,
pending_events: &mut VecDeque<Event<T>>,
pending_redraws: &mut HashSet<WindowId>,
) {
let mut callback = |event| {
pending_events.push_back(event);
if let Event::RedrawRequested(crate::window::WindowId(super::WindowId::X(wid))) = event {
pending_redraws.insert(wid);
} else {
pending_events.push_back(event);
}
};

// process all pending events
Expand Down

0 comments on commit 7f1d244

Please sign in to comment.