use std::cell::RefCell; use std::sync::Arc; use wayland_protocols_wlr::data_control::v1::server::zwlr_data_control_device_v1::{ self, ZwlrDataControlDeviceV1, }; use wayland_server::protocol::wl_seat::WlSeat; use wayland_server::{Client, Dispatch, DisplayHandle}; use crate::input::Seat; use crate::wayland::selection::device::SelectionDevice; use crate::wayland::selection::offer::OfferReplySource; use crate::wayland::selection::seat_data::SeatData; use crate::wayland::selection::source::SelectionSourceProvider; use crate::wayland::selection::{SelectionSource, SelectionTarget}; use super::{DataControlHandler, DataControlState}; #[allow(missing_debug_implementations)] #[doc(hidden)] pub struct DataControlDeviceUserData { pub(crate) primary_selection_filter: Arc Fn(&'c Client) -> bool + Send + Sync>>, pub(crate) wl_seat: WlSeat, } impl Dispatch for DataControlState where D: Dispatch, D: DataControlHandler, D: 'static, { fn request( handler: &mut D, client: &Client, resource: &ZwlrDataControlDeviceV1, request: ::Request, data: &DataControlDeviceUserData, dh: &DisplayHandle, _: &mut wayland_server::DataInit<'_, D>, ) { let seat = match Seat::::from_resource(&data.wl_seat) { Some(seat) => seat, None => return, }; match request { zwlr_data_control_device_v1::Request::SetSelection { source, .. } => { seat.user_data() .insert_if_missing(|| RefCell::new(SeatData::::new())); let source = source.map(SelectionSourceProvider::WlrDataControl); handler.new_selection( SelectionTarget::Clipboard, source.clone().map(|provider| SelectionSource { provider }), seat.clone(), ); seat.user_data() .get::>>() .unwrap() .borrow_mut() .set_clipboard_selection::(dh, source.map(OfferReplySource::Client)); } zwlr_data_control_device_v1::Request::SetPrimarySelection { source, .. } => { // When the primary selection is disabled, we should simply ignore the requests. if !(*data.primary_selection_filter)(client) { return; } seat.user_data() .insert_if_missing(|| RefCell::new(SeatData::::new())); let source = source.map(SelectionSourceProvider::WlrDataControl); handler.new_selection( SelectionTarget::Primary, source.clone().map(|provider| SelectionSource { provider }), seat.clone(), ); seat.user_data() .get::>>() .unwrap() .borrow_mut() .set_primary_selection::(dh, source.map(OfferReplySource::Client)); } zwlr_data_control_device_v1::Request::Destroy => seat .user_data() .get::>>() .unwrap() .borrow_mut() .retain_devices(|ndd| match ndd { SelectionDevice::WlrDataControl(ndd) => ndd != resource, _ => true, }), _ => unreachable!(), } } }