Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
xDarksome committed Apr 16, 2023
1 parent 8f6ad62 commit 7983f5c
Show file tree
Hide file tree
Showing 15 changed files with 785 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/backend/kms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ pub fn init_backend(
// Create relative pointer global
RelativePointerManagerState::new::<State>(&dh);

state.launch_xwayland(Some(primary));
// state.launch_xwayland(Some(primary));

for (dev, path) in udev_dispatcher.as_source_ref().device_list() {
state
Expand Down
2 changes: 1 addition & 1 deletion src/backend/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ pub fn init_backend(
seats.iter().cloned(),
&state.common.event_loop_handle,
);
state.launch_xwayland(None);
// state.launch_xwayland(None);

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ pub fn init_backend(
seats.iter().cloned(),
&state.common.event_loop_handle,
);
state.launch_xwayland(None);
// state.launch_xwayland(None);

event_loop
.handle()
Expand Down
4 changes: 4 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
shell::{layout::floating::SeatMoveGrabState, Shell},
utils::prelude::*,
wayland::protocols::{
data_control,
drm::WlDrmState,
output_configuration::OutputConfigurationState,
screencopy::{BufferParams, ScreencopyState, Session as ScreencopySession},
Expand Down Expand Up @@ -117,6 +118,7 @@ pub struct Common {
pub output_configuration_state: OutputConfigurationState<State>,
pub presentation_state: PresentationState,
pub primary_selection_state: PrimarySelectionState,
pub data_control_state: data_control::State,
pub screencopy_state: ScreencopyState,
pub seat_state: SeatState<State>,
pub shm_state: ShmState,
Expand Down Expand Up @@ -248,6 +250,7 @@ impl State {
let output_configuration_state = OutputConfigurationState::new(dh, |_| true);
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
let data_control_state = data_control::State::new::<Self>(dh);
let screencopy_state = ScreencopyState::new::<Self, _, _>(
dh,
vec![CursorMode::Embedded, CursorMode::Hidden],
Expand Down Expand Up @@ -299,6 +302,7 @@ impl State {
output_configuration_state,
presentation_state,
primary_selection_state,
data_control_state,
viewporter_state,
wl_drm_state,
kde_decoration_state,
Expand Down
51 changes: 51 additions & 0 deletions src/wayland/handlers/data_control.rs
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);
1 change: 1 addition & 0 deletions src/wayland/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub mod buffer;
pub mod compositor;
pub mod data_control;
pub mod data_device;
pub mod decoration;
pub mod dmabuf;
Expand Down
4 changes: 3 additions & 1 deletion src/wayland/handlers/seat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::{
shell::focus::target::{KeyboardFocusTarget, PointerFocusTarget},
state::State,
wayland::protocols::data_control,
};
use smithay::{
delegate_seat,
Expand Down Expand Up @@ -46,7 +47,8 @@ impl SeatHandler for State {
.and_then(|s| dh.get_client(s.id()).ok())
{
set_data_device_focus(dh, seat, Some(client.clone()));
set_primary_focus(dh, seat, Some(client))
set_primary_focus(dh, seat, Some(client.clone()));
data_control::set_primary_focus(dh, seat, Some(client))
}
}
}
Expand Down
79 changes: 79 additions & 0 deletions src/wayland/protocols/data_control/device.rs
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!(),
}
}
}
80 changes: 80 additions & 0 deletions src/wayland/protocols/data_control/manager.rs
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!(),
}
}
}
Loading

0 comments on commit 7983f5c

Please sign in to comment.