diff --git a/src/wayland/data_device/data_source.rs b/src/wayland/data_device/data_source.rs index cee8b4a..9ebe10b 100644 --- a/src/wayland/data_device/data_source.rs +++ b/src/wayland/data_device/data_source.rs @@ -1,4 +1,4 @@ -use std::sync::Mutex; +use std::cell::RefCell; use wayland_server::{ protocol::{ @@ -20,8 +20,8 @@ pub struct SourceMetadata { pub(crate) fn implement_data_source(src: NewResource) -> WlDataSource { src.implement_closure( |req, me| { - let data: &Mutex = me.as_ref().user_data().unwrap(); - let mut guard = data.lock().unwrap(); + let data: &RefCell = me.as_ref().user_data().unwrap(); + let mut guard = data.borrow_mut(); match req { Request::Offer { mime_type } => guard.mime_types.push(mime_type), Request::SetActions { dnd_actions } => { @@ -32,7 +32,7 @@ pub(crate) fn implement_data_source(src: NewResource) -> WlDataSou } }, None::, - Mutex::new(SourceMetadata { + RefCell::new(SourceMetadata { mime_types: Vec::new(), dnd_action: DndAction::None, }), @@ -44,8 +44,8 @@ pub fn with_source_metadata T>( source: &WlDataSource, f: F, ) -> Result { - match source.as_ref().user_data::>() { - Some(data) => Ok(f(&data.lock().unwrap())), + match source.as_ref().user_data::>() { + Some(data) => Ok(f(&data.borrow())), None => Err(()), } } diff --git a/src/wayland/data_device/dnd_grab.rs b/src/wayland/data_device/dnd_grab.rs index f7ea05d..32e47fb 100644 --- a/src/wayland/data_device/dnd_grab.rs +++ b/src/wayland/data_device/dnd_grab.rs @@ -1,4 +1,5 @@ -use std::sync::{Arc, Mutex}; +use std::cell::RefCell; +use std::rc::Rc; use wayland_server::{ protocol::{ @@ -19,10 +20,10 @@ pub(crate) struct DnDGrab { data_source: Option, current_focus: Option, pending_offers: Vec, - offer_data: Option>>, + offer_data: Option>>, icon: Option, origin: wl_surface::WlSurface, - callback: Arc>, + callback: Rc>, token: CompositorToken, seat: Seat, } @@ -34,7 +35,7 @@ impl + 'static> DnDGrab { seat: Seat, icon: Option, token: CompositorToken, - callback: Arc>, + callback: Rc>, ) -> DnDGrab { DnDGrab { data_source: source, @@ -63,10 +64,9 @@ impl + 'static> PointerGrab for DnDGrab { let seat_data = self .seat .user_data() - .get::>() + .get::>() .unwrap() - .lock() - .unwrap(); + .borrow_mut(); if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() { // focus changed, we need to make a leave if appropriate if let Some(surface) = self.current_focus.take() { @@ -80,7 +80,7 @@ impl + 'static> PointerGrab for DnDGrab { // disable the offers self.pending_offers.clear(); if let Some(offer_data) = self.offer_data.take() { - offer_data.lock().unwrap().active = false; + offer_data.borrow_mut().active = false; } } } @@ -94,7 +94,7 @@ impl + 'static> PointerGrab for DnDGrab { if self.current_focus.is_none() { // We entered a new surface, send the data offer if appropriate if let Some(ref source) = self.data_source { - let offer_data = Arc::new(Mutex::new(OfferData { + let offer_data = Rc::new(RefCell::new(OfferData { active: true, dropped: false, accepted: true, @@ -173,12 +173,11 @@ impl + 'static> PointerGrab for DnDGrab { let seat_data = self .seat .user_data() - .get::>() + .get::>() .unwrap() - .lock() - .unwrap(); + .borrow_mut(); let validated = if let Some(ref data) = self.offer_data { - let data = data.lock().unwrap(); + let data = data.borrow(); data.accepted && (!data.chosen_action.is_empty()) } else { false @@ -197,7 +196,7 @@ impl + 'static> PointerGrab for DnDGrab { } } if let Some(ref offer_data) = self.offer_data { - let mut data = offer_data.lock().unwrap(); + let mut data = offer_data.borrow_mut(); if validated { data.dropped = true; } else { @@ -210,7 +209,7 @@ impl + 'static> PointerGrab for DnDGrab { source.cancelled(); } } - (&mut *self.callback.lock().unwrap())(super::DataDeviceEvent::DnDDropped); + (&mut *self.callback.borrow_mut())(super::DataDeviceEvent::DnDDropped); if let Some(icon) = self.icon.take() { if icon.as_ref().is_alive() { self.token.remove_role::(&icon).unwrap(); @@ -238,13 +237,13 @@ struct OfferData { fn implement_dnd_data_offer( offer: NewResource, source: wl_data_source::WlDataSource, - offer_data: Arc>, - action_choice: Arc DndAction + Send + 'static>>, + offer_data: Rc>, + action_choice: Rc DndAction + 'static>>, ) -> wl_data_offer::WlDataOffer { use self::wl_data_offer::Request; offer.implement_closure( move |req, offer| { - let mut data = offer_data.lock().unwrap(); + let mut data = offer_data.borrow_mut(); match req { Request::Accept { serial: _, mime_type } => { if let Some(mtype) = mime_type { @@ -312,7 +311,7 @@ fn implement_dnd_data_offer( with_source_metadata(&source, |meta| meta.dnd_action).unwrap_or(DndAction::empty()); let possible_actions = source_actions & DndAction::from_bits_truncate(dnd_actions); data.chosen_action = - (&mut *action_choice.lock().unwrap())(possible_actions, preferred_action); + (&mut *action_choice.borrow_mut())(possible_actions, preferred_action); // check that the user provided callback respects that one precise action should be chosen debug_assert!( [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) diff --git a/src/wayland/data_device/mod.rs b/src/wayland/data_device/mod.rs index f88be7d..fbef6b7 100644 --- a/src/wayland/data_device/mod.rs +++ b/src/wayland/data_device/mod.rs @@ -56,8 +56,9 @@ //! # } //! ``` +use std::cell::RefCell; use std::os::unix::io::RawFd; -use std::sync::{Arc, Mutex}; +use std::rc::Rc; use wayland_server::{ protocol::{ @@ -237,7 +238,7 @@ impl SeatData { debug!(log, "Denying a wl_data_offer.receive with invalid source."); let _ = ::nix::unistd::close(fd); } else { - (&mut *callback.lock().unwrap())(DataDeviceEvent::SendSelection { + (&mut *callback.borrow_mut())(DataDeviceEvent::SendSelection { mime_type, fd, }); @@ -293,15 +294,15 @@ pub fn init_data_device( logger: L, ) -> Global where - F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, - C: FnMut(DataDeviceEvent) + Send + 'static, + F: FnMut(DndAction, DndAction) -> DndAction + 'static, + C: FnMut(DataDeviceEvent) + 'static, R: Role + 'static, U: 'static, L: Into>, { let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr")); - let action_choice = Arc::new(Mutex::new(action_choice)); - let callback = Arc::new(Mutex::new(callback)); + let action_choice = Rc::new(RefCell::new(action_choice)); + let callback = Rc::new(RefCell::new(callback)); let global = display.create_global(3, move |new_ddm, _version| { implement_ddm( new_ddm, @@ -323,12 +324,12 @@ pub fn set_data_device_focus(seat: &Seat, client: Option) { // This should be a rare path anyway, it is unlikely that a client gets focus // before initializing its data device, which would already init the user_data. seat.user_data().insert_if_missing(|| { - Mutex::new(SeatData::new( + RefCell::new(SeatData::new( seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), )) }); - let seat_data = seat.user_data().get::>().unwrap(); - seat_data.lock().unwrap().set_focus(client); + let seat_data = seat.user_data().get::>().unwrap(); + seat_data.borrow_mut().set_focus(client); } /// Set a compositor-provided selection for this seat @@ -340,14 +341,13 @@ pub fn set_data_device_focus(seat: &Seat, client: Option) { pub fn set_data_device_selection(seat: &Seat, mime_types: Vec) { // TODO: same question as in set_data_device_focus seat.user_data().insert_if_missing(|| { - Mutex::new(SeatData::new( + RefCell::new(SeatData::new( seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), )) }); - let seat_data = seat.user_data().get::>().unwrap(); + let seat_data = seat.user_data().get::>().unwrap(); seat_data - .lock() - .unwrap() + .borrow_mut() .set_selection(Selection::Compositor(SourceMetadata { mime_types, dnd_action: DndAction::empty(), @@ -361,17 +361,17 @@ pub fn set_data_device_selection(seat: &Seat, mime_types: Vec) { /// which events can be generated and what response is expected from you to them. pub fn start_dnd(seat: &Seat, serial: u32, metadata: SourceMetadata, callback: C) where - C: FnMut(ServerDndEvent) + Send + 'static, + C: FnMut(ServerDndEvent) + 'static, { // TODO: same question as in set_data_device_focus seat.user_data().insert_if_missing(|| { - Mutex::new(SeatData::new( + RefCell::new(SeatData::new( seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), )) }); if let Some(pointer) = seat.get_pointer() { pointer.set_grab( - server_dnd_grab::ServerDnDGrab::new(metadata, seat.clone(), Arc::new(Mutex::new(callback))), + server_dnd_grab::ServerDnDGrab::new(metadata, seat.clone(), Rc::new(RefCell::new(callback))), serial, ); return; @@ -380,14 +380,14 @@ where fn implement_ddm( new_ddm: NewResource, - callback: Arc>, - action_choice: Arc>, + callback: Rc>, + action_choice: Rc>, token: CompositorToken, log: ::slog::Logger, ) -> wl_data_device_manager::WlDataDeviceManager where - F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, - C: FnMut(DataDeviceEvent) + Send + 'static, + F: FnMut(DndAction, DndAction) -> DndAction + 'static, + C: FnMut(DataDeviceEvent) + 'static, R: Role + 'static, U: 'static, { @@ -401,8 +401,8 @@ where Some(seat) => { // ensure the seat user_data is ready seat.user_data() - .insert_if_missing(|| Mutex::new(SeatData::new(log.clone()))); - let seat_data = seat.user_data().get::>().unwrap(); + .insert_if_missing(|| RefCell::new(SeatData::new(log.clone()))); + let seat_data = seat.user_data().get::>().unwrap(); let data_device = implement_data_device( id, seat.clone(), @@ -411,7 +411,7 @@ where token.clone(), log.clone(), ); - seat_data.lock().unwrap().known_devices.push(data_device); + seat_data.borrow_mut().known_devices.push(data_device); } None => { error!(log, "Unmanaged seat given to a data device."); @@ -425,21 +425,21 @@ where } struct DataDeviceData { - callback: Arc>, - action_choice: Arc DndAction + Send + 'static>>, + callback: Rc>, + action_choice: Rc DndAction + 'static>>, } fn implement_data_device( new_dd: NewResource, seat: Seat, - callback: Arc>, - action_choice: Arc>, + callback: Rc>, + action_choice: Rc>, token: CompositorToken, log: ::slog::Logger, ) -> wl_data_device::WlDataDevice where - F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, - C: FnMut(DataDeviceEvent) + Send + 'static, + F: FnMut(DndAction, DndAction) -> DndAction + 'static, + C: FnMut(DataDeviceEvent) + 'static, R: Role + 'static, U: 'static, { @@ -469,7 +469,7 @@ where } } // The StartDrag is in response to a pointer implicit grab, all is good - (&mut *callback.lock().unwrap())(DataDeviceEvent::DnDStarted { + (&mut *callback.borrow_mut())(DataDeviceEvent::DnDStarted { source: source.clone(), icon: icon.clone(), }); @@ -498,12 +498,11 @@ where .map(|c| keyboard.has_focus(c)) .unwrap_or(false) { - let seat_data = seat.user_data().get::>().unwrap(); - (&mut *callback.lock().unwrap())(DataDeviceEvent::NewSelection(source.clone())); + let seat_data = seat.user_data().get::>().unwrap(); + (&mut *callback.borrow_mut())(DataDeviceEvent::NewSelection(source.clone())); // The client has kbd focus, it can set the selection seat_data - .lock() - .unwrap() + .borrow_mut() .set_selection(source.map(Selection::Client).unwrap_or(Selection::Empty)); return; } @@ -513,10 +512,9 @@ where Request::Release => { // Clean up the known devices seat.user_data() - .get::>() - .unwrap() - .lock() + .get::>() .unwrap() + .borrow_mut() .known_devices .retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref()))) } diff --git a/src/wayland/data_device/server_dnd_grab.rs b/src/wayland/data_device/server_dnd_grab.rs index 009ce6f..4c094b7 100644 --- a/src/wayland/data_device/server_dnd_grab.rs +++ b/src/wayland/data_device/server_dnd_grab.rs @@ -1,5 +1,6 @@ +use std::cell::RefCell; use std::os::unix::io::RawFd; -use std::sync::{Arc, Mutex}; +use std::rc::Rc; use wayland_server::{ protocol::{wl_data_device, wl_data_device_manager::DndAction, wl_data_offer, wl_pointer, wl_surface}, @@ -39,16 +40,16 @@ pub(crate) struct ServerDnDGrab { metadata: super::SourceMetadata, current_focus: Option, pending_offers: Vec, - offer_data: Option>>, + offer_data: Option>>, seat: Seat, - callback: Arc>, + callback: Rc>, } impl ServerDnDGrab { pub(crate) fn new( metadata: super::SourceMetadata, seat: Seat, - callback: Arc>, + callback: Rc>, ) -> ServerDnDGrab { ServerDnDGrab { metadata, @@ -63,7 +64,7 @@ impl ServerDnDGrab { impl PointerGrab for ServerDnDGrab where - C: FnMut(ServerDndEvent) + Send + 'static, + C: FnMut(ServerDndEvent) + 'static, { fn motion( &mut self, @@ -77,10 +78,9 @@ where let seat_data = self .seat .user_data() - .get::>() + .get::>() .unwrap() - .lock() - .unwrap(); + .borrow_mut(); if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() { // focus changed, we need to make a leave if appropriate if let Some(surface) = self.current_focus.take() { @@ -92,7 +92,7 @@ where // disable the offers self.pending_offers.clear(); if let Some(offer_data) = self.offer_data.take() { - offer_data.lock().unwrap().active = false; + offer_data.borrow_mut().active = false; } } } @@ -104,7 +104,7 @@ where }; if self.current_focus.is_none() { // We entered a new surface, send the data offer - let offer_data = Arc::new(Mutex::new(OfferData { + let offer_data = Rc::new(RefCell::new(OfferData { active: true, dropped: false, accepted: true, @@ -169,12 +169,11 @@ where let seat_data = self .seat .user_data() - .get::>() + .get::>() .unwrap() - .lock() - .unwrap(); + .borrow_mut(); let validated = if let Some(ref data) = self.offer_data { - let data = data.lock().unwrap(); + let data = data.borrow(); data.accepted && (!data.chosen_action.is_empty()) } else { false @@ -191,14 +190,14 @@ where } } if let Some(ref offer_data) = self.offer_data { - let mut data = offer_data.lock().unwrap(); + let mut data = offer_data.borrow_mut(); if validated { data.dropped = true; } else { data.active = false; } } - let mut callback = self.callback.lock().unwrap(); + let mut callback = self.callback.borrow_mut(); (&mut *callback)(ServerDndEvent::Dropped); if !validated { (&mut *callback)(ServerDndEvent::Cancelled); @@ -225,17 +224,17 @@ struct OfferData { fn implement_dnd_data_offer( offer: NewResource, metadata: super::SourceMetadata, - offer_data: Arc>, - callback: Arc>, - action_choice: Arc DndAction + Send + 'static>>, + offer_data: Rc>, + callback: Rc>, + action_choice: Rc DndAction + 'static>>, ) -> wl_data_offer::WlDataOffer where - C: FnMut(ServerDndEvent) + Send + 'static, + C: FnMut(ServerDndEvent) + 'static, { use self::wl_data_offer::Request; offer.implement_closure( move |req, offer| { - let mut data = offer_data.lock().unwrap(); + let mut data = offer_data.borrow_mut(); match req { Request::Accept { serial: _, mime_type } => { if let Some(mtype) = mime_type { @@ -247,7 +246,7 @@ where Request::Receive { mime_type, fd } => { // check if the source and associated mime type is still valid if metadata.mime_types.contains(&mime_type) && data.active { - (&mut *callback.lock().unwrap())(ServerDndEvent::Send { mime_type, fd }); + (&mut *callback.borrow_mut())(ServerDndEvent::Send { mime_type, fd }); } } Request::Destroy => {} @@ -276,7 +275,7 @@ where "Cannot finish a data offer with no valid action.".into(), ); } - (&mut *callback.lock().unwrap())(ServerDndEvent::Finished); + (&mut *callback.borrow_mut())(ServerDndEvent::Finished); data.active = false; } Request::SetActions { @@ -292,13 +291,13 @@ where } let possible_actions = metadata.dnd_action & DndAction::from_bits_truncate(dnd_actions); data.chosen_action = - (&mut *action_choice.lock().unwrap())(possible_actions, preferred_action); + (&mut *action_choice.borrow_mut())(possible_actions, preferred_action); // check that the user provided callback respects that one precise action should be chosen debug_assert!( [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) ); offer.action(data.chosen_action.to_raw()); - (&mut *callback.lock().unwrap())(ServerDndEvent::Action(data.chosen_action)); + (&mut *callback.borrow_mut())(ServerDndEvent::Action(data.chosen_action)); } _ => unreachable!(), } diff --git a/src/wayland/seat/keyboard.rs b/src/wayland/seat/keyboard.rs index cdc8d12..e34921b 100644 --- a/src/wayland/seat/keyboard.rs +++ b/src/wayland/seat/keyboard.rs @@ -1,9 +1,10 @@ use crate::backend::input::KeyState; use std::{ + cell::RefCell, default::Default, io::{Error as IoError, Write}, os::unix::io::AsRawFd, - sync::{Arc, Mutex}, + rc::Rc, }; use tempfile::tempfile; use wayland_server::{ @@ -253,24 +254,23 @@ where let keymap = internal.keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1); Ok(KeyboardHandle { - arc: Arc::new(KbdArc { - internal: Mutex::new(internal), + arc: Rc::new(KbdRc { + internal: RefCell::new(internal), keymap, logger: log, }), }) } -struct KbdArc { - internal: Mutex, +struct KbdRc { + internal: RefCell, keymap: String, logger: ::slog::Logger, } /// An handle to a keyboard handler /// -/// It can be cloned and all clones manipulate the same internal state. Clones -/// can also be sent across threads. +/// It can be cloned and all clones manipulate the same internal state. /// /// This handle gives you 2 main ways to interact with the keyboard handling: /// @@ -281,7 +281,7 @@ struct KbdArc { /// details. #[derive(Clone)] pub struct KeyboardHandle { - arc: Arc, + arc: Rc, } impl KeyboardHandle { @@ -302,7 +302,7 @@ impl KeyboardHandle { F: FnOnce(&ModifiersState, Keysym) -> bool, { trace!(self.arc.logger, "Handling keystroke"; "keycode" => keycode, "state" => format_args!("{:?}", state)); - let mut guard = self.arc.internal.lock().unwrap(); + let mut guard = self.arc.internal.borrow_mut(); // Offset the keycode by 8, as the evdev XKB rules reflect X's // broken keycode system, which starts at 8. @@ -350,7 +350,7 @@ impl KeyboardHandle { /// event, and if the new focus is not `None`, /// a [`wl_keyboard::Event::Enter`](wayland_server::protocol::wl_keyboard::Event::Enter) event will be sent. pub fn set_focus(&self, focus: Option<&WlSurface>, serial: u32) { - let mut guard = self.arc.internal.lock().unwrap(); + let mut guard = self.arc.internal.borrow_mut(); let same = guard .focus @@ -394,8 +394,7 @@ impl KeyboardHandle { pub fn has_focus(&self, client: &Client) -> bool { self.arc .internal - .lock() - .unwrap() + .borrow_mut() .focus .as_ref() .and_then(|f| f.as_ref().client()) @@ -431,7 +430,7 @@ impl KeyboardHandle { return; }; - let mut guard = self.arc.internal.lock().unwrap(); + let mut guard = self.arc.internal.borrow_mut(); if kbd.as_ref().version() >= 4 { kbd.repeat_info(guard.repeat_rate, guard.repeat_delay); } @@ -440,7 +439,7 @@ impl KeyboardHandle { /// Change the repeat info configured for this keyboard pub fn change_repeat_info(&self, rate: i32, delay: i32) { - let mut guard = self.arc.internal.lock().unwrap(); + let mut guard = self.arc.internal.borrow_mut(); guard.repeat_delay = delay; guard.repeat_rate = rate; for kbd in &guard.known_kbds { @@ -458,8 +457,7 @@ pub(crate) fn implement_keyboard( let arc = h.arc.clone(); Some(move |keyboard: WlKeyboard| { arc.internal - .lock() - .unwrap() + .borrow_mut() .known_kbds .retain(|k| !k.as_ref().equals(&keyboard.as_ref())) }) diff --git a/src/wayland/seat/mod.rs b/src/wayland/seat/mod.rs index b4781cd..bb8ad69 100644 --- a/src/wayland/seat/mod.rs +++ b/src/wayland/seat/mod.rs @@ -43,7 +43,7 @@ //! These methods return handles that can be cloned and sent across thread, so you can keep one around //! in your event-handling code to forward inputs to your clients. -use std::sync::{Arc, Mutex}; +use std::{cell::RefCell, rc::Rc}; mod keyboard; mod pointer; @@ -70,8 +70,8 @@ struct Inner { known_seats: Vec, } -pub(crate) struct SeatArc { - inner: Mutex, +pub(crate) struct SeatRc { + inner: RefCell, user_data: UserDataMap, pub(crate) log: ::slog::Logger, name: String, @@ -104,13 +104,12 @@ impl Inner { /// /// It is directly inserted in the event loop by its [`new`](Seat::new) method. /// -/// This is an handle to the inner logic, it can be cloned and shared accross -/// threads. +/// This is an handle to the inner logic, it can be cloned. /// /// See module-level documentation for details of use. #[derive(Clone)] pub struct Seat { - pub(crate) arc: Arc, + pub(crate) arc: Rc, } impl Seat { @@ -134,8 +133,8 @@ impl Seat { L: Into>, { let log = crate::slog_or_stdlog(logger); - let arc = Arc::new(SeatArc { - inner: Mutex::new(Inner { + let arc = Rc::new(SeatRc { + inner: RefCell::new(Inner { pointer: None, keyboard: None, known_seats: Vec::new(), @@ -147,7 +146,7 @@ impl Seat { let seat = Seat { arc: arc.clone() }; let global = display.create_global(5, move |new_seat, _version| { let seat = implement_seat(new_seat, arc.clone(), token.clone()); - let mut inner = arc.inner.lock().unwrap(); + let mut inner = arc.inner.borrow_mut(); if seat.as_ref().version() >= 2 { seat.name(arc.name.clone()); } @@ -160,7 +159,7 @@ impl Seat { /// Attempt to retrieve a [`Seat`] from an existing resource pub fn from_resource(seat: &wl_seat::WlSeat) -> Option { seat.as_ref() - .user_data::>() + .user_data::>() .cloned() .map(|arc| Seat { arc }) } @@ -173,7 +172,7 @@ impl Seat { /// Adds the pointer capability to this seat /// /// You are provided a [`PointerHandle`], which allows you to send input events - /// to this pointer. This handle can be cloned and sent across threads. + /// to this pointer. This handle can be cloned. /// /// Calling this method on a seat that already has a pointer capability /// will overwrite it, and will be seen by the clients as if the @@ -212,9 +211,9 @@ impl Seat { where U: 'static, R: Role + 'static, - F: FnMut(CursorImageStatus) + Send + 'static, + F: FnMut(CursorImageStatus) + 'static, { - let mut inner = self.arc.inner.lock().unwrap(); + let mut inner = self.arc.inner.borrow_mut(); let pointer = self::pointer::create_pointer_handler(token, cb); if inner.pointer.is_some() { // there is already a pointer, remove it and notify the clients @@ -229,14 +228,14 @@ impl Seat { /// Access the pointer of this seat if any pub fn get_pointer(&self) -> Option { - self.arc.inner.lock().unwrap().pointer.clone() + self.arc.inner.borrow_mut().pointer.clone() } /// Remove the pointer capability from this seat /// /// Clients will be appropriately notified. pub fn remove_pointer(&mut self) { - let mut inner = self.arc.inner.lock().unwrap(); + let mut inner = self.arc.inner.borrow_mut(); if inner.pointer.is_some() { inner.pointer = None; inner.send_all_caps(); @@ -246,7 +245,7 @@ impl Seat { /// Adds the keyboard capability to this seat /// /// You are provided a [`KeyboardHandle`], which allows you to send input events - /// to this keyboard. This handle can be cloned and sent across threads. + /// to this keyboard. This handle can be cloned. /// /// You also provide a Model/Layout/Variant/Options specification of the /// keymap to be used for this keyboard, as well as any repeat-info that @@ -289,7 +288,7 @@ impl Seat { F: FnMut(&Seat, Option<&wl_surface::WlSurface>) + 'static, { let me = self.clone(); - let mut inner = self.arc.inner.lock().unwrap(); + let mut inner = self.arc.inner.borrow_mut(); let keyboard = self::keyboard::create_keyboard_handler( xkb_config, repeat_delay, @@ -310,14 +309,14 @@ impl Seat { /// Access the keyboard of this seat if any pub fn get_keyboard(&self) -> Option { - self.arc.inner.lock().unwrap().keyboard.clone() + self.arc.inner.borrow_mut().keyboard.clone() } /// Remove the keyboard capability from this seat /// /// Clients will be appropriately notified. pub fn remove_keyboard(&mut self) { - let mut inner = self.arc.inner.lock().unwrap(); + let mut inner = self.arc.inner.borrow_mut(); if inner.keyboard.is_some() { inner.keyboard = None; inner.send_all_caps(); @@ -326,20 +325,20 @@ impl Seat { /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`] pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool { - let inner = self.arc.inner.lock().unwrap(); + let inner = self.arc.inner.borrow_mut(); inner.known_seats.iter().any(|s| s.as_ref().equals(seat.as_ref())) } } impl ::std::cmp::PartialEq for Seat { fn eq(&self, other: &Seat) -> bool { - Arc::ptr_eq(&self.arc, &other.arc) + Rc::ptr_eq(&self.arc, &other.arc) } } fn implement_seat( new_seat: NewResource, - arc: Arc, + arc: Rc, token: CompositorToken, ) -> wl_seat::WlSeat where @@ -349,8 +348,8 @@ where let dest_arc = arc.clone(); new_seat.implement_closure( move |request, seat| { - let arc = seat.as_ref().user_data::>().unwrap(); - let inner = arc.inner.lock().unwrap(); + let arc = seat.as_ref().user_data::>().unwrap(); + let inner = arc.inner.borrow_mut(); match request { wl_seat::Request::GetPointer { id } => { let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref(), token.clone()); @@ -381,8 +380,7 @@ where Some(move |seat: wl_seat::WlSeat| { dest_arc .inner - .lock() - .unwrap() + .borrow_mut() .known_seats .retain(|s| !s.as_ref().equals(&seat.as_ref())); }), diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index 354a22d..1cbbb07 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -1,4 +1,6 @@ -use std::sync::{Arc, Mutex}; +use std::cell::RefCell; +use std::rc::Rc; + use wayland_server::{ protocol::{ wl_pointer::{self, Axis, AxisSource, ButtonState, Event, Request, WlPointer}, @@ -48,7 +50,7 @@ impl PointerInternal { where U: 'static, R: Role + 'static, - F: FnMut(CursorImageStatus) + Send + 'static, + F: FnMut(CursorImageStatus) + 'static, { let mut old_status = CursorImageStatus::Default; let wrapper = move |new_status: CursorImageStatus| { @@ -117,8 +119,7 @@ impl PointerInternal { /// An handle to a pointer handler /// -/// It can be cloned and all clones manipulate the same internal state. Clones -/// can also be sent across threads. +/// It can be cloned and all clones manipulate the same internal state. /// /// This handle gives you access to an interface to send pointer events to your /// clients. @@ -127,12 +128,12 @@ impl PointerInternal { /// grab if any is active. See the [`PointerGrab`] trait for details. #[derive(Clone)] pub struct PointerHandle { - inner: Arc>, + inner: Rc>, } impl PointerHandle { pub(crate) fn new_pointer(&self, pointer: WlPointer) { - let mut guard = self.inner.lock().unwrap(); + let mut guard = self.inner.borrow_mut(); guard.known_pointers.push(pointer); } @@ -140,17 +141,17 @@ impl PointerHandle { /// /// Overwrites any current grab. pub fn set_grab(&self, grab: G, serial: u32) { - self.inner.lock().unwrap().grab = GrabStatus::Active(serial, Box::new(grab)); + self.inner.borrow_mut().grab = GrabStatus::Active(serial, Box::new(grab)); } /// Remove any current grab on this pointer, reseting it to the default behavior pub fn unset_grab(&self) { - self.inner.lock().unwrap().grab = GrabStatus::None; + self.inner.borrow_mut().grab = GrabStatus::None; } /// Check if this pointer is currently grabbed with this serial pub fn has_grab(&self, serial: u32) -> bool { - let guard = self.inner.lock().unwrap(); + let guard = self.inner.borrow_mut(); match guard.grab { GrabStatus::Active(s, _) => s == serial, _ => false, @@ -159,7 +160,7 @@ impl PointerHandle { /// Check if this pointer is currently being grabbed pub fn is_grabbed(&self) -> bool { - let guard = self.inner.lock().unwrap(); + let guard = self.inner.borrow_mut(); match guard.grab { GrabStatus::None => false, _ => true, @@ -184,7 +185,7 @@ impl PointerHandle { serial: u32, time: u32, ) { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.borrow_mut(); inner.pending_focus = focus.clone(); inner.with_grab(move |mut handle, grab| { grab.motion(&mut handle, location, focus, serial, time); @@ -196,7 +197,7 @@ impl PointerHandle { /// This will internally send the appropriate button event to the client /// objects matching with the currently focused surface. pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) { - let mut inner = self.inner.lock().unwrap(); + let mut inner = self.inner.borrow_mut(); match state { ButtonState::Pressed => { inner.pressed_buttons.push(button); @@ -215,7 +216,7 @@ impl PointerHandle { /// /// A single frame will group multiple scroll events as if they happened in the same instance. pub fn axis(&self, details: AxisFrame) { - self.inner.lock().unwrap().with_grab(|mut handle, grab| { + self.inner.borrow_mut().with_grab(|mut handle, grab| { grab.axis(&mut handle, details); }); } @@ -517,10 +518,10 @@ pub(crate) fn create_pointer_handler(token: CompositorToken, cb: where R: Role + 'static, U: 'static, - F: FnMut(CursorImageStatus) + Send + 'static, + F: FnMut(CursorImageStatus) + 'static, { PointerHandle { - inner: Arc::new(Mutex::new(PointerInternal::new(token, cb))), + inner: Rc::new(RefCell::new(PointerInternal::new(token, cb))), } } @@ -537,8 +538,7 @@ where let destructor = match inner.clone() { Some(inner) => Some(move |pointer: WlPointer| { inner - .lock() - .unwrap() + .borrow_mut() .known_pointers .retain(|p| !p.as_ref().equals(&pointer.as_ref())) }), @@ -554,7 +554,7 @@ where hotspot_y, } => { if let Some(ref inner) = inner { - let mut guard = inner.lock().unwrap(); + let mut guard = inner.borrow_mut(); // only allow setting the cursor icon if the current pointer focus // is of the same client let PointerInternal {