mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
anvil: handle dnd icon buffer offset
This commit is contained in:
parent
86e8b80eeb
commit
03aaea2415
6 changed files with 114 additions and 40 deletions
|
@ -178,6 +178,21 @@ impl<BackendData: Backend> CompositorHandler for AnvilState<BackendData> {
|
|||
});
|
||||
}
|
||||
|
||||
if matches!(&self.dnd_icon, Some(icon) if &icon.surface == surface) {
|
||||
let dnd_icon = self.dnd_icon.as_mut().unwrap();
|
||||
with_states(&dnd_icon.surface, |states| {
|
||||
let buffer_delta = states
|
||||
.cached_state
|
||||
.get::<SurfaceAttributes>()
|
||||
.current()
|
||||
.buffer_delta
|
||||
.take()
|
||||
.unwrap_or_default();
|
||||
tracing::trace!(offset = ?dnd_icon.offset, ?buffer_delta, "moving dnd offset");
|
||||
dnd_icon.offset += buffer_delta;
|
||||
});
|
||||
}
|
||||
|
||||
ensure_initial_configure(surface, &self.space, &mut self.popups)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ use smithay::{
|
|||
},
|
||||
input::{
|
||||
keyboard::{Keysym, LedState, XkbConfig},
|
||||
pointer::{CursorImageStatus, PointerHandle},
|
||||
pointer::{CursorImageStatus, CursorImageSurfaceData, PointerHandle},
|
||||
Seat, SeatHandler, SeatState,
|
||||
},
|
||||
output::Output,
|
||||
|
@ -44,7 +44,7 @@ use smithay::{
|
|||
Display, DisplayHandle, Resource,
|
||||
},
|
||||
},
|
||||
utils::{Clock, Monotonic, Rectangle},
|
||||
utils::{Clock, Logical, Monotonic, Point, Rectangle},
|
||||
wayland::{
|
||||
compositor::{get_parent, with_states, CompositorClientState, CompositorState},
|
||||
dmabuf::DmabufFeedback,
|
||||
|
@ -101,7 +101,7 @@ use crate::{
|
|||
#[cfg(feature = "xwayland")]
|
||||
use smithay::{
|
||||
delegate_xwayland_keyboard_grab, delegate_xwayland_shell,
|
||||
utils::{Point, Size},
|
||||
utils::Size,
|
||||
wayland::selection::{SelectionSource, SelectionTarget},
|
||||
wayland::xwayland_keyboard_grab::{XWaylandKeyboardGrabHandler, XWaylandKeyboardGrabState},
|
||||
wayland::xwayland_shell,
|
||||
|
@ -153,7 +153,7 @@ pub struct AnvilState<BackendData: Backend + 'static> {
|
|||
pub xwayland_shell_state: xwayland_shell::XWaylandShellState,
|
||||
pub single_pixel_buffer_state: SinglePixelBufferState,
|
||||
|
||||
pub dnd_icon: Option<WlSurface>,
|
||||
pub dnd_icon: Option<DndIcon>,
|
||||
|
||||
// input-related fields
|
||||
pub suppressed_keys: Vec<Keysym>,
|
||||
|
@ -174,6 +174,12 @@ pub struct AnvilState<BackendData: Backend + 'static> {
|
|||
pub show_window_preview: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DndIcon {
|
||||
pub surface: WlSurface,
|
||||
pub offset: Point<i32, Logical>,
|
||||
}
|
||||
|
||||
delegate_compositor!(@<BackendData: Backend + 'static> AnvilState<BackendData>);
|
||||
|
||||
impl<BackendData: Backend> DataDeviceHandler for AnvilState<BackendData> {
|
||||
|
@ -184,7 +190,21 @@ impl<BackendData: Backend> DataDeviceHandler for AnvilState<BackendData> {
|
|||
|
||||
impl<BackendData: Backend> ClientDndGrabHandler for AnvilState<BackendData> {
|
||||
fn started(&mut self, _source: Option<WlDataSource>, icon: Option<WlSurface>, _seat: Seat<Self>) {
|
||||
self.dnd_icon = icon;
|
||||
let offset = if let CursorImageStatus::Surface(ref surface) = self.cursor_status {
|
||||
with_states(surface, |states| {
|
||||
let hotspot = states
|
||||
.data_map
|
||||
.get::<CursorImageSurfaceData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.hotspot;
|
||||
Point::from((-hotspot.x, -hotspot.y))
|
||||
})
|
||||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
self.dnd_icon = icon.map(|surface| DndIcon { surface, offset });
|
||||
}
|
||||
fn dropped(&mut self, _seat: Seat<Self>) {
|
||||
self.dnd_icon = None;
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use crate::state::SurfaceDmabufFeedback;
|
||||
use crate::state::{DndIcon, SurfaceDmabufFeedback};
|
||||
use crate::{
|
||||
drawing::*,
|
||||
render::*,
|
||||
|
@ -1567,7 +1567,7 @@ fn render_surface<'a>(
|
|||
pointer_location: Point<f64, Logical>,
|
||||
pointer_image: &MemoryRenderBuffer,
|
||||
pointer_element: &mut PointerElement,
|
||||
dnd_icon: &Option<wl_surface::WlSurface>,
|
||||
dnd_icon: &Option<DndIcon>,
|
||||
cursor_status: &mut CursorImageStatus,
|
||||
clock: &Clock<Monotonic>,
|
||||
show_window_preview: bool,
|
||||
|
@ -1591,8 +1591,7 @@ fn render_surface<'a>(
|
|||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
let cursor_pos = pointer_location - output_geometry.loc.to_f64() - cursor_hotspot.to_f64();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
|
||||
let cursor_pos = pointer_location - output_geometry.loc.to_f64();
|
||||
|
||||
// set cursor
|
||||
pointer_element.set_buffer(pointer_image.clone());
|
||||
|
@ -1611,16 +1610,28 @@ fn render_surface<'a>(
|
|||
pointer_element.set_status(cursor_status.clone());
|
||||
}
|
||||
|
||||
custom_elements.extend(pointer_element.render_elements(renderer, cursor_pos_scaled, scale, 1.0));
|
||||
custom_elements.extend(
|
||||
pointer_element.render_elements(
|
||||
renderer,
|
||||
(cursor_pos - cursor_hotspot.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round(),
|
||||
scale,
|
||||
1.0,
|
||||
),
|
||||
);
|
||||
|
||||
// draw the dnd icon if applicable
|
||||
{
|
||||
if let Some(wl_surface) = dnd_icon.as_ref() {
|
||||
if wl_surface.alive() {
|
||||
if let Some(icon) = dnd_icon.as_ref() {
|
||||
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round();
|
||||
if icon.surface.alive() {
|
||||
custom_elements.extend(AsRenderElements::<UdevRenderer<'a>>::render_elements(
|
||||
&SurfaceTree::from_surface(wl_surface),
|
||||
&SurfaceTree::from_surface(&icon.surface),
|
||||
renderer,
|
||||
cursor_pos_scaled,
|
||||
dnd_icon_pos,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
|
|
|
@ -277,8 +277,7 @@ pub fn run_winit() {
|
|||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
let cursor_pos = state.pointer.current_location() - cursor_hotspot.to_f64();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
|
||||
let cursor_pos = state.pointer.current_location();
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
let mut renderdoc = state.renderdoc.as_mut();
|
||||
|
@ -310,15 +309,27 @@ pub fn run_winit() {
|
|||
|
||||
let mut elements = Vec::<CustomRenderElements<GlesRenderer>>::new();
|
||||
|
||||
elements.extend(pointer_element.render_elements(renderer, cursor_pos_scaled, scale, 1.0));
|
||||
elements.extend(
|
||||
pointer_element.render_elements(
|
||||
renderer,
|
||||
(cursor_pos - cursor_hotspot.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round(),
|
||||
scale,
|
||||
1.0,
|
||||
),
|
||||
);
|
||||
|
||||
// draw the dnd icon if any
|
||||
if let Some(surface) = dnd_icon {
|
||||
if surface.alive() {
|
||||
if let Some(icon) = dnd_icon {
|
||||
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round();
|
||||
if icon.surface.alive() {
|
||||
elements.extend(AsRenderElements::<GlesRenderer>::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(surface),
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(&icon.surface),
|
||||
renderer,
|
||||
cursor_pos_scaled,
|
||||
dnd_icon_pos,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
|
|
|
@ -346,24 +346,30 @@ pub fn run_x11() {
|
|||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
let cursor_pos = state.pointer.current_location() - cursor_hotspot.to_f64();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
|
||||
let cursor_pos = state.pointer.current_location();
|
||||
|
||||
pointer_element.set_status(state.cursor_status.clone());
|
||||
elements.extend(pointer_element.render_elements(
|
||||
elements.extend(
|
||||
pointer_element.render_elements(
|
||||
&mut backend_data.renderer,
|
||||
cursor_pos_scaled,
|
||||
(cursor_pos - cursor_hotspot.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round(),
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
),
|
||||
);
|
||||
|
||||
// draw the dnd icon if any
|
||||
if let Some(surface) = state.dnd_icon.as_ref() {
|
||||
if surface.alive() {
|
||||
if let Some(icon) = state.dnd_icon.as_ref() {
|
||||
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round();
|
||||
if icon.surface.alive() {
|
||||
elements.extend(AsRenderElements::<GlesRenderer>::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(surface),
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(&icon.surface),
|
||||
&mut backend_data.renderer,
|
||||
cursor_pos_scaled,
|
||||
dnd_icon_pos,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
|
|
|
@ -115,19 +115,30 @@ pub fn run(channel: Channel<WlcsEvent>) {
|
|||
} else {
|
||||
(0, 0).into()
|
||||
};
|
||||
let cursor_pos = state.pointer.current_location() - cursor_hotspot.to_f64();
|
||||
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
|
||||
let cursor_pos = state.pointer.current_location();
|
||||
|
||||
pointer_element.set_status(state.cursor_status.clone());
|
||||
elements.extend(pointer_element.render_elements(&mut renderer, cursor_pos_scaled, scale, 1.0));
|
||||
elements.extend(
|
||||
pointer_element.render_elements(
|
||||
&mut renderer,
|
||||
(cursor_pos - cursor_hotspot.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round(),
|
||||
scale,
|
||||
1.0,
|
||||
),
|
||||
);
|
||||
|
||||
// draw the dnd icon if any
|
||||
if let Some(surface) = state.dnd_icon.as_ref() {
|
||||
if surface.alive() {
|
||||
if let Some(icon) = state.dnd_icon.as_ref() {
|
||||
if icon.surface.alive() {
|
||||
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
|
||||
.to_physical(scale)
|
||||
.to_i32_round();
|
||||
elements.extend(AsRenderElements::<DummyRenderer>::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(surface),
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(&icon.surface),
|
||||
&mut renderer,
|
||||
cursor_pos_scaled,
|
||||
dnd_icon_pos,
|
||||
scale,
|
||||
1.0,
|
||||
));
|
||||
|
|
Loading…
Reference in a new issue