Don't promise thread-safety that we can't respect

This commit is contained in:
Victor Berger 2019-02-23 17:55:47 +01:00 committed by Victor Berger
parent 3f2857fbf3
commit 3d8f22c805
7 changed files with 139 additions and 147 deletions

View File

@ -1,4 +1,4 @@
use std::sync::Mutex; use std::cell::RefCell;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
@ -20,8 +20,8 @@ pub struct SourceMetadata {
pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSource { pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSource {
src.implement_closure( src.implement_closure(
|req, me| { |req, me| {
let data: &Mutex<SourceMetadata> = me.as_ref().user_data().unwrap(); let data: &RefCell<SourceMetadata> = me.as_ref().user_data().unwrap();
let mut guard = data.lock().unwrap(); let mut guard = data.borrow_mut();
match req { match req {
Request::Offer { mime_type } => guard.mime_types.push(mime_type), Request::Offer { mime_type } => guard.mime_types.push(mime_type),
Request::SetActions { dnd_actions } => { Request::SetActions { dnd_actions } => {
@ -32,7 +32,7 @@ pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSou
} }
}, },
None::<fn(_)>, None::<fn(_)>,
Mutex::new(SourceMetadata { RefCell::new(SourceMetadata {
mime_types: Vec::new(), mime_types: Vec::new(),
dnd_action: DndAction::None, dnd_action: DndAction::None,
}), }),
@ -44,8 +44,8 @@ pub fn with_source_metadata<T, F: FnOnce(&SourceMetadata) -> T>(
source: &WlDataSource, source: &WlDataSource,
f: F, f: F,
) -> Result<T, ()> { ) -> Result<T, ()> {
match source.as_ref().user_data::<Mutex<SourceMetadata>>() { match source.as_ref().user_data::<RefCell<SourceMetadata>>() {
Some(data) => Ok(f(&data.lock().unwrap())), Some(data) => Ok(f(&data.borrow())),
None => Err(()), None => Err(()),
} }
} }

View File

@ -1,4 +1,5 @@
use std::sync::{Arc, Mutex}; use std::cell::RefCell;
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
@ -19,10 +20,10 @@ pub(crate) struct DnDGrab<U, R> {
data_source: Option<wl_data_source::WlDataSource>, data_source: Option<wl_data_source::WlDataSource>,
current_focus: Option<wl_surface::WlSurface>, current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>, pending_offers: Vec<wl_data_offer::WlDataOffer>,
offer_data: Option<Arc<Mutex<OfferData>>>, offer_data: Option<Rc<RefCell<OfferData>>>,
icon: Option<wl_surface::WlSurface>, icon: Option<wl_surface::WlSurface>,
origin: wl_surface::WlSurface, origin: wl_surface::WlSurface,
callback: Arc<Mutex<dyn FnMut(super::DataDeviceEvent) + Send>>, callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
token: CompositorToken<U, R>, token: CompositorToken<U, R>,
seat: Seat, seat: Seat,
} }
@ -34,7 +35,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
seat: Seat, seat: Seat,
icon: Option<wl_surface::WlSurface>, icon: Option<wl_surface::WlSurface>,
token: CompositorToken<U, R>, token: CompositorToken<U, R>,
callback: Arc<Mutex<dyn FnMut(super::DataDeviceEvent) + Send>>, callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
) -> DnDGrab<U, R> { ) -> DnDGrab<U, R> {
DnDGrab { DnDGrab {
data_source: source, data_source: source,
@ -63,10 +64,9 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
let seat_data = self let seat_data = self
.seat .seat
.user_data() .user_data()
.get::<Mutex<SeatData>>() .get::<RefCell<SeatData>>()
.unwrap() .unwrap()
.lock() .borrow_mut();
.unwrap();
if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() { if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() {
// focus changed, we need to make a leave if appropriate // focus changed, we need to make a leave if appropriate
if let Some(surface) = self.current_focus.take() { if let Some(surface) = self.current_focus.take() {
@ -80,7 +80,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
// disable the offers // disable the offers
self.pending_offers.clear(); self.pending_offers.clear();
if let Some(offer_data) = self.offer_data.take() { 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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
if self.current_focus.is_none() { if self.current_focus.is_none() {
// We entered a new surface, send the data offer if appropriate // We entered a new surface, send the data offer if appropriate
if let Some(ref source) = self.data_source { 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, active: true,
dropped: false, dropped: false,
accepted: true, accepted: true,
@ -173,12 +173,11 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
let seat_data = self let seat_data = self
.seat .seat
.user_data() .user_data()
.get::<Mutex<SeatData>>() .get::<RefCell<SeatData>>()
.unwrap() .unwrap()
.lock() .borrow_mut();
.unwrap();
let validated = if let Some(ref data) = self.offer_data { 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()) data.accepted && (!data.chosen_action.is_empty())
} else { } else {
false false
@ -197,7 +196,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
} }
} }
if let Some(ref offer_data) = self.offer_data { 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 { if validated {
data.dropped = true; data.dropped = true;
} else { } else {
@ -210,7 +209,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
source.cancelled(); 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 let Some(icon) = self.icon.take() {
if icon.as_ref().is_alive() { if icon.as_ref().is_alive() {
self.token.remove_role::<super::DnDIconRole>(&icon).unwrap(); self.token.remove_role::<super::DnDIconRole>(&icon).unwrap();
@ -238,13 +237,13 @@ struct OfferData {
fn implement_dnd_data_offer( fn implement_dnd_data_offer(
offer: NewResource<wl_data_offer::WlDataOffer>, offer: NewResource<wl_data_offer::WlDataOffer>,
source: wl_data_source::WlDataSource, source: wl_data_source::WlDataSource,
offer_data: Arc<Mutex<OfferData>>, offer_data: Rc<RefCell<OfferData>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>, action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
) -> wl_data_offer::WlDataOffer { ) -> wl_data_offer::WlDataOffer {
use self::wl_data_offer::Request; use self::wl_data_offer::Request;
offer.implement_closure( offer.implement_closure(
move |req, offer| { move |req, offer| {
let mut data = offer_data.lock().unwrap(); let mut data = offer_data.borrow_mut();
match req { match req {
Request::Accept { serial: _, mime_type } => { Request::Accept { serial: _, mime_type } => {
if let Some(mtype) = 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()); with_source_metadata(&source, |meta| meta.dnd_action).unwrap_or(DndAction::empty());
let possible_actions = source_actions & DndAction::from_bits_truncate(dnd_actions); let possible_actions = source_actions & DndAction::from_bits_truncate(dnd_actions);
data.chosen_action = 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 // check that the user provided callback respects that one precise action should be chosen
debug_assert!( debug_assert!(
[DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action)

View File

@ -56,8 +56,9 @@
//! # } //! # }
//! ``` //! ```
use std::cell::RefCell;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::sync::{Arc, Mutex}; use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
@ -237,7 +238,7 @@ impl SeatData {
debug!(log, "Denying a wl_data_offer.receive with invalid source."); debug!(log, "Denying a wl_data_offer.receive with invalid source.");
let _ = ::nix::unistd::close(fd); let _ = ::nix::unistd::close(fd);
} else { } else {
(&mut *callback.lock().unwrap())(DataDeviceEvent::SendSelection { (&mut *callback.borrow_mut())(DataDeviceEvent::SendSelection {
mime_type, mime_type,
fd, fd,
}); });
@ -293,15 +294,15 @@ pub fn init_data_device<F, C, U, R, L>(
logger: L, logger: L,
) -> Global<wl_data_device_manager::WlDataDeviceManager> ) -> Global<wl_data_device_manager::WlDataDeviceManager>
where where
F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + Send + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static, U: 'static,
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
{ {
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr")); let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr"));
let action_choice = Arc::new(Mutex::new(action_choice)); let action_choice = Rc::new(RefCell::new(action_choice));
let callback = Arc::new(Mutex::new(callback)); let callback = Rc::new(RefCell::new(callback));
let global = display.create_global(3, move |new_ddm, _version| { let global = display.create_global(3, move |new_ddm, _version| {
implement_ddm( implement_ddm(
new_ddm, new_ddm,
@ -323,12 +324,12 @@ pub fn set_data_device_focus(seat: &Seat, client: Option<Client>) {
// This should be a rare path anyway, it is unlikely that a client gets focus // 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. // before initializing its data device, which would already init the user_data.
seat.user_data().insert_if_missing(|| { seat.user_data().insert_if_missing(|| {
Mutex::new(SeatData::new( RefCell::new(SeatData::new(
seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), seat.arc.log.new(o!("smithay_module" => "data_device_mgr")),
)) ))
}); });
let seat_data = seat.user_data().get::<Mutex<SeatData>>().unwrap(); let seat_data = seat.user_data().get::<RefCell<SeatData>>().unwrap();
seat_data.lock().unwrap().set_focus(client); seat_data.borrow_mut().set_focus(client);
} }
/// Set a compositor-provided selection for this seat /// Set a compositor-provided selection for this seat
@ -340,14 +341,13 @@ pub fn set_data_device_focus(seat: &Seat, client: Option<Client>) {
pub fn set_data_device_selection(seat: &Seat, mime_types: Vec<String>) { pub fn set_data_device_selection(seat: &Seat, mime_types: Vec<String>) {
// TODO: same question as in set_data_device_focus // TODO: same question as in set_data_device_focus
seat.user_data().insert_if_missing(|| { seat.user_data().insert_if_missing(|| {
Mutex::new(SeatData::new( RefCell::new(SeatData::new(
seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), seat.arc.log.new(o!("smithay_module" => "data_device_mgr")),
)) ))
}); });
let seat_data = seat.user_data().get::<Mutex<SeatData>>().unwrap(); let seat_data = seat.user_data().get::<RefCell<SeatData>>().unwrap();
seat_data seat_data
.lock() .borrow_mut()
.unwrap()
.set_selection(Selection::Compositor(SourceMetadata { .set_selection(Selection::Compositor(SourceMetadata {
mime_types, mime_types,
dnd_action: DndAction::empty(), dnd_action: DndAction::empty(),
@ -361,17 +361,17 @@ pub fn set_data_device_selection(seat: &Seat, mime_types: Vec<String>) {
/// which events can be generated and what response is expected from you to them. /// which events can be generated and what response is expected from you to them.
pub fn start_dnd<C>(seat: &Seat, serial: u32, metadata: SourceMetadata, callback: C) pub fn start_dnd<C>(seat: &Seat, serial: u32, metadata: SourceMetadata, callback: C)
where where
C: FnMut(ServerDndEvent) + Send + 'static, C: FnMut(ServerDndEvent) + 'static,
{ {
// TODO: same question as in set_data_device_focus // TODO: same question as in set_data_device_focus
seat.user_data().insert_if_missing(|| { seat.user_data().insert_if_missing(|| {
Mutex::new(SeatData::new( RefCell::new(SeatData::new(
seat.arc.log.new(o!("smithay_module" => "data_device_mgr")), seat.arc.log.new(o!("smithay_module" => "data_device_mgr")),
)) ))
}); });
if let Some(pointer) = seat.get_pointer() { if let Some(pointer) = seat.get_pointer() {
pointer.set_grab( 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, serial,
); );
return; return;
@ -380,14 +380,14 @@ where
fn implement_ddm<F, C, U, R>( fn implement_ddm<F, C, U, R>(
new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>, new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>,
callback: Arc<Mutex<C>>, callback: Rc<RefCell<C>>,
action_choice: Arc<Mutex<F>>, action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>, token: CompositorToken<U, R>,
log: ::slog::Logger, log: ::slog::Logger,
) -> wl_data_device_manager::WlDataDeviceManager ) -> wl_data_device_manager::WlDataDeviceManager
where where
F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + Send + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static, U: 'static,
{ {
@ -401,8 +401,8 @@ where
Some(seat) => { Some(seat) => {
// ensure the seat user_data is ready // ensure the seat user_data is ready
seat.user_data() seat.user_data()
.insert_if_missing(|| Mutex::new(SeatData::new(log.clone()))); .insert_if_missing(|| RefCell::new(SeatData::new(log.clone())));
let seat_data = seat.user_data().get::<Mutex<SeatData>>().unwrap(); let seat_data = seat.user_data().get::<RefCell<SeatData>>().unwrap();
let data_device = implement_data_device( let data_device = implement_data_device(
id, id,
seat.clone(), seat.clone(),
@ -411,7 +411,7 @@ where
token.clone(), token.clone(),
log.clone(), log.clone(),
); );
seat_data.lock().unwrap().known_devices.push(data_device); seat_data.borrow_mut().known_devices.push(data_device);
} }
None => { None => {
error!(log, "Unmanaged seat given to a data device."); error!(log, "Unmanaged seat given to a data device.");
@ -425,21 +425,21 @@ where
} }
struct DataDeviceData { struct DataDeviceData {
callback: Arc<Mutex<dyn FnMut(DataDeviceEvent) + Send + 'static>>, callback: Rc<RefCell<dyn FnMut(DataDeviceEvent) + 'static>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>, action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
} }
fn implement_data_device<F, C, U, R>( fn implement_data_device<F, C, U, R>(
new_dd: NewResource<wl_data_device::WlDataDevice>, new_dd: NewResource<wl_data_device::WlDataDevice>,
seat: Seat, seat: Seat,
callback: Arc<Mutex<C>>, callback: Rc<RefCell<C>>,
action_choice: Arc<Mutex<F>>, action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>, token: CompositorToken<U, R>,
log: ::slog::Logger, log: ::slog::Logger,
) -> wl_data_device::WlDataDevice ) -> wl_data_device::WlDataDevice
where where
F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + Send + 'static, C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static, R: Role<DnDIconRole> + 'static,
U: 'static, U: 'static,
{ {
@ -469,7 +469,7 @@ where
} }
} }
// The StartDrag is in response to a pointer implicit grab, all is good // 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(), source: source.clone(),
icon: icon.clone(), icon: icon.clone(),
}); });
@ -498,12 +498,11 @@ where
.map(|c| keyboard.has_focus(c)) .map(|c| keyboard.has_focus(c))
.unwrap_or(false) .unwrap_or(false)
{ {
let seat_data = seat.user_data().get::<Mutex<SeatData>>().unwrap(); let seat_data = seat.user_data().get::<RefCell<SeatData>>().unwrap();
(&mut *callback.lock().unwrap())(DataDeviceEvent::NewSelection(source.clone())); (&mut *callback.borrow_mut())(DataDeviceEvent::NewSelection(source.clone()));
// The client has kbd focus, it can set the selection // The client has kbd focus, it can set the selection
seat_data seat_data
.lock() .borrow_mut()
.unwrap()
.set_selection(source.map(Selection::Client).unwrap_or(Selection::Empty)); .set_selection(source.map(Selection::Client).unwrap_or(Selection::Empty));
return; return;
} }
@ -513,10 +512,9 @@ where
Request::Release => { Request::Release => {
// Clean up the known devices // Clean up the known devices
seat.user_data() seat.user_data()
.get::<Mutex<SeatData>>() .get::<RefCell<SeatData>>()
.unwrap()
.lock()
.unwrap() .unwrap()
.borrow_mut()
.known_devices .known_devices
.retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref()))) .retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref())))
} }

View File

@ -1,5 +1,6 @@
use std::cell::RefCell;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::sync::{Arc, Mutex}; use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{wl_data_device, wl_data_device_manager::DndAction, wl_data_offer, wl_pointer, wl_surface}, protocol::{wl_data_device, wl_data_device_manager::DndAction, wl_data_offer, wl_pointer, wl_surface},
@ -39,16 +40,16 @@ pub(crate) struct ServerDnDGrab<C: 'static> {
metadata: super::SourceMetadata, metadata: super::SourceMetadata,
current_focus: Option<wl_surface::WlSurface>, current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>, pending_offers: Vec<wl_data_offer::WlDataOffer>,
offer_data: Option<Arc<Mutex<OfferData>>>, offer_data: Option<Rc<RefCell<OfferData>>>,
seat: Seat, seat: Seat,
callback: Arc<Mutex<C>>, callback: Rc<RefCell<C>>,
} }
impl<C: 'static> ServerDnDGrab<C> { impl<C: 'static> ServerDnDGrab<C> {
pub(crate) fn new( pub(crate) fn new(
metadata: super::SourceMetadata, metadata: super::SourceMetadata,
seat: Seat, seat: Seat,
callback: Arc<Mutex<C>>, callback: Rc<RefCell<C>>,
) -> ServerDnDGrab<C> { ) -> ServerDnDGrab<C> {
ServerDnDGrab { ServerDnDGrab {
metadata, metadata,
@ -63,7 +64,7 @@ impl<C: 'static> ServerDnDGrab<C> {
impl<C> PointerGrab for ServerDnDGrab<C> impl<C> PointerGrab for ServerDnDGrab<C>
where where
C: FnMut(ServerDndEvent) + Send + 'static, C: FnMut(ServerDndEvent) + 'static,
{ {
fn motion( fn motion(
&mut self, &mut self,
@ -77,10 +78,9 @@ where
let seat_data = self let seat_data = self
.seat .seat
.user_data() .user_data()
.get::<Mutex<SeatData>>() .get::<RefCell<SeatData>>()
.unwrap() .unwrap()
.lock() .borrow_mut();
.unwrap();
if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() { if focus.as_ref().map(|&(ref s, _)| s) != self.current_focus.as_ref() {
// focus changed, we need to make a leave if appropriate // focus changed, we need to make a leave if appropriate
if let Some(surface) = self.current_focus.take() { if let Some(surface) = self.current_focus.take() {
@ -92,7 +92,7 @@ where
// disable the offers // disable the offers
self.pending_offers.clear(); self.pending_offers.clear();
if let Some(offer_data) = self.offer_data.take() { 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() { if self.current_focus.is_none() {
// We entered a new surface, send the data offer // 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, active: true,
dropped: false, dropped: false,
accepted: true, accepted: true,
@ -169,12 +169,11 @@ where
let seat_data = self let seat_data = self
.seat .seat
.user_data() .user_data()
.get::<Mutex<SeatData>>() .get::<RefCell<SeatData>>()
.unwrap() .unwrap()
.lock() .borrow_mut();
.unwrap();
let validated = if let Some(ref data) = self.offer_data { 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()) data.accepted && (!data.chosen_action.is_empty())
} else { } else {
false false
@ -191,14 +190,14 @@ where
} }
} }
if let Some(ref offer_data) = self.offer_data { 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 { if validated {
data.dropped = true; data.dropped = true;
} else { } else {
data.active = false; data.active = false;
} }
} }
let mut callback = self.callback.lock().unwrap(); let mut callback = self.callback.borrow_mut();
(&mut *callback)(ServerDndEvent::Dropped); (&mut *callback)(ServerDndEvent::Dropped);
if !validated { if !validated {
(&mut *callback)(ServerDndEvent::Cancelled); (&mut *callback)(ServerDndEvent::Cancelled);
@ -225,17 +224,17 @@ struct OfferData {
fn implement_dnd_data_offer<C>( fn implement_dnd_data_offer<C>(
offer: NewResource<wl_data_offer::WlDataOffer>, offer: NewResource<wl_data_offer::WlDataOffer>,
metadata: super::SourceMetadata, metadata: super::SourceMetadata,
offer_data: Arc<Mutex<OfferData>>, offer_data: Rc<RefCell<OfferData>>,
callback: Arc<Mutex<C>>, callback: Rc<RefCell<C>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>, action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
) -> wl_data_offer::WlDataOffer ) -> wl_data_offer::WlDataOffer
where where
C: FnMut(ServerDndEvent) + Send + 'static, C: FnMut(ServerDndEvent) + 'static,
{ {
use self::wl_data_offer::Request; use self::wl_data_offer::Request;
offer.implement_closure( offer.implement_closure(
move |req, offer| { move |req, offer| {
let mut data = offer_data.lock().unwrap(); let mut data = offer_data.borrow_mut();
match req { match req {
Request::Accept { serial: _, mime_type } => { Request::Accept { serial: _, mime_type } => {
if let Some(mtype) = mime_type { if let Some(mtype) = mime_type {
@ -247,7 +246,7 @@ where
Request::Receive { mime_type, fd } => { Request::Receive { mime_type, fd } => {
// check if the source and associated mime type is still valid // check if the source and associated mime type is still valid
if metadata.mime_types.contains(&mime_type) && data.active { 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 => {} Request::Destroy => {}
@ -276,7 +275,7 @@ where
"Cannot finish a data offer with no valid action.".into(), "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; data.active = false;
} }
Request::SetActions { Request::SetActions {
@ -292,13 +291,13 @@ where
} }
let possible_actions = metadata.dnd_action & DndAction::from_bits_truncate(dnd_actions); let possible_actions = metadata.dnd_action & DndAction::from_bits_truncate(dnd_actions);
data.chosen_action = 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 // check that the user provided callback respects that one precise action should be chosen
debug_assert!( debug_assert!(
[DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action)
); );
offer.action(data.chosen_action.to_raw()); 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!(), _ => unreachable!(),
} }

View File

@ -1,9 +1,10 @@
use crate::backend::input::KeyState; use crate::backend::input::KeyState;
use std::{ use std::{
cell::RefCell,
default::Default, default::Default,
io::{Error as IoError, Write}, io::{Error as IoError, Write},
os::unix::io::AsRawFd, os::unix::io::AsRawFd,
sync::{Arc, Mutex}, rc::Rc,
}; };
use tempfile::tempfile; use tempfile::tempfile;
use wayland_server::{ use wayland_server::{
@ -253,24 +254,23 @@ where
let keymap = internal.keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1); let keymap = internal.keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1);
Ok(KeyboardHandle { Ok(KeyboardHandle {
arc: Arc::new(KbdArc { arc: Rc::new(KbdRc {
internal: Mutex::new(internal), internal: RefCell::new(internal),
keymap, keymap,
logger: log, logger: log,
}), }),
}) })
} }
struct KbdArc { struct KbdRc {
internal: Mutex<KbdInternal>, internal: RefCell<KbdInternal>,
keymap: String, keymap: String,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
/// An handle to a keyboard handler /// An handle to a keyboard handler
/// ///
/// It can be cloned and all clones manipulate the same internal state. Clones /// It can be cloned and all clones manipulate the same internal state.
/// can also be sent across threads.
/// ///
/// This handle gives you 2 main ways to interact with the keyboard handling: /// This handle gives you 2 main ways to interact with the keyboard handling:
/// ///
@ -281,7 +281,7 @@ struct KbdArc {
/// details. /// details.
#[derive(Clone)] #[derive(Clone)]
pub struct KeyboardHandle { pub struct KeyboardHandle {
arc: Arc<KbdArc>, arc: Rc<KbdRc>,
} }
impl KeyboardHandle { impl KeyboardHandle {
@ -302,7 +302,7 @@ impl KeyboardHandle {
F: FnOnce(&ModifiersState, Keysym) -> bool, F: FnOnce(&ModifiersState, Keysym) -> bool,
{ {
trace!(self.arc.logger, "Handling keystroke"; "keycode" => keycode, "state" => format_args!("{:?}", state)); 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 // Offset the keycode by 8, as the evdev XKB rules reflect X's
// broken keycode system, which starts at 8. // broken keycode system, which starts at 8.
@ -350,7 +350,7 @@ impl KeyboardHandle {
/// event, and if the new focus is not `None`, /// 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. /// 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) { 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 let same = guard
.focus .focus
@ -394,8 +394,7 @@ impl KeyboardHandle {
pub fn has_focus(&self, client: &Client) -> bool { pub fn has_focus(&self, client: &Client) -> bool {
self.arc self.arc
.internal .internal
.lock() .borrow_mut()
.unwrap()
.focus .focus
.as_ref() .as_ref()
.and_then(|f| f.as_ref().client()) .and_then(|f| f.as_ref().client())
@ -431,7 +430,7 @@ impl KeyboardHandle {
return; return;
}; };
let mut guard = self.arc.internal.lock().unwrap(); let mut guard = self.arc.internal.borrow_mut();
if kbd.as_ref().version() >= 4 { if kbd.as_ref().version() >= 4 {
kbd.repeat_info(guard.repeat_rate, guard.repeat_delay); kbd.repeat_info(guard.repeat_rate, guard.repeat_delay);
} }
@ -440,7 +439,7 @@ impl KeyboardHandle {
/// Change the repeat info configured for this keyboard /// Change the repeat info configured for this keyboard
pub fn change_repeat_info(&self, rate: i32, delay: i32) { 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_delay = delay;
guard.repeat_rate = rate; guard.repeat_rate = rate;
for kbd in &guard.known_kbds { for kbd in &guard.known_kbds {
@ -458,8 +457,7 @@ pub(crate) fn implement_keyboard(
let arc = h.arc.clone(); let arc = h.arc.clone();
Some(move |keyboard: WlKeyboard| { Some(move |keyboard: WlKeyboard| {
arc.internal arc.internal
.lock() .borrow_mut()
.unwrap()
.known_kbds .known_kbds
.retain(|k| !k.as_ref().equals(&keyboard.as_ref())) .retain(|k| !k.as_ref().equals(&keyboard.as_ref()))
}) })

View File

@ -43,7 +43,7 @@
//! These methods return handles that can be cloned and sent across thread, so you can keep one around //! 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. //! 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 keyboard;
mod pointer; mod pointer;
@ -70,8 +70,8 @@ struct Inner {
known_seats: Vec<wl_seat::WlSeat>, known_seats: Vec<wl_seat::WlSeat>,
} }
pub(crate) struct SeatArc { pub(crate) struct SeatRc {
inner: Mutex<Inner>, inner: RefCell<Inner>,
user_data: UserDataMap, user_data: UserDataMap,
pub(crate) log: ::slog::Logger, pub(crate) log: ::slog::Logger,
name: String, name: String,
@ -104,13 +104,12 @@ impl Inner {
/// ///
/// It is directly inserted in the event loop by its [`new`](Seat::new) method. /// 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 /// This is an handle to the inner logic, it can be cloned.
/// threads.
/// ///
/// See module-level documentation for details of use. /// See module-level documentation for details of use.
#[derive(Clone)] #[derive(Clone)]
pub struct Seat { pub struct Seat {
pub(crate) arc: Arc<SeatArc>, pub(crate) arc: Rc<SeatRc>,
} }
impl Seat { impl Seat {
@ -134,8 +133,8 @@ impl Seat {
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
{ {
let log = crate::slog_or_stdlog(logger); let log = crate::slog_or_stdlog(logger);
let arc = Arc::new(SeatArc { let arc = Rc::new(SeatRc {
inner: Mutex::new(Inner { inner: RefCell::new(Inner {
pointer: None, pointer: None,
keyboard: None, keyboard: None,
known_seats: Vec::new(), known_seats: Vec::new(),
@ -147,7 +146,7 @@ impl Seat {
let seat = Seat { arc: arc.clone() }; let seat = Seat { arc: arc.clone() };
let global = display.create_global(5, move |new_seat, _version| { let global = display.create_global(5, move |new_seat, _version| {
let seat = implement_seat(new_seat, arc.clone(), token.clone()); 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 { if seat.as_ref().version() >= 2 {
seat.name(arc.name.clone()); seat.name(arc.name.clone());
} }
@ -160,7 +159,7 @@ impl Seat {
/// Attempt to retrieve a [`Seat`] from an existing resource /// Attempt to retrieve a [`Seat`] from an existing resource
pub fn from_resource(seat: &wl_seat::WlSeat) -> Option<Seat> { pub fn from_resource(seat: &wl_seat::WlSeat) -> Option<Seat> {
seat.as_ref() seat.as_ref()
.user_data::<Arc<SeatArc>>() .user_data::<Rc<SeatRc>>()
.cloned() .cloned()
.map(|arc| Seat { arc }) .map(|arc| Seat { arc })
} }
@ -173,7 +172,7 @@ impl Seat {
/// Adds the pointer capability to this seat /// Adds the pointer capability to this seat
/// ///
/// You are provided a [`PointerHandle`], which allows you to send input events /// 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 /// 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 /// will overwrite it, and will be seen by the clients as if the
@ -212,9 +211,9 @@ impl Seat {
where where
U: 'static, U: 'static,
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + '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); let pointer = self::pointer::create_pointer_handler(token, cb);
if inner.pointer.is_some() { if inner.pointer.is_some() {
// there is already a pointer, remove it and notify the clients // 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 /// Access the pointer of this seat if any
pub fn get_pointer(&self) -> Option<PointerHandle> { pub fn get_pointer(&self) -> Option<PointerHandle> {
self.arc.inner.lock().unwrap().pointer.clone() self.arc.inner.borrow_mut().pointer.clone()
} }
/// Remove the pointer capability from this seat /// Remove the pointer capability from this seat
/// ///
/// Clients will be appropriately notified. /// Clients will be appropriately notified.
pub fn remove_pointer(&mut self) { 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() { if inner.pointer.is_some() {
inner.pointer = None; inner.pointer = None;
inner.send_all_caps(); inner.send_all_caps();
@ -246,7 +245,7 @@ impl Seat {
/// Adds the keyboard capability to this seat /// Adds the keyboard capability to this seat
/// ///
/// You are provided a [`KeyboardHandle`], which allows you to send input events /// 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 /// 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 /// 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, F: FnMut(&Seat, Option<&wl_surface::WlSurface>) + 'static,
{ {
let me = self.clone(); 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( let keyboard = self::keyboard::create_keyboard_handler(
xkb_config, xkb_config,
repeat_delay, repeat_delay,
@ -310,14 +309,14 @@ impl Seat {
/// Access the keyboard of this seat if any /// Access the keyboard of this seat if any
pub fn get_keyboard(&self) -> Option<KeyboardHandle> { pub fn get_keyboard(&self) -> Option<KeyboardHandle> {
self.arc.inner.lock().unwrap().keyboard.clone() self.arc.inner.borrow_mut().keyboard.clone()
} }
/// Remove the keyboard capability from this seat /// Remove the keyboard capability from this seat
/// ///
/// Clients will be appropriately notified. /// Clients will be appropriately notified.
pub fn remove_keyboard(&mut self) { 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() { if inner.keyboard.is_some() {
inner.keyboard = None; inner.keyboard = None;
inner.send_all_caps(); inner.send_all_caps();
@ -326,20 +325,20 @@ impl Seat {
/// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`] /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`]
pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool { 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())) inner.known_seats.iter().any(|s| s.as_ref().equals(seat.as_ref()))
} }
} }
impl ::std::cmp::PartialEq for Seat { impl ::std::cmp::PartialEq for Seat {
fn eq(&self, other: &Seat) -> bool { fn eq(&self, other: &Seat) -> bool {
Arc::ptr_eq(&self.arc, &other.arc) Rc::ptr_eq(&self.arc, &other.arc)
} }
} }
fn implement_seat<U, R>( fn implement_seat<U, R>(
new_seat: NewResource<wl_seat::WlSeat>, new_seat: NewResource<wl_seat::WlSeat>,
arc: Arc<SeatArc>, arc: Rc<SeatRc>,
token: CompositorToken<U, R>, token: CompositorToken<U, R>,
) -> wl_seat::WlSeat ) -> wl_seat::WlSeat
where where
@ -349,8 +348,8 @@ where
let dest_arc = arc.clone(); let dest_arc = arc.clone();
new_seat.implement_closure( new_seat.implement_closure(
move |request, seat| { move |request, seat| {
let arc = seat.as_ref().user_data::<Arc<SeatArc>>().unwrap(); let arc = seat.as_ref().user_data::<Rc<SeatRc>>().unwrap();
let inner = arc.inner.lock().unwrap(); let inner = arc.inner.borrow_mut();
match request { match request {
wl_seat::Request::GetPointer { id } => { wl_seat::Request::GetPointer { id } => {
let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref(), token.clone()); let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref(), token.clone());
@ -381,8 +380,7 @@ where
Some(move |seat: wl_seat::WlSeat| { Some(move |seat: wl_seat::WlSeat| {
dest_arc dest_arc
.inner .inner
.lock() .borrow_mut()
.unwrap()
.known_seats .known_seats
.retain(|s| !s.as_ref().equals(&seat.as_ref())); .retain(|s| !s.as_ref().equals(&seat.as_ref()));
}), }),

View File

@ -1,4 +1,6 @@
use std::sync::{Arc, Mutex}; use std::cell::RefCell;
use std::rc::Rc;
use wayland_server::{ use wayland_server::{
protocol::{ protocol::{
wl_pointer::{self, Axis, AxisSource, ButtonState, Event, Request, WlPointer}, wl_pointer::{self, Axis, AxisSource, ButtonState, Event, Request, WlPointer},
@ -48,7 +50,7 @@ impl PointerInternal {
where where
U: 'static, U: 'static,
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
F: FnMut(CursorImageStatus) + Send + 'static, F: FnMut(CursorImageStatus) + 'static,
{ {
let mut old_status = CursorImageStatus::Default; let mut old_status = CursorImageStatus::Default;
let wrapper = move |new_status: CursorImageStatus| { let wrapper = move |new_status: CursorImageStatus| {
@ -117,8 +119,7 @@ impl PointerInternal {
/// An handle to a pointer handler /// An handle to a pointer handler
/// ///
/// It can be cloned and all clones manipulate the same internal state. Clones /// It can be cloned and all clones manipulate the same internal state.
/// can also be sent across threads.
/// ///
/// This handle gives you access to an interface to send pointer events to your /// This handle gives you access to an interface to send pointer events to your
/// clients. /// clients.
@ -127,12 +128,12 @@ impl PointerInternal {
/// grab if any is active. See the [`PointerGrab`] trait for details. /// grab if any is active. See the [`PointerGrab`] trait for details.
#[derive(Clone)] #[derive(Clone)]
pub struct PointerHandle { pub struct PointerHandle {
inner: Arc<Mutex<PointerInternal>>, inner: Rc<RefCell<PointerInternal>>,
} }
impl PointerHandle { impl PointerHandle {
pub(crate) fn new_pointer(&self, pointer: WlPointer) { 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); guard.known_pointers.push(pointer);
} }
@ -140,17 +141,17 @@ impl PointerHandle {
/// ///
/// Overwrites any current grab. /// Overwrites any current grab.
pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: u32) { pub fn set_grab<G: PointerGrab + 'static>(&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 /// Remove any current grab on this pointer, reseting it to the default behavior
pub fn unset_grab(&self) { 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 /// Check if this pointer is currently grabbed with this serial
pub fn has_grab(&self, serial: u32) -> bool { pub fn has_grab(&self, serial: u32) -> bool {
let guard = self.inner.lock().unwrap(); let guard = self.inner.borrow_mut();
match guard.grab { match guard.grab {
GrabStatus::Active(s, _) => s == serial, GrabStatus::Active(s, _) => s == serial,
_ => false, _ => false,
@ -159,7 +160,7 @@ impl PointerHandle {
/// Check if this pointer is currently being grabbed /// Check if this pointer is currently being grabbed
pub fn is_grabbed(&self) -> bool { pub fn is_grabbed(&self) -> bool {
let guard = self.inner.lock().unwrap(); let guard = self.inner.borrow_mut();
match guard.grab { match guard.grab {
GrabStatus::None => false, GrabStatus::None => false,
_ => true, _ => true,
@ -184,7 +185,7 @@ impl PointerHandle {
serial: u32, serial: u32,
time: u32, time: u32,
) { ) {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.borrow_mut();
inner.pending_focus = focus.clone(); inner.pending_focus = focus.clone();
inner.with_grab(move |mut handle, grab| { inner.with_grab(move |mut handle, grab| {
grab.motion(&mut handle, location, focus, serial, time); 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 /// This will internally send the appropriate button event to the client
/// objects matching with the currently focused surface. /// objects matching with the currently focused surface.
pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) { 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 { match state {
ButtonState::Pressed => { ButtonState::Pressed => {
inner.pressed_buttons.push(button); 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. /// A single frame will group multiple scroll events as if they happened in the same instance.
pub fn axis(&self, details: AxisFrame) { 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); grab.axis(&mut handle, details);
}); });
} }
@ -517,10 +518,10 @@ pub(crate) fn create_pointer_handler<F, U, R>(token: CompositorToken<U, R>, cb:
where where
R: Role<CursorImageRole> + 'static, R: Role<CursorImageRole> + 'static,
U: 'static, U: 'static,
F: FnMut(CursorImageStatus) + Send + 'static, F: FnMut(CursorImageStatus) + 'static,
{ {
PointerHandle { 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() { let destructor = match inner.clone() {
Some(inner) => Some(move |pointer: WlPointer| { Some(inner) => Some(move |pointer: WlPointer| {
inner inner
.lock() .borrow_mut()
.unwrap()
.known_pointers .known_pointers
.retain(|p| !p.as_ref().equals(&pointer.as_ref())) .retain(|p| !p.as_ref().equals(&pointer.as_ref()))
}), }),
@ -554,7 +554,7 @@ where
hotspot_y, hotspot_y,
} => { } => {
if let Some(ref inner) = inner { 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 // only allow setting the cursor icon if the current pointer focus
// is of the same client // is of the same client
let PointerInternal { let PointerInternal {