2022-07-04 15:26:26 +02:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
|
|
2022-07-04 16:00:29 +02:00
|
|
|
use crate::state::State;
|
2022-07-04 15:26:26 +02:00
|
|
|
use smithay::{
|
2022-07-04 16:00:29 +02:00
|
|
|
delegate_data_device,
|
2022-08-31 13:01:23 +02:00
|
|
|
input::Seat,
|
2022-07-04 16:00:29 +02:00
|
|
|
reexports::wayland_server::protocol::{wl_data_source::WlDataSource, wl_surface::WlSurface},
|
2022-08-30 13:28:36 +02:00
|
|
|
utils::IsAlive,
|
2022-08-31 13:01:23 +02:00
|
|
|
wayland::data_device::{
|
2023-02-13 17:44:24 +01:00
|
|
|
with_source_metadata, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
|
|
|
|
|
ServerDndGrabHandler,
|
2022-07-04 15:26:26 +02:00
|
|
|
},
|
2023-02-13 17:44:24 +01:00
|
|
|
xwayland::xwm::{SelectionType, XwmId},
|
2022-07-04 15:26:26 +02:00
|
|
|
};
|
2023-02-13 17:44:24 +01:00
|
|
|
use std::{cell::RefCell, os::unix::io::OwnedFd};
|
2023-02-24 17:41:52 +01:00
|
|
|
use tracing::warn;
|
2022-07-04 15:26:26 +02:00
|
|
|
|
|
|
|
|
pub struct DnDIcon {
|
|
|
|
|
surface: RefCell<Option<WlSurface>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_dnd_icon(seat: &Seat<State>) -> Option<WlSurface> {
|
|
|
|
|
let userdata = seat.user_data();
|
|
|
|
|
userdata
|
|
|
|
|
.get::<DnDIcon>()
|
|
|
|
|
.and_then(|x| x.surface.borrow().clone())
|
2022-08-05 16:28:05 +02:00
|
|
|
.filter(IsAlive::alive)
|
2022-07-04 15:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ClientDndGrabHandler for State {
|
|
|
|
|
fn started(
|
2022-07-04 16:00:29 +02:00
|
|
|
&mut self,
|
|
|
|
|
_source: Option<WlDataSource>,
|
|
|
|
|
icon: Option<WlSurface>,
|
|
|
|
|
seat: Seat<Self>,
|
2022-07-04 15:26:26 +02:00
|
|
|
) {
|
|
|
|
|
let user_data = seat.user_data();
|
|
|
|
|
user_data.insert_if_missing(|| DnDIcon {
|
|
|
|
|
surface: RefCell::new(None),
|
|
|
|
|
});
|
|
|
|
|
*user_data.get::<DnDIcon>().unwrap().surface.borrow_mut() = icon;
|
|
|
|
|
}
|
|
|
|
|
fn dropped(&mut self, seat: Seat<Self>) {
|
|
|
|
|
seat.user_data()
|
|
|
|
|
.get::<DnDIcon>()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.surface
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.take();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
impl ServerDndGrabHandler for State {}
|
|
|
|
|
impl DataDeviceHandler for State {
|
2023-02-13 17:44:24 +01:00
|
|
|
type SelectionUserData = XwmId;
|
|
|
|
|
|
2022-07-04 15:26:26 +02:00
|
|
|
fn data_device_state(&self) -> &DataDeviceState {
|
|
|
|
|
&self.common.data_device_state
|
|
|
|
|
}
|
2023-02-13 17:44:24 +01:00
|
|
|
|
2023-04-18 17:10:21 +02:00
|
|
|
fn new_selection(&mut self, source: Option<WlDataSource>, _seat: Seat<State>) {
|
2023-03-07 20:28:41 +01:00
|
|
|
if let Some(state) = self.common.xwayland_state.as_mut() {
|
|
|
|
|
if let Some(xwm) = state.xwm.as_mut() {
|
2023-02-13 17:44:24 +01:00
|
|
|
if let Some(source) = &source {
|
|
|
|
|
if let Ok(Err(err)) = with_source_metadata(source, |metadata| {
|
|
|
|
|
xwm.new_selection(
|
|
|
|
|
SelectionType::Clipboard,
|
|
|
|
|
Some(metadata.mime_types.clone()),
|
|
|
|
|
)
|
|
|
|
|
}) {
|
2023-02-24 17:41:52 +01:00
|
|
|
warn!(?err, "Failed to set Xwayland clipboard selection.");
|
2023-02-13 17:44:24 +01:00
|
|
|
}
|
|
|
|
|
} else if let Err(err) = xwm.new_selection(SelectionType::Clipboard, None) {
|
2023-02-24 17:41:52 +01:00
|
|
|
warn!(?err, "Failed to clear Xwayland clipboard selection.");
|
2023-02-13 17:44:24 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn send_selection(
|
|
|
|
|
&mut self,
|
|
|
|
|
mime_type: String,
|
|
|
|
|
fd: OwnedFd,
|
2023-04-18 17:10:21 +02:00
|
|
|
_seat: Seat<State>,
|
2023-03-07 20:28:41 +01:00
|
|
|
_user_data: &Self::SelectionUserData,
|
2023-02-13 17:44:24 +01:00
|
|
|
) {
|
|
|
|
|
if let Some(xwm) = self
|
|
|
|
|
.common
|
|
|
|
|
.xwayland_state
|
2023-03-07 20:28:41 +01:00
|
|
|
.as_mut()
|
|
|
|
|
.and_then(|xstate| xstate.xwm.as_mut())
|
2023-02-13 17:44:24 +01:00
|
|
|
{
|
|
|
|
|
if let Err(err) = xwm.send_selection(
|
|
|
|
|
SelectionType::Clipboard,
|
|
|
|
|
mime_type,
|
|
|
|
|
fd,
|
|
|
|
|
self.common.event_loop_handle.clone(),
|
|
|
|
|
) {
|
2023-02-24 17:41:52 +01:00
|
|
|
warn!(?err, "Failed to send clipboard (X11 -> Wayland).");
|
2023-02-13 17:44:24 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-04 15:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delegate_data_device!(State);
|