Commit 5c3ede313624
tarball2 files changed+92-1
@@ -6,13 +6,14 @@ use smithay::reexports::wayland_server::Resource;
66
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;77
use smithay::utils::Serial;88
use smithay::wayland::seat::WaylandFocus;9
-use smithay::wayland::selection::SelectionHandler;109
use smithay::wayland::selection::data_device::{1110
DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler, set_data_device_focus,1211
};1312
use smithay::wayland::selection::primary_selection::{1413
PrimarySelectionHandler, PrimarySelectionState, set_primary_focus,1514
};15
+use smithay::wayland::selection::{SelectionHandler, SelectionSource, SelectionTarget};16
+use std::os::fd::OwnedFd;1617
1718
impl SeatHandler for State {1819
type KeyboardFocus = crate::focus::Focus;@@ -39,6 +40,34 @@ impl SeatHandler for State {
3940
4041
impl SelectionHandler for State {4142
type SelectionUserData = ();43
+44
+ fn new_selection(45
+ &mut self,46
+ ty: SelectionTarget,47
+ source: Option<SelectionSource>,48
+ _seat: Seat<Self>,49
+ ) {50
+ if let Some(wm) = self.services.xwayland.as_mut().and_then(|x| x.wm.as_mut())51
+ && let Err(e) = wm.new_selection(ty, source.map(|s| s.mime_types()))52
+ {53
+ tracing::warn!("cannot set the X11 {ty:?} selection: {e:?}");54
+ }55
+ }56
+57
+ fn send_selection(58
+ &mut self,59
+ ty: SelectionTarget,60
+ mime_type: String,61
+ fd: OwnedFd,62
+ _seat: Seat<Self>,63
+ _user_data: &(),64
+ ) {65
+ if let Some(wm) = self.services.xwayland.as_mut().and_then(|x| x.wm.as_mut())66
+ && let Err(e) = wm.send_selection(ty, mime_type, fd)67
+ {68
+ tracing::warn!("cannot read the X11 {ty:?} selection: {e:?}");69
+ }70
+ }4271
}4372
4473
impl DataDeviceHandler for State {@@ -3,6 +3,7 @@
33
//! connection that woke it is served. Xwayland exits once its last client44
//! leaves and the socket is watched again.55
6
+use crate::focus::Focus;67
use crate::state::State;78
use smithay::desktop::Window;89
use smithay::reexports::calloop::generic::Generic;@@ -10,10 +11,20 @@ use smithay::reexports::calloop::{Interest, Mode, PostAction, RegistrationToken}
1011
use smithay::reexports::rustix::io::{FdFlags, fcntl_getfd, fcntl_setfd};1112
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;1213
use smithay::utils::{Logical, Rectangle, Size};14
+use smithay::wayland::selection::SelectionTarget;15
+use smithay::wayland::selection::data_device::{16
+ clear_data_device_selection, current_data_device_selection_userdata,17
+ request_data_device_client_selection, set_data_device_selection,18
+};19
+use smithay::wayland::selection::primary_selection::{20
+ clear_primary_selection, current_primary_selection_userdata, request_primary_client_selection,21
+ set_primary_selection,22
+};1323
use smithay::wayland::xwayland_shell::{XWaylandShellHandler, XWaylandShellState};1424
use smithay::xwayland::xwm::{Reorder, ResizeEdge, WmWindowProperty, WmWindowType, XwmId};1525
use smithay::xwayland::{X11Surface, X11Wm, XWayland, XWaylandEvent, XwmHandler};1626
use std::os::fd::AsFd;27
+use std::os::fd::OwnedFd;1728
use std::os::linux::net::SocketAddrExt;1829
use std::os::unix::net::{SocketAddr, UnixListener};1930
use std::process::Stdio;@@ -327,6 +338,57 @@ impl XwmHandler for State {
327338
}328339
}329340
341
+ fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionTarget) -> bool {342
+ matches!(343
+ self.input.seat.get_keyboard().and_then(|k| k.current_focus()),344
+ Some(Focus::X11(x)) if x.xwm_id() == Some(xwm)345
+ )346
+ }347
+348
+ fn send_selection(349
+ &mut self,350
+ _xwm: XwmId,351
+ selection: SelectionTarget,352
+ mime_type: String,353
+ fd: OwnedFd,354
+ ) {355
+ let seat = &self.input.seat;356
+ let result = match selection {357
+ SelectionTarget::Clipboard => request_data_device_client_selection(seat, mime_type, fd)358
+ .map_err(|e| format!("{e:?}")),359
+ SelectionTarget::Primary => {360
+ request_primary_client_selection(seat, mime_type, fd).map_err(|e| format!("{e:?}"))361
+ }362
+ };363
+ if let Err(e) = result {364
+ tracing::warn!("cannot serve {selection:?} to X11: {e}");365
+ }366
+ }367
+368
+ fn new_selection(&mut self, _xwm: XwmId, selection: SelectionTarget, mime_types: Vec<String>) {369
+ let (dh, seat) = (&self.core.display, &self.input.seat);370
+ match selection {371
+ SelectionTarget::Clipboard => set_data_device_selection(dh, seat, mime_types, ()),372
+ SelectionTarget::Primary => set_primary_selection(dh, seat, mime_types, ()),373
+ }374
+ }375
+376
+ fn cleared_selection(&mut self, _xwm: XwmId, selection: SelectionTarget) {377
+ let (dh, seat) = (&self.core.display, &self.input.seat);378
+ match selection {379
+ SelectionTarget::Clipboard => {380
+ if current_data_device_selection_userdata(seat).is_some() {381
+ clear_data_device_selection(dh, seat);382
+ }383
+ }384
+ SelectionTarget::Primary => {385
+ if current_primary_selection_userdata(seat).is_some() {386
+ clear_primary_selection(dh, seat);387
+ }388
+ }389
+ }390
+ }391
+330392
fn disconnected(&mut self, _xwm: XwmId) {331393
tracing::info!("Xwayland exited");332394
let gone: Vec<_> = self