diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index fd820225..6e12ffe1 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -47,7 +47,7 @@ pub enum Window2 { #[doc(hidden)] X(x11::Window2), #[doc(hidden)] - Wayland(wayland::Window2) + Wayland(wayland::Window) } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -130,7 +130,7 @@ impl Window2 { match *UNIX_BACKEND { UnixBackend::Wayland(ref ctxt) => { if let EventsLoop::Wayland(ref evlp) = *events_loop { - wayland::Window2::new(evlp, ctxt.clone(), window).map(Window2::Wayland) + wayland::Window::new(evlp, ctxt.clone(), window).map(Window2::Wayland) } else { // It is not possible to instanciate an EventsLoop not matching its backend unreachable!() diff --git a/src/platform/linux/wayland/event_loop.rs b/src/platform/linux/wayland/event_loop.rs index ea86dd58..efc9411d 100644 --- a/src/platform/linux/wayland/event_loop.rs +++ b/src/platform/linux/wayland/event_loop.rs @@ -14,6 +14,15 @@ use super::wayland_window::DecoratedSurface; use super::wayland_kbd::MappedKeyboard; use super::keyboard::KbdHandler; +/// This struct is used as a holder for the callback +/// during the dispatching of events. +/// +/// The proper ay to use it is: +/// - set a callback in it (and retrieve the noop one it contains) +/// - dispatch the EventQueue +/// - put back the noop callback in it +/// +/// Failure to do so is unsafeā„¢ pub struct EventsLoopSink { callback: Box } @@ -50,11 +59,17 @@ impl EventsLoopSink { } pub struct EventsLoop { + // the global wayland context ctxt: Arc, + // our EventQueue evq: Arc>, + // ids of the DecoratedHandlers of the surfaces we know decorated_ids: Mutex)>>, + // our sink, receiver of callbacks, shared with some handlers sink: Arc>, + // trigger interruption of the run interrupted: AtomicBool, + // trigger cleanup of the dead surfaces cleanup_needed: Arc, hid: usize } @@ -75,6 +90,7 @@ impl EventsLoop { } } + // some internals that Window needs access to pub fn get_window_init(&self) -> (Arc>, Arc) { (self.evq.clone(), self.cleanup_needed.clone()) } @@ -183,14 +199,14 @@ impl EventsLoop { |cb| Self::process_resize(&mut evq_guard, &ids_guard, cb) ); self.ctxt.flush(); + + if self.cleanup_needed.swap(false, ::std::sync::atomic::Ordering::Relaxed) { + self.prune_dead_windows() + } } // replace the old noop callback unsafe { self.sink.lock().unwrap().set_callback(old_cb) }; - - if self.cleanup_needed.swap(false, ::std::sync::atomic::Ordering::Relaxed) { - self.prune_dead_windows() - } } } diff --git a/src/platform/linux/wayland/mod.rs b/src/platform/linux/wayland/mod.rs index 1f5a6411..f2ae3477 100644 --- a/src/platform/linux/wayland/mod.rs +++ b/src/platform/linux/wayland/mod.rs @@ -1,6 +1,6 @@ #![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))] -pub use self::window::{Window as Window2, WindowId}; +pub use self::window::{Window, WindowId}; pub use self::event_loop::EventsLoop; pub use self::context::{WaylandContext, MonitorId, get_available_monitors, get_primary_monitor}; diff --git a/src/platform/linux/wayland/window.rs b/src/platform/linux/wayland/window.rs index 30d192b4..6486c710 100644 --- a/src/platform/linux/wayland/window.rs +++ b/src/platform/linux/wayland/window.rs @@ -12,11 +12,17 @@ use super::wayland_window; use super::wayland_window::DecoratedSurface; pub struct Window { + // the global wayland context ctxt: Arc, + // the EventQueue of our EventsLoop evq: Arc>, + // signal to advertize the EventsLoop when we are destroyed cleanup_signal: Arc, + // our wayland surface surface: Arc, + // our current inner dimensions size: Mutex<(u32, u32)>, + // the id of our DecoratedHandler in the EventQueue decorated_id: usize } @@ -41,10 +47,12 @@ impl Window { let mut evq_guard = evq.lock().unwrap(); let decorated_id = evq_guard.add_handler_with_init(decorated); { + // initialize the DecoratedHandler let mut state = evq_guard.state(); let decorated = state.get_mut_handler::>(decorated_id); *(decorated.handler()) = Some(DecoratedHandler::new()); + // set fullscreen if necessary if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = attributes.monitor { ctxt.with_output(monitor_id.clone(), |output| { decorated.set_fullscreen( @@ -70,6 +78,7 @@ impl Window { decorated_id: decorated_id }; + // register ourselves to the EventsLoop evlp.register_window(me.decorated_id, me.surface.clone()); Ok(me)