mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-29 20:34:46 +01:00
Add drag-and-drop support between x11 windows
This commit is contained in:
parent
4e4eb0fe7c
commit
7048a89dbf
3 changed files with 100 additions and 8 deletions
|
@ -7,8 +7,8 @@ use std::time::Duration;
|
|||
use smithay::{
|
||||
backend::renderer::utils,
|
||||
delegate_compositor, delegate_data_device, delegate_fractional_scale, delegate_output,
|
||||
delegate_presentation, delegate_relative_pointer, delegate_seat, delegate_shm,
|
||||
delegate_viewporter, delegate_xdg_shell,
|
||||
delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat,
|
||||
delegate_shm, delegate_viewporter, delegate_xdg_shell,
|
||||
desktop::{
|
||||
find_popup_root_surface, utils::surface_primary_scanout_output, PopupKeyboardGrab,
|
||||
PopupKind, PopupPointerGrab, PopupUngrabStrategy, Window,
|
||||
|
@ -38,6 +38,7 @@ use smithay::{
|
|||
},
|
||||
dmabuf,
|
||||
fractional_scale::{self, FractionalScaleHandler},
|
||||
primary_selection::{PrimarySelectionHandler, PrimarySelectionState},
|
||||
seat::WaylandFocus,
|
||||
shell::xdg::{
|
||||
Configure, PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData,
|
||||
|
@ -207,6 +208,15 @@ impl<B: Backend> DataDeviceHandler for State<B> {
|
|||
}
|
||||
delegate_data_device!(@<B: Backend> State<B>);
|
||||
|
||||
impl<B: Backend> PrimarySelectionHandler for State<B> {
|
||||
type SelectionUserData = ();
|
||||
|
||||
fn primary_selection_state(&self) -> &PrimarySelectionState {
|
||||
&self.primary_selection_state
|
||||
}
|
||||
}
|
||||
delegate_primary_selection!(@<B: Backend> State<B>);
|
||||
|
||||
impl<B: Backend> SeatHandler for State<B> {
|
||||
type KeyboardFocus = FocusTarget;
|
||||
type PointerFocus = FocusTarget;
|
||||
|
|
|
@ -7,9 +7,19 @@
|
|||
use smithay::{
|
||||
reexports::wayland_server::Resource,
|
||||
utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
|
||||
wayland::compositor::{self, CompositorHandler},
|
||||
wayland::{
|
||||
compositor::{self, CompositorHandler},
|
||||
data_device::{
|
||||
clear_data_device_selection, current_data_device_selection_userdata,
|
||||
request_data_device_client_selection, set_data_device_selection,
|
||||
},
|
||||
primary_selection::{
|
||||
clear_primary_selection, current_primary_selection_userdata,
|
||||
request_primary_client_selection, set_primary_selection,
|
||||
},
|
||||
},
|
||||
xwayland::{
|
||||
xwm::{Reorder, WmWindowType, XwmId},
|
||||
xwm::{Reorder, SelectionType, WmWindowType, XwmId},
|
||||
X11Surface, X11Wm, XwmHandler,
|
||||
},
|
||||
};
|
||||
|
@ -375,13 +385,80 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: allow_selection_access
|
||||
fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionType) -> bool {
|
||||
self.state
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.and_then(|kb| kb.current_focus())
|
||||
.is_some_and(|focus| {
|
||||
if let FocusTarget::Window(WindowElement::X11(surface)) = focus {
|
||||
surface.xwm_id().expect("x11surface had no xwm id") == xwm
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: send_selection
|
||||
fn send_selection(
|
||||
&mut self,
|
||||
xwm: XwmId,
|
||||
selection: SelectionType,
|
||||
mime_type: String,
|
||||
fd: std::os::fd::OwnedFd,
|
||||
) {
|
||||
match selection {
|
||||
SelectionType::Clipboard => {
|
||||
if let Err(err) =
|
||||
request_data_device_client_selection(&self.state.seat, mime_type, fd)
|
||||
{
|
||||
tracing::error!(
|
||||
?err,
|
||||
"Failed to request current wayland clipboard for XWayland"
|
||||
);
|
||||
}
|
||||
}
|
||||
SelectionType::Primary => {
|
||||
if let Err(err) = request_primary_client_selection(&self.state.seat, mime_type, fd)
|
||||
{
|
||||
tracing::error!(
|
||||
?err,
|
||||
"Failed to request current wayland primary selection for XWayland"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: new_selection
|
||||
fn new_selection(&mut self, xwm: XwmId, selection: SelectionType, mime_types: Vec<String>) {
|
||||
match selection {
|
||||
SelectionType::Clipboard => {
|
||||
set_data_device_selection(
|
||||
&self.state.display_handle,
|
||||
&self.state.seat,
|
||||
mime_types,
|
||||
(),
|
||||
);
|
||||
}
|
||||
SelectionType::Primary => {
|
||||
set_primary_selection(&self.state.display_handle, &self.state.seat, mime_types, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: cleared_selection
|
||||
fn cleared_selection(&mut self, xwm: XwmId, selection: SelectionType) {
|
||||
match selection {
|
||||
SelectionType::Clipboard => {
|
||||
if current_data_device_selection_userdata(&self.state.seat).is_some() {
|
||||
clear_data_device_selection(&self.state.display_handle, &self.state.seat);
|
||||
}
|
||||
}
|
||||
SelectionType::Primary => {
|
||||
if current_primary_selection_userdata(&self.state.seat).is_some() {
|
||||
clear_primary_selection(&self.state.display_handle, &self.state.seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make assumptions on whether or not the surface should be floating.
|
||||
|
|
|
@ -57,6 +57,7 @@ use smithay::{
|
|||
dmabuf::DmabufFeedback,
|
||||
fractional_scale::FractionalScaleManagerState,
|
||||
output::OutputManagerState,
|
||||
primary_selection::PrimarySelectionState,
|
||||
shell::xdg::{XdgShellState, XdgToplevelSurfaceData},
|
||||
shm::ShmState,
|
||||
socket::ListeningSocketSource,
|
||||
|
@ -90,6 +91,8 @@ pub struct State<B: Backend> {
|
|||
pub xdg_shell_state: XdgShellState,
|
||||
pub viewporter_state: ViewporterState,
|
||||
pub fractional_scale_manager_state: FractionalScaleManagerState,
|
||||
pub primary_selection_state: PrimarySelectionState,
|
||||
|
||||
pub input_state: InputState,
|
||||
pub api_state: ApiState,
|
||||
pub focus_state: FocusState,
|
||||
|
@ -889,6 +892,8 @@ impl<B: Backend> State<B> {
|
|||
fractional_scale_manager_state: FractionalScaleManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
primary_selection_state: PrimarySelectionState::new::<Self>(&display_handle),
|
||||
|
||||
input_state: InputState::new(),
|
||||
api_state: ApiState::new(),
|
||||
focus_state: FocusState::new(),
|
||||
|
|
Loading…
Add table
Reference in a new issue