diff --git a/Cargo.toml b/Cargo.toml index 7990dcb7..d9aebc4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "i686-unknown-linux [features] default = ["x11", "wayland"] -x11 = ["x11-dl", "mio", "mio-misc", "percent-encoding", "parking_lot"] +x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"] wayland = ["wayland-client", "wayland-protocols", "sctk"] [dependencies] @@ -87,7 +87,6 @@ wayland-client = { version = "0.29", features = [ "dlopen"], optional = true } wayland-protocols = { version = "0.29", features = [ "staging_protocols"], optional = true } sctk = { package = "smithay-client-toolkit", version = "0.15.0", optional = true } mio = { version = "0.7", features = ["os-ext"], optional = true } -mio-misc = { version = "1.0", optional = true } x11-dl = { version = "2.18.5", optional = true } percent-encoding = { version = "2.0", optional = true } parking_lot = { version = "0.11.0", optional = true } diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index a784e8b2..7f462ab6 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -32,7 +32,7 @@ use std::{ ptr, rc::Rc, slice, - sync::mpsc::Receiver, + sync::mpsc::{Receiver, Sender}, sync::{mpsc, Arc, Weak}, time::{Duration, Instant}, }; @@ -41,12 +41,6 @@ use libc::{self, setlocale, LC_CTYPE}; use mio::{unix::SourceFd, Events, Interest, Poll, Token, Waker}; -use mio_misc::{ - channel::{channel, SendError, Sender}, - queue::NotificationQueue, - NotificationId, -}; - use self::{ dnd::{Dnd, DndState}, event_processor::EventProcessor, @@ -64,6 +58,11 @@ use crate::{ const X_TOKEN: Token = Token(0); const USER_REDRAW_TOKEN: Token = Token(1); +struct WakeSender { + sender: Sender, + waker: Arc, +} + pub struct EventLoopWindowTarget { xconn: Arc, wm_delete_window: ffi::Atom, @@ -72,27 +71,30 @@ pub struct EventLoopWindowTarget { root: ffi::Window, ime: RefCell, windows: RefCell>>, - redraw_sender: Sender, + redraw_sender: WakeSender, _marker: ::std::marker::PhantomData, } pub struct EventLoop { poll: Poll, + waker: Arc, event_processor: EventProcessor, redraw_channel: Receiver, - user_channel: Receiver, + user_channel: Receiver, //waker.wake needs to be called whenever something gets sent user_sender: Sender, target: Rc>, } pub struct EventLoopProxy { user_sender: Sender, + waker: Arc, } impl Clone for EventLoopProxy { fn clone(&self) -> Self { EventLoopProxy { user_sender: self.user_sender.clone(), + waker: self.waker.clone(), } } } @@ -185,15 +187,13 @@ impl EventLoop { let poll = Poll::new().unwrap(); let waker = Arc::new(Waker::new(poll.registry(), USER_REDRAW_TOKEN).unwrap()); - let queue = Arc::new(NotificationQueue::new(waker)); poll.registry() .register(&mut SourceFd(&xconn.x11_fd), X_TOKEN, Interest::READABLE) .unwrap(); - let (user_sender, user_channel) = channel(queue.clone(), NotificationId::gen_next()); - - let (redraw_sender, redraw_channel) = channel(queue, NotificationId::gen_next()); + let (user_sender, user_channel) = std::sync::mpsc::channel(); + let (redraw_sender, redraw_channel) = std::sync::mpsc::channel(); let target = Rc::new(RootELW { p: super::EventLoopWindowTarget::X(EventLoopWindowTarget { @@ -205,7 +205,10 @@ impl EventLoop { xconn, wm_delete_window, net_wm_ping, - redraw_sender, + redraw_sender: WakeSender { + sender: redraw_sender, // not used again so no clone + waker: waker.clone(), + }, }), _marker: ::std::marker::PhantomData, }); @@ -233,21 +236,21 @@ impl EventLoop { event_processor.init_device(ffi::XIAllDevices); - let result = EventLoop { + EventLoop { poll, + waker, + event_processor, redraw_channel, user_channel, user_sender, - event_processor, target, - }; - - result + } } pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { user_sender: self.user_sender.clone(), + waker: self.waker.clone(), } } @@ -392,7 +395,6 @@ impl EventLoop { { let target = &self.target; let mut xev = MaybeUninit::uninit(); - let wt = get_xtarget(&self.target); while unsafe { self.event_processor.poll_one_event(xev.as_mut_ptr()) } { @@ -407,7 +409,8 @@ impl EventLoop { super::WindowId::X(wid), )) = event { - wt.redraw_sender.send(wid).unwrap(); + wt.redraw_sender.sender.send(wid).unwrap(); + wt.redraw_sender.waker.wake().unwrap(); } else { callback(event, window_target, control_flow); } @@ -436,13 +439,10 @@ impl EventLoopWindowTarget { impl EventLoopProxy { pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { - self.user_sender.send(event).map_err(|e| { - EventLoopClosed(if let SendError::Disconnected(x) = e { - x - } else { - unreachable!() - }) - }) + self.user_sender + .send(event) + .map_err(|e| EventLoopClosed(e.0)) + .map(|_| self.waker.wake().unwrap()) } } @@ -520,7 +520,7 @@ impl Window { attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { - let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?); + let window = Arc::new(UnownedWindow::new(event_loop, attribs, pl_attribs)?); event_loop .windows .borrow_mut() diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index ea8bc616..3648c225 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -11,7 +11,6 @@ use std::{ use x11_dl::xlib::TrueColor; use libc; -use mio_misc::channel::Sender; use parking_lot::Mutex; use crate::{ @@ -26,7 +25,9 @@ use crate::{ window::{CursorIcon, Fullscreen, Icon, UserAttentionType, WindowAttributes}, }; -use super::{ffi, util, EventLoopWindowTarget, ImeSender, WindowId, XConnection, XError}; +use super::{ + ffi, util, EventLoopWindowTarget, ImeSender, WakeSender, WindowId, XConnection, XError, +}; #[derive(Debug)] pub struct SharedState { @@ -104,7 +105,7 @@ pub struct UnownedWindow { cursor_visible: Mutex, ime_sender: Mutex, pub shared_state: Mutex, - redraw_sender: Sender, + redraw_sender: WakeSender, } impl UnownedWindow { @@ -274,7 +275,10 @@ impl UnownedWindow { cursor_visible: Mutex::new(true), ime_sender: Mutex::new(event_loop.ime_sender.clone()), shared_state: SharedState::new(guessed_monitor, window_attrs.visible), - redraw_sender: event_loop.redraw_sender.clone(), + redraw_sender: WakeSender { + waker: event_loop.redraw_sender.waker.clone(), + sender: event_loop.redraw_sender.sender.clone(), + }, }; // Title must be set before mapping. Some tiling window managers (i.e. i3) use the window @@ -1102,7 +1106,7 @@ impl UnownedWindow { fn update_normal_hints(&self, callback: F) -> Result<(), XError> where - F: FnOnce(&mut util::NormalHints<'_>) -> (), + F: FnOnce(&mut util::NormalHints<'_>), { let mut normal_hints = self.xconn.get_normal_hints(self.xwindow)?; callback(&mut normal_hints); @@ -1183,7 +1187,7 @@ impl UnownedWindow { ) } else { let window_size = Some(Size::from(self.inner_size())); - (window_size.clone(), window_size) + (window_size, window_size) }; self.set_maximizable_inner(resizable).queue(); @@ -1445,7 +1449,11 @@ impl UnownedWindow { #[inline] pub fn request_redraw(&self) { - self.redraw_sender.send(WindowId(self.xwindow)).unwrap(); + self.redraw_sender + .sender + .send(WindowId(self.xwindow)) + .unwrap(); + self.redraw_sender.waker.wake().unwrap(); } #[inline]