mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
wayland: internal event buffer & wait for xdg configure (#255)
This commit is contained in:
parent
7dc6fcdedc
commit
1b22e39fb2
|
@ -39,6 +39,6 @@ dwmapi-sys = "0.1"
|
||||||
wayland-client = { version = "0.9.9", features = ["dlopen"] }
|
wayland-client = { version = "0.9.9", features = ["dlopen"] }
|
||||||
wayland-protocols = { version = "0.9.9", features = ["unstable_protocols"] }
|
wayland-protocols = { version = "0.9.9", features = ["unstable_protocols"] }
|
||||||
wayland-kbd = "0.9.1"
|
wayland-kbd = "0.9.1"
|
||||||
wayland-window = "0.7.0"
|
wayland-window = "0.8.0"
|
||||||
tempfile = "2.1"
|
tempfile = "2.1"
|
||||||
x11-dl = "2.8"
|
x11-dl = "2.8"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase, ModifiersState,
|
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase, ModifiersState,
|
||||||
KeyboardInput, EventsLoopClosed, ControlFlow};
|
KeyboardInput, EventsLoopClosed, ControlFlow};
|
||||||
|
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::sync::{Arc, Mutex, Weak};
|
use std::sync::{Arc, Mutex, Weak};
|
||||||
use std::sync::atomic::{self, AtomicBool};
|
use std::sync::atomic::{self, AtomicBool};
|
||||||
|
|
||||||
|
@ -31,10 +32,13 @@ pub struct EventsLoopSink {
|
||||||
unsafe impl Send for EventsLoopSink { }
|
unsafe impl Send for EventsLoopSink { }
|
||||||
|
|
||||||
impl EventsLoopSink {
|
impl EventsLoopSink {
|
||||||
pub fn new() -> EventsLoopSink {
|
pub fn new() -> (EventsLoopSink, Arc<Mutex<VecDeque<::Event>>>) {
|
||||||
EventsLoopSink {
|
let buffer = Arc::new(Mutex::new(VecDeque::new()));
|
||||||
callback: Box::new(|_| {}),
|
let buffer_clone = buffer.clone();
|
||||||
}
|
let sink = EventsLoopSink {
|
||||||
|
callback: Box::new(move |evt| { println!("TEMP: {:?}", evt); buffer.lock().unwrap().push_back(evt)}),
|
||||||
|
};
|
||||||
|
(sink, buffer_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_event(&mut self, evt: ::WindowEvent, wid: WindowId) {
|
pub fn send_event(&mut self, evt: ::WindowEvent, wid: WindowId) {
|
||||||
|
@ -70,6 +74,9 @@ pub struct EventsLoop {
|
||||||
decorated_ids: Mutex<Vec<(usize, Arc<wl_surface::WlSurface>)>>,
|
decorated_ids: Mutex<Vec<(usize, Arc<wl_surface::WlSurface>)>>,
|
||||||
// our sink, receiver of callbacks, shared with some handlers
|
// our sink, receiver of callbacks, shared with some handlers
|
||||||
sink: Arc<Mutex<EventsLoopSink>>,
|
sink: Arc<Mutex<EventsLoopSink>>,
|
||||||
|
// a buffer in which events that were dispatched internally are stored
|
||||||
|
// until the user next dispatches events
|
||||||
|
buffer: Arc<Mutex<VecDeque<::Event>>>,
|
||||||
// trigger cleanup of the dead surfaces
|
// trigger cleanup of the dead surfaces
|
||||||
cleanup_needed: Arc<AtomicBool>,
|
cleanup_needed: Arc<AtomicBool>,
|
||||||
// Whether or not there is a pending `Awakened` event to be emitted.
|
// Whether or not there is a pending `Awakened` event to be emitted.
|
||||||
|
@ -109,13 +116,15 @@ impl EventsLoopProxy {
|
||||||
impl EventsLoop {
|
impl EventsLoop {
|
||||||
pub fn new(ctxt: Arc<WaylandContext>) -> EventsLoop {
|
pub fn new(ctxt: Arc<WaylandContext>) -> EventsLoop {
|
||||||
let mut evq = ctxt.display.create_event_queue();
|
let mut evq = ctxt.display.create_event_queue();
|
||||||
let sink = Arc::new(Mutex::new(EventsLoopSink::new()));
|
let (sink, buffer) = EventsLoopSink::new();
|
||||||
|
let sink = Arc::new(Mutex::new(sink));
|
||||||
let hid = evq.add_handler_with_init(InputHandler::new(&ctxt, sink.clone()));
|
let hid = evq.add_handler_with_init(InputHandler::new(&ctxt, sink.clone()));
|
||||||
EventsLoop {
|
EventsLoop {
|
||||||
ctxt: ctxt,
|
ctxt: ctxt,
|
||||||
evq: Arc::new(Mutex::new(evq)),
|
evq: Arc::new(Mutex::new(evq)),
|
||||||
decorated_ids: Mutex::new(Vec::new()),
|
decorated_ids: Mutex::new(Vec::new()),
|
||||||
sink: sink,
|
sink: sink,
|
||||||
|
buffer: buffer,
|
||||||
pending_wakeup: Arc::new(AtomicBool::new(false)),
|
pending_wakeup: Arc::new(AtomicBool::new(false)),
|
||||||
cleanup_needed: Arc::new(AtomicBool::new(false)),
|
cleanup_needed: Arc::new(AtomicBool::new(false)),
|
||||||
hid: hid
|
hid: hid
|
||||||
|
@ -135,6 +144,10 @@ impl EventsLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_window(&self, decorated_id: usize, surface: Arc<wl_surface::WlSurface>) {
|
pub fn register_window(&self, decorated_id: usize, surface: Arc<wl_surface::WlSurface>) {
|
||||||
|
self.buffer.lock().unwrap().push_back(::Event::WindowEvent {
|
||||||
|
window_id: ::WindowId(::platform::WindowId::Wayland(make_wid(&surface))),
|
||||||
|
event: ::WindowEvent::Refresh
|
||||||
|
});
|
||||||
self.decorated_ids.lock().unwrap().push((decorated_id, surface.clone()));
|
self.decorated_ids.lock().unwrap().push((decorated_id, surface.clone()));
|
||||||
let mut guard = self.evq.lock().unwrap();
|
let mut guard = self.evq.lock().unwrap();
|
||||||
let mut state = guard.state();
|
let mut state = guard.state();
|
||||||
|
@ -180,7 +193,14 @@ impl EventsLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F>(&mut self, callback: F)
|
fn empty_buffer<F>(&self, callback: &mut F) where F: FnMut(::Event) {
|
||||||
|
let mut guard = self.buffer.lock().unwrap();
|
||||||
|
for evt in guard.drain(..) {
|
||||||
|
callback(evt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_events<F>(&mut self, mut callback: F)
|
||||||
where F: FnMut(::Event)
|
where F: FnMut(::Event)
|
||||||
{
|
{
|
||||||
// send pending requests to the server...
|
// send pending requests to the server...
|
||||||
|
@ -189,6 +209,9 @@ impl EventsLoop {
|
||||||
// first of all, get exclusive access to this event queue
|
// first of all, get exclusive access to this event queue
|
||||||
let mut evq_guard = self.evq.lock().unwrap();
|
let mut evq_guard = self.evq.lock().unwrap();
|
||||||
|
|
||||||
|
// dispatch pre-buffered events
|
||||||
|
self.empty_buffer(&mut callback);
|
||||||
|
|
||||||
// read some events from the socket if some are waiting & queue is empty
|
// read some events from the socket if some are waiting & queue is empty
|
||||||
if let Some(guard) = evq_guard.prepare_read() {
|
if let Some(guard) = evq_guard.prepare_read() {
|
||||||
guard.read_events().expect("Wayland connection unexpectedly lost");
|
guard.read_events().expect("Wayland connection unexpectedly lost");
|
||||||
|
@ -235,10 +258,13 @@ impl EventsLoop {
|
||||||
|
|
||||||
// Check for control flow by wrapping the callback.
|
// Check for control flow by wrapping the callback.
|
||||||
let control_flow = ::std::cell::Cell::new(ControlFlow::Continue);
|
let control_flow = ::std::cell::Cell::new(ControlFlow::Continue);
|
||||||
let callback = |event| if let ControlFlow::Break = callback(event) {
|
let mut callback = |event| if let ControlFlow::Break = callback(event) {
|
||||||
control_flow.set(ControlFlow::Break);
|
control_flow.set(ControlFlow::Break);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// dispatch pre-buffered events
|
||||||
|
self.empty_buffer(&mut callback);
|
||||||
|
|
||||||
// set the callback into the sink
|
// set the callback into the sink
|
||||||
// we extend the lifetime of the closure to 'static to be able to put it in
|
// we extend the lifetime of the closure to 'static to be able to put it in
|
||||||
// the sink, but we'll explicitly drop it at the end of this function, so it's fine
|
// the sink, but we'll explicitly drop it at the end of this function, so it's fine
|
||||||
|
|
|
@ -66,6 +66,9 @@ impl Window {
|
||||||
// Finally, set the decorations size
|
// Finally, set the decorations size
|
||||||
decorated.resize(width as i32, height as i32);
|
decorated.resize(width as i32, height as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evq_guard.sync_roundtrip().unwrap();
|
||||||
|
|
||||||
decorated_id
|
decorated_id
|
||||||
};
|
};
|
||||||
let me = Window {
|
let me = Window {
|
||||||
|
@ -204,11 +207,12 @@ impl DecoratedHandler {
|
||||||
impl wayland_window::Handler for DecoratedHandler {
|
impl wayland_window::Handler for DecoratedHandler {
|
||||||
fn configure(&mut self,
|
fn configure(&mut self,
|
||||||
_: &mut EventQueueHandle,
|
_: &mut EventQueueHandle,
|
||||||
_: wayland_window::Configure,
|
_cfg: wayland_window::Configure,
|
||||||
width: i32, height: i32)
|
newsize: Option<(i32, i32)>)
|
||||||
{
|
{
|
||||||
use std::cmp::max;
|
if let Some((w, h)) = newsize {
|
||||||
self.newsize = Some((max(width,1) as u32, max(height,1) as u32));
|
self.newsize = Some((w as u32, h as u32));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&mut self, _: &mut EventQueueHandle) {
|
fn close(&mut self, _: &mut EventQueueHandle) {
|
||||||
|
|
Loading…
Reference in a new issue