-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
785 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
use crate::state::State; | ||
use crate::wayland::protocols::data_control; | ||
use smithay::xwayland::xwm::{SelectionType, XwmId}; | ||
use tracing::warn; | ||
|
||
use std::os::unix::io::OwnedFd; | ||
|
||
impl data_control::Handler for State { | ||
fn new_selection(&mut self, source: Option<data_control::Source>) { | ||
if let Some(state) = self.common.xwayland_state.as_mut() { | ||
if let Some(xwm) = state.xwm.as_mut() { | ||
if let Some(source) = &source { | ||
if let Ok(Err(err)) = | ||
data_control::source::with_source_metadata(source, |metadata| { | ||
xwm.new_selection( | ||
SelectionType::Clipboard, | ||
Some(metadata.mime_types.clone()), | ||
) | ||
}) | ||
{ | ||
warn!(?err, "Failed to set Xwayland primary selection"); | ||
} | ||
} else if let Err(err) = xwm.new_selection(SelectionType::Clipboard, None) { | ||
warn!(?err, "Failed to clear Xwayland primary selection"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn send_selection(&mut self, mime_type: String, fd: OwnedFd) { | ||
if let Some(xwm) = self | ||
.common | ||
.xwayland_state | ||
.as_mut() | ||
.and_then(|xstate| xstate.xwm.as_mut()) | ||
{ | ||
if let Err(err) = xwm.send_selection( | ||
SelectionType::Clipboard, | ||
mime_type, | ||
fd, | ||
self.common.event_loop_handle.clone(), | ||
) { | ||
warn!(?err, "Failed to send primary selection (X11 -> Wayland)."); | ||
} | ||
} | ||
} | ||
} | ||
|
||
data_control::delegate!(State); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
pub use super::server::zwlr_data_control_device_v1::{Request, ZwlrDataControlDeviceV1 as Device}; | ||
|
||
use std::cell::RefCell; | ||
|
||
use smithay::reexports::wayland_server::{ | ||
protocol::wl_seat::WlSeat, Client, DataInit, Dispatch, DisplayHandle, Resource, | ||
}; | ||
use tracing::debug; | ||
|
||
use smithay::{ | ||
input::{Seat, SeatHandler}, | ||
wayland::seat::WaylandFocus, | ||
}; | ||
|
||
use super::{source, Handler, Offer, SeatData, Selection, Source, State}; | ||
|
||
#[derive(Debug)] | ||
pub struct Data { | ||
wl_seat: WlSeat, | ||
} | ||
|
||
impl State { | ||
/// Registers a new [`Device`] created by the client. | ||
pub(super) fn register_device<D>( | ||
&mut self, | ||
new: New<Device>, | ||
wl_seat: WlSeat, | ||
di: DataInit<'_, D>, | ||
) -> Device { | ||
let device = di.init(new, ()); | ||
let _ = self.devices.insert(device.id(), Data { wl_seat }); | ||
device | ||
} | ||
} | ||
|
||
impl<D> Dispatch<Device, (), D> for State | ||
where | ||
D: Dispatch<Device, Data> + Dispatch<Offer, Source> + Dispatch<Offer, source::Metadata>, | ||
D: Handler, | ||
D: SeatHandler, | ||
<D as SeatHandler>::KeyboardFocus: WaylandFocus, | ||
D: 'static, | ||
{ | ||
fn request( | ||
handler: &mut D, | ||
client: &Client, | ||
resource: &Device, | ||
request: Request, | ||
data: &Data, | ||
dh: &DisplayHandle, | ||
_data_init: &mut DataInit<'_, D>, | ||
) { | ||
match request { | ||
Request::SetSelection { source } => { | ||
debug!(source, "set_selection"); | ||
|
||
handler.new_selection(source.clone()); | ||
seat_data.borrow_mut().set_selection::<D>( | ||
dh, | ||
source.map(Selection::Client).unwrap_or(Selection::Empty), | ||
); | ||
} | ||
Request::SetPrimarySelection { source } => { | ||
debug!("set_primary_selection(source: {source:?})"); | ||
} | ||
Request::Destroy => { | ||
debug!("destroy()"); | ||
|
||
// Clean up the known devices | ||
seat.user_data() | ||
.get::<RefCell<SeatData>>() | ||
.unwrap() | ||
.borrow_mut() | ||
.retain_devices(|ndd| ndd != resource) | ||
} | ||
_ => unreachable!(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
pub use super::server::zwlr_data_control_manager_v1::{ | ||
Request, ZwlrDataControlManagerV1 as Manager, | ||
}; | ||
|
||
use std::cell::RefCell; | ||
|
||
use smithay::reexports::wayland_server::{ | ||
self, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, | ||
}; | ||
use tracing::{debug, error}; | ||
|
||
use smithay::input::{Seat, SeatHandler}; | ||
|
||
use super::{Handler, SeatData, State}; | ||
|
||
use super::{device, offer, source, Device, Offer, Source, State}; | ||
|
||
pub(super) fn new(dh: &DisplayHandle) -> GlobalId { | ||
dh.create_global::<D, Manager, _>(1, ()) | ||
} | ||
|
||
impl<D> GlobalDispatch<Manager, (), D> for State | ||
where | ||
D: SeatHandler + GlobalDispatch<Manager, ()>, | ||
D: Dispatch<Manager, ()>, | ||
D: Dispatch<Source, source::Data>, | ||
D: Dispatch<Device, device::Data>, | ||
D: Handler, | ||
D: 'static, | ||
{ | ||
fn bind( | ||
_state: &mut D, | ||
_handle: &DisplayHandle, | ||
_client: &wayland_server::Client, | ||
resource: wayland_server::New<Manager>, | ||
_global_data: &(), | ||
data_init: &mut wayland_server::DataInit<'_, D>, | ||
) { | ||
data_init.init(resource, ()); | ||
} | ||
} | ||
|
||
impl<D> Dispatch<Manager, (), D> for State | ||
where | ||
D: Dispatch<Manager, ()>, | ||
D: Dispatch<Source, source::Data>, | ||
D: Dispatch<Device, device::Data>, | ||
D: Dispatch<Offer, Source> + Dispatch<Offer, source::Metadata>, | ||
D: Handler, | ||
D: SeatHandler, | ||
D: 'static, | ||
{ | ||
fn request( | ||
state: &mut D, | ||
client: &wayland_server::Client, | ||
_resource: &Manager, | ||
request: Request, | ||
_data: &(), | ||
dhandle: &DisplayHandle, | ||
data_init: &mut wayland_server::DataInit<'_, D>, | ||
) { | ||
let state = state.data_control(); | ||
match request { | ||
Request::CreateDataSource { id } => { | ||
debug!(id, "create_data_source"); | ||
|
||
state.register_source(id, data_init); | ||
} | ||
Request::GetDataDevice { id, seat } => { | ||
debug!(id, seat, "get_data_device"); | ||
|
||
state.register_device(id, seat, data_init); | ||
// seat_data.borrow_mut().add_device(device); | ||
// seat_data.borrow_mut().send_selection::<D>(dhandle); | ||
} | ||
Request::Destroy => debug!("destroy"), | ||
_ => unreachable!(), | ||
} | ||
} | ||
} |
Oops, something went wrong.