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::{
protocol::{
@ -20,8 +20,8 @@ pub struct SourceMetadata {
pub(crate) fn implement_data_source(src: NewResource<WlDataSource>) -> WlDataSource {
src.implement_closure(
|req, me| {
let data: &Mutex<SourceMetadata> = me.as_ref().user_data().unwrap();
let mut guard = data.lock().unwrap();
let data: &RefCell<SourceMetadata> = 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<WlDataSource>) -> WlDataSou
}
},
None::<fn(_)>,
Mutex::new(SourceMetadata {
RefCell::new(SourceMetadata {
mime_types: Vec::new(),
dnd_action: DndAction::None,
}),
@ -44,8 +44,8 @@ pub fn with_source_metadata<T, F: FnOnce(&SourceMetadata) -> T>(
source: &WlDataSource,
f: F,
) -> Result<T, ()> {
match source.as_ref().user_data::<Mutex<SourceMetadata>>() {
Some(data) => Ok(f(&data.lock().unwrap())),
match source.as_ref().user_data::<RefCell<SourceMetadata>>() {
Some(data) => Ok(f(&data.borrow())),
None => Err(()),
}
}

View File

@ -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<U, R> {
data_source: Option<wl_data_source::WlDataSource>,
current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>,
offer_data: Option<Arc<Mutex<OfferData>>>,
offer_data: Option<Rc<RefCell<OfferData>>>,
icon: Option<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>,
seat: Seat,
}
@ -34,7 +35,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
seat: Seat,
icon: Option<wl_surface::WlSurface>,
token: CompositorToken<U, R>,
callback: Arc<Mutex<dyn FnMut(super::DataDeviceEvent) + Send>>,
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
) -> DnDGrab<U, R> {
DnDGrab {
data_source: source,
@ -63,10 +64,9 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
let seat_data = self
.seat
.user_data()
.get::<Mutex<SeatData>>()
.get::<RefCell<SeatData>>()
.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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
// 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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
let seat_data = self
.seat
.user_data()
.get::<Mutex<SeatData>>()
.get::<RefCell<SeatData>>()
.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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
}
}
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<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
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::<super::DnDIconRole>(&icon).unwrap();
@ -238,13 +237,13 @@ struct OfferData {
fn implement_dnd_data_offer(
offer: NewResource<wl_data_offer::WlDataOffer>,
source: wl_data_source::WlDataSource,
offer_data: Arc<Mutex<OfferData>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>,
offer_data: Rc<RefCell<OfferData>>,
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> 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)

View File

@ -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<F, C, U, R, L>(
logger: L,
) -> Global<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<DnDIconRole> + 'static,
U: 'static,
L: Into<Option<::slog::Logger>>,
{
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<Client>) {
// 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::<Mutex<SeatData>>().unwrap();
seat_data.lock().unwrap().set_focus(client);
let seat_data = seat.user_data().get::<RefCell<SeatData>>().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<Client>) {
pub fn set_data_device_selection(seat: &Seat, mime_types: Vec<String>) {
// 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::<Mutex<SeatData>>().unwrap();
let seat_data = seat.user_data().get::<RefCell<SeatData>>().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<String>) {
/// 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)
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<F, C, U, R>(
new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>,
callback: Arc<Mutex<C>>,
action_choice: Arc<Mutex<F>>,
callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>,
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<DnDIconRole> + '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::<Mutex<SeatData>>().unwrap();
.insert_if_missing(|| RefCell::new(SeatData::new(log.clone())));
let seat_data = seat.user_data().get::<RefCell<SeatData>>().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<Mutex<dyn FnMut(DataDeviceEvent) + Send + 'static>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>,
callback: Rc<RefCell<dyn FnMut(DataDeviceEvent) + 'static>>,
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
}
fn implement_data_device<F, C, U, R>(
new_dd: NewResource<wl_data_device::WlDataDevice>,
seat: Seat,
callback: Arc<Mutex<C>>,
action_choice: Arc<Mutex<F>>,
callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>,
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<DnDIconRole> + '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::<Mutex<SeatData>>().unwrap();
(&mut *callback.lock().unwrap())(DataDeviceEvent::NewSelection(source.clone()));
let seat_data = seat.user_data().get::<RefCell<SeatData>>().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::<Mutex<SeatData>>()
.unwrap()
.lock()
.get::<RefCell<SeatData>>()
.unwrap()
.borrow_mut()
.known_devices
.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::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<C: 'static> {
metadata: super::SourceMetadata,
current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>,
offer_data: Option<Arc<Mutex<OfferData>>>,
offer_data: Option<Rc<RefCell<OfferData>>>,
seat: Seat,
callback: Arc<Mutex<C>>,
callback: Rc<RefCell<C>>,
}
impl<C: 'static> ServerDnDGrab<C> {
pub(crate) fn new(
metadata: super::SourceMetadata,
seat: Seat,
callback: Arc<Mutex<C>>,
callback: Rc<RefCell<C>>,
) -> ServerDnDGrab<C> {
ServerDnDGrab {
metadata,
@ -63,7 +64,7 @@ impl<C: 'static> ServerDnDGrab<C> {
impl<C> PointerGrab for ServerDnDGrab<C>
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::<Mutex<SeatData>>()
.get::<RefCell<SeatData>>()
.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::<Mutex<SeatData>>()
.get::<RefCell<SeatData>>()
.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<C>(
offer: NewResource<wl_data_offer::WlDataOffer>,
metadata: super::SourceMetadata,
offer_data: Arc<Mutex<OfferData>>,
callback: Arc<Mutex<C>>,
action_choice: Arc<Mutex<dyn FnMut(DndAction, DndAction) -> DndAction + Send + 'static>>,
offer_data: Rc<RefCell<OfferData>>,
callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> 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!(),
}

View File

@ -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<KbdInternal>,
struct KbdRc {
internal: RefCell<KbdInternal>,
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<KbdArc>,
arc: Rc<KbdRc>,
}
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()))
})

View File

@ -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<wl_seat::WlSeat>,
}
pub(crate) struct SeatArc {
inner: Mutex<Inner>,
pub(crate) struct SeatRc {
inner: RefCell<Inner>,
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<SeatArc>,
pub(crate) arc: Rc<SeatRc>,
}
impl Seat {
@ -134,8 +133,8 @@ impl Seat {
L: Into<Option<::slog::Logger>>,
{
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> {
seat.as_ref()
.user_data::<Arc<SeatArc>>()
.user_data::<Rc<SeatRc>>()
.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<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);
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<PointerHandle> {
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<KeyboardHandle> {
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<U, R>(
new_seat: NewResource<wl_seat::WlSeat>,
arc: Arc<SeatArc>,
arc: Rc<SeatRc>,
token: CompositorToken<U, R>,
) -> 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::<Arc<SeatArc>>().unwrap();
let inner = arc.inner.lock().unwrap();
let arc = seat.as_ref().user_data::<Rc<SeatRc>>().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()));
}),

View File

@ -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<CursorImageRole> + '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<Mutex<PointerInternal>>,
inner: Rc<RefCell<PointerInternal>>,
}
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<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
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<F, U, R>(token: CompositorToken<U, R>, cb:
where
R: Role<CursorImageRole> + '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 {