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::{
|
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(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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())))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
})
|
})
|
||||||
|
|
|
@ -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()));
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue