mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-29 20:34:46 +01:00
Add dnd icon
This commit is contained in:
parent
7048a89dbf
commit
ad30f4668b
5 changed files with 126 additions and 10 deletions
|
@ -1378,6 +1378,7 @@ impl State<UdevData> {
|
|||
&pointer_image,
|
||||
&mut self.backend_data.pointer_element,
|
||||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
&self.clock,
|
||||
);
|
||||
let reschedule = match &result {
|
||||
|
@ -1482,6 +1483,7 @@ fn render_surface<'a>(
|
|||
pointer_image: &TextureBuffer<MultiTexture>,
|
||||
pointer_element: &mut PointerElement<MultiTexture>,
|
||||
cursor_status: &mut CursorImageStatus,
|
||||
dnd_icon: Option<&WlSurface>,
|
||||
clock: &Clock<Monotonic>,
|
||||
) -> Result<bool, SwapBuffersError> {
|
||||
let output_geometry = space.output_geometry(output).unwrap();
|
||||
|
@ -1545,7 +1547,15 @@ fn render_surface<'a>(
|
|||
1.0,
|
||||
));
|
||||
|
||||
// TODO: dnd icon
|
||||
if let Some(dnd_icon) = dnd_icon {
|
||||
custom_elements.extend(AsRenderElements::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(dnd_icon),
|
||||
renderer,
|
||||
cursor_pos_scaled,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let mut output_render_elements = custom_elements
|
||||
|
|
|
@ -293,6 +293,16 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
1.0,
|
||||
));
|
||||
|
||||
if let Some(dnd_icon) = state.dnd_icon.as_ref() {
|
||||
custom_render_elements.extend(AsRenderElements::<GlesRenderer>::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(dnd_icon),
|
||||
state.backend_data.backend.renderer(),
|
||||
cursor_pos_scaled,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
}
|
||||
|
||||
let render_res = state.backend_data.backend.bind().and_then(|_| {
|
||||
let age = if *full_redraw > 0 {
|
||||
0
|
||||
|
|
109
src/handlers.rs
109
src/handlers.rs
|
@ -21,7 +21,10 @@ use smithay::{
|
|||
calloop::Interest,
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge},
|
||||
wayland_server::{
|
||||
protocol::{wl_buffer::WlBuffer, wl_seat::WlSeat, wl_surface::WlSurface},
|
||||
protocol::{
|
||||
wl_buffer::WlBuffer, wl_data_source::WlDataSource, wl_seat::WlSeat,
|
||||
wl_surface::WlSurface,
|
||||
},
|
||||
Client, Resource,
|
||||
},
|
||||
},
|
||||
|
@ -33,12 +36,14 @@ use smithay::{
|
|||
SurfaceAttributes,
|
||||
},
|
||||
data_device::{
|
||||
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
|
||||
self, set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
|
||||
ServerDndGrabHandler,
|
||||
},
|
||||
dmabuf,
|
||||
fractional_scale::{self, FractionalScaleHandler},
|
||||
primary_selection::{PrimarySelectionHandler, PrimarySelectionState},
|
||||
primary_selection::{
|
||||
self, set_primary_focus, PrimarySelectionHandler, PrimarySelectionState,
|
||||
},
|
||||
seat::WaylandFocus,
|
||||
shell::xdg::{
|
||||
Configure, PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData,
|
||||
|
@ -46,7 +51,7 @@ use smithay::{
|
|||
},
|
||||
shm::{ShmHandler, ShmState},
|
||||
},
|
||||
xwayland::{X11Wm, XWaylandClientData},
|
||||
xwayland::{xwm::SelectionType, X11Wm, XWaylandClientData},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -196,7 +201,21 @@ fn ensure_initial_configure<B: Backend>(surface: &WlSurface, state: &mut State<B
|
|||
// TODO: layer map thingys
|
||||
}
|
||||
|
||||
impl<B: Backend> ClientDndGrabHandler for State<B> {}
|
||||
impl<B: Backend> ClientDndGrabHandler for State<B> {
|
||||
fn started(
|
||||
&mut self,
|
||||
_source: Option<WlDataSource>,
|
||||
icon: Option<WlSurface>,
|
||||
_seat: Seat<Self>,
|
||||
) {
|
||||
self.dnd_icon = icon;
|
||||
}
|
||||
|
||||
fn dropped(&mut self, _seat: Seat<Self>) {
|
||||
self.dnd_icon = None;
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> ServerDndGrabHandler for State<B> {}
|
||||
|
||||
impl<B: Backend> DataDeviceHandler for State<B> {
|
||||
|
@ -205,6 +224,39 @@ impl<B: Backend> DataDeviceHandler for State<B> {
|
|||
fn data_device_state(&self) -> &DataDeviceState {
|
||||
&self.data_device_state
|
||||
}
|
||||
|
||||
fn new_selection(&mut self, source: Option<WlDataSource>, _seat: Seat<Self>) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Some(source) = source {
|
||||
if let Ok(Err(err)) = data_device::with_source_metadata(&source, |metadata| {
|
||||
xwm.new_selection(SelectionType::Clipboard, Some(metadata.mime_types.clone()))
|
||||
}) {
|
||||
tracing::warn!(?err, "Failed to set Xwayland clipboard selection");
|
||||
}
|
||||
} else if let Err(err) = xwm.new_selection(SelectionType::Clipboard, None) {
|
||||
tracing::warn!(?err, "Failed to clear Xwayland clipboard selection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_selection(
|
||||
&mut self,
|
||||
mime_type: String,
|
||||
fd: std::os::fd::OwnedFd,
|
||||
_seat: Seat<Self>,
|
||||
_user_data: &Self::SelectionUserData,
|
||||
) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Err(err) = xwm.send_selection(
|
||||
SelectionType::Clipboard,
|
||||
mime_type,
|
||||
fd,
|
||||
self.loop_handle.clone(),
|
||||
) {
|
||||
tracing::warn!(?err, "Failed to send clipboard (X11 -> Wayland)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate_data_device!(@<B: Backend> State<B>);
|
||||
|
||||
|
@ -214,6 +266,43 @@ impl<B: Backend> PrimarySelectionHandler for State<B> {
|
|||
fn primary_selection_state(&self) -> &PrimarySelectionState {
|
||||
&self.primary_selection_state
|
||||
}
|
||||
|
||||
fn new_selection(
|
||||
&mut self,
|
||||
source: Option<smithay::reexports::wayland_protocols::wp::primary_selection::zv1::server::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1>,
|
||||
_seat: Seat<Self>,
|
||||
) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Some(source) = source {
|
||||
if let Ok(Err(err)) = primary_selection::with_source_metadata(&source, |metadata| {
|
||||
xwm.new_selection(SelectionType::Primary, Some(metadata.mime_types.clone()))
|
||||
}) {
|
||||
tracing::warn!(?err, "Failed to set Xwayland primary selection");
|
||||
}
|
||||
} else if let Err(err) = xwm.new_selection(SelectionType::Primary, None) {
|
||||
tracing::warn!(?err, "Failed to clear Xwayland primary selection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_selection(
|
||||
&mut self,
|
||||
mime_type: String,
|
||||
fd: std::os::fd::OwnedFd,
|
||||
_seat: Seat<Self>,
|
||||
_user_data: &Self::SelectionUserData,
|
||||
) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Err(err) = xwm.send_selection(
|
||||
SelectionType::Primary,
|
||||
mime_type,
|
||||
fd,
|
||||
self.loop_handle.clone(),
|
||||
) {
|
||||
tracing::warn!(?err, "Failed to send primary (X11 -> Wayland)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate_primary_selection!(@<B: Backend> State<B>);
|
||||
|
||||
|
@ -236,9 +325,13 @@ impl<B: Backend> SeatHandler for State<B> {
|
|||
{
|
||||
self.focus_state.set_focus(focus);
|
||||
}
|
||||
let focus_client =
|
||||
focused.and_then(|surf| self.display_handle.get_client(surf.wl_surface()?.id()).ok());
|
||||
set_data_device_focus(&self.display_handle, seat, focus_client);
|
||||
let focus_client = focused.and_then(|foc_target| {
|
||||
self.display_handle
|
||||
.get_client(foc_target.wl_surface()?.id())
|
||||
.ok()
|
||||
});
|
||||
set_data_device_focus(&self.display_handle, seat, focus_client.clone());
|
||||
set_primary_focus(&self.display_handle, seat, focus_client);
|
||||
}
|
||||
}
|
||||
delegate_seat!(@<B: Backend> State<B>);
|
||||
|
|
|
@ -101,6 +101,8 @@ pub struct State<B: Backend> {
|
|||
|
||||
pub cursor_status: CursorImageStatus,
|
||||
pub pointer_location: Point<f64, Logical>,
|
||||
pub dnd_icon: Option<WlSurface>,
|
||||
|
||||
pub windows: Vec<WindowElement>,
|
||||
|
||||
pub async_scheduler: Scheduler<()>,
|
||||
|
@ -900,6 +902,8 @@ impl<B: Backend> State<B> {
|
|||
|
||||
seat,
|
||||
|
||||
dnd_icon: None,
|
||||
|
||||
move_mode: false,
|
||||
socket_name: socket_name.to_string_lossy().to_string(),
|
||||
|
||||
|
|
|
@ -495,7 +495,6 @@ pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &WindowElement)
|
|||
.element_location(window)
|
||||
.unwrap_or((0, 0).into())
|
||||
}));
|
||||
// TODO: TOMORROW: come up with a better way to keep window location
|
||||
if let WindowElement::Wayland(window) = window {
|
||||
window.toplevel().with_pending_state(|tl_state| {
|
||||
tl_state.states.unset(xdg_toplevel::State::TiledTop);
|
||||
|
|
Loading…
Add table
Reference in a new issue