Don't promise thread-safety that we can't respect
This commit is contained in:
parent
3f2857fbf3
commit
3d8f22c805
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())))
|
||||
}
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
})
|
||||
|
|
|
@ -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()));
|
||||
}),
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue