use std::cell::RefCell; use wayland_protocols::ext::data_control::v1::server::ext_data_control_device_v1::{ self, ExtDataControlDeviceV1, }; 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}; #[doc(hidden)] #[derive(Debug)] pub struct ExtDataControlDeviceUserData { pub(crate) primary: bool, pub(crate) wl_seat: WlSeat, } impl Dispatch for DataControlState where D: Dispatch, D: DataControlHandler, D: 'static, { fn request( handler: &mut D, _client: &Client, resource: &ExtDataControlDeviceV1, request: ::Request, data: &ExtDataControlDeviceUserData, dh: &DisplayHandle, _: &mut wayland_server::DataInit<'_, D>, ) { let seat = match Seat::::from_resource(&data.wl_seat) { Some(seat) => seat, None => return, }; match request { ext_data_control_device_v1::Request::SetSelection { source, .. } => { seat.user_data() .insert_if_missing(|| RefCell::new(SeatData::::new())); let source = source.map(SelectionSourceProvider::ExtDataControl); 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)); } ext_data_control_device_v1::Request::SetPrimarySelection { source, .. } => { // When the primary selection is disabled, we should simply ignore the requests. if !data.primary { return; } seat.user_data() .insert_if_missing(|| RefCell::new(SeatData::::new())); let source = source.map(SelectionSourceProvider::ExtDataControl); 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)); } ext_data_control_device_v1::Request::Destroy => seat .user_data() .get::>>() .unwrap() .borrow_mut() .retain_devices(|ndd| match ndd { SelectionDevice::ExtDataControl(ndd) => ndd != resource, _ => true, }), _ => unreachable!(), } } }