1
0
Fork 0
forked from wry/wry

wayland: implement wlr-data-control

This commit is contained in:
Julian Orth 2024-03-31 01:36:45 +01:00
parent 8bca8b0e86
commit 99be020c19
18 changed files with 985 additions and 33 deletions

View file

@ -3,7 +3,9 @@ use {
client::{Client, ClientError, ClientId},
fixed::Fixed,
ifs::{
ipc::x_data_device::XIpcDevice,
ipc::{
x_data_device::XIpcDevice, zwlr_data_control_device_v1::ZwlrDataControlDeviceV1,
},
wl_seat::{WlSeatError, WlSeatGlobal},
},
utils::{
@ -31,6 +33,10 @@ pub mod wl_data_source;
pub mod x_data_device;
pub mod x_data_offer;
pub mod x_data_source;
pub mod zwlr_data_control_device_v1;
pub mod zwlr_data_control_manager_v1;
pub mod zwlr_data_control_offer_v1;
pub mod zwlr_data_control_source_v1;
pub mod zwp_primary_selection_device_manager_v1;
pub mod zwp_primary_selection_device_v1;
pub mod zwp_primary_selection_offer_v1;
@ -60,8 +66,9 @@ pub trait DynDataSource: 'static {
fn send_send(&self, mime_type: &str, fd: Rc<OwnedFd>);
fn offer_to_regular_client(self: Rc<Self>, client: &Rc<Client>);
fn offer_to_x(self: Rc<Self>, dd: &Rc<XIpcDevice>);
fn offer_to_wlr_device(self: Rc<Self>, dd: &Rc<ZwlrDataControlDeviceV1>);
fn detach_seat(&self, seat: &Rc<WlSeatGlobal>);
fn cancel_offers(&self);
fn cancel_unprivileged_offers(&self);
fn send_target(&self, mime_type: Option<&str>) {
let _ = mime_type;
@ -98,6 +105,10 @@ pub trait DynDataOffer: 'static {
fn cancel(&self);
fn get_seat(&self) -> Rc<WlSeatGlobal>;
fn is_privileged(&self) -> bool {
false
}
fn send_action(&self, action: u32) {
let _ = action;
log::warn!(
@ -129,6 +140,12 @@ pub trait IterableIpcVtable: IpcVtable {
C: FnMut(&Rc<Self::Device>);
}
pub trait WlrIpcVtable: IpcVtable<Device = ZwlrDataControlDeviceV1> {
fn for_each_device<C>(seat: &WlSeatGlobal, f: C)
where
C: FnMut(&Rc<Self::Device>);
}
pub trait IpcVtable: Sized {
const LOCATION: IpcLocation;
@ -277,11 +294,17 @@ pub fn attach_seat<S: DynDataSource>(
Ok(())
}
pub fn cancel_offers<S: DynDataSource>(src: &S) {
pub fn cancel_offers<S: DynDataSource>(src: &S, cancel_privileged: bool) {
let data = src.source_data();
while let Some((_, offer)) = data.offers.pop() {
offer.cancel();
}
let mut offers = data.offers.take();
offers.retain(|o| {
let retain = !cancel_privileged && o.1.is_privileged();
if !retain {
o.1.cancel();
}
retain
});
data.offers.replace(offers);
}
pub fn cancel_offer<T: IpcVtable>(offer: &T::Offer) {
@ -293,7 +316,7 @@ pub fn cancel_offer<T: IpcVtable>(offer: &T::Offer) {
pub fn detach_seat<S: DataSource>(src: &S, seat: &Rc<WlSeatGlobal>) {
let data = src.source_data();
data.seat.set(None);
cancel_offers(src);
cancel_offers(src, true);
if !data.state.get().contains(SOURCE_STATE_FINISHED) {
src.send_cancelled(seat);
}
@ -342,12 +365,23 @@ where
S: DynDataSource,
{
let data = src.source_data();
src.cancel_offers();
src.cancel_unprivileged_offers();
let shared = data.shared.get();
shared.role.set(data.role.get());
offer_source_to_device::<T, S>(src, dd, data, shared);
}
pub fn offer_source_to_wlr_device<T, S>(src: &Rc<S>, dd: &Rc<T::Device>)
where
T: IpcVtable<Device = ZwlrDataControlDeviceV1>,
S: DynDataSource,
{
let data = src.source_data();
let shared = data.shared.get();
shared.role.set(data.role.get());
offer_source_to_device::<T, _>(src, dd, data, shared);
}
fn offer_source_to_regular_client<T: IterableIpcVtable, S: DynDataSource>(
src: &Rc<S>,
client: &Rc<Client>,
@ -360,7 +394,7 @@ fn offer_source_to_regular_client<T: IterableIpcVtable, S: DynDataSource>(
return;
}
};
src.cancel_offers();
src.cancel_unprivileged_offers();
let shared = data.shared.get();
shared.role.set(data.role.get());
T::for_each_device(&seat, client.id, |dd| {