Skip to content

Commit

Permalink
wip: fix buffer offset
Browse files Browse the repository at this point in the history
  • Loading branch information
cmeissl committed Feb 24, 2024
1 parent 5386601 commit 23c9ac9
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 53 deletions.
19 changes: 19 additions & 0 deletions anvil/src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,25 @@ impl<BackendData: Backend> CompositorHandler for AnvilState<BackendData> {
}
self.popups.commit(surface);

if let Some(dnd_icon) = self.dnd_icon.as_mut().and_then(|icon| {
if &icon.surface == surface {
Some(icon)
} else {
None
}
}) {
with_states(surface, |states| {
let buffer_delta = states
.cached_state
.current::<SurfaceAttributes>()
.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)
}
}
Expand Down
41 changes: 32 additions & 9 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use smithay::{
},
input::{
keyboard::{Keysym, LedState, XkbConfig},
pointer::{CursorImageStatus, PointerHandle},
pointer::{CursorImageAttributes, CursorImageStatus, PointerHandle},
Seat, SeatHandler, SeatState,
},
output::Output,
Expand All @@ -41,7 +41,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,
Expand All @@ -59,11 +59,11 @@ use smithay::{
security_context::{
SecurityContext, SecurityContextHandler, SecurityContextListenerSource, SecurityContextState,
},
selection::data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
},
selection::{
data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
},
primary_selection::{set_primary_focus, PrimarySelectionHandler, PrimarySelectionState},
wlr_data_control::{DataControlHandler, DataControlState},
SelectionHandler,
Expand Down Expand Up @@ -96,7 +96,7 @@ use crate::{
#[cfg(feature = "xwayland")]
use smithay::{
delegate_xwayland_keyboard_grab,
utils::{Point, Size},
utils::Size,
wayland::selection::{SelectionSource, SelectionTarget},
wayland::xwayland_keyboard_grab::{XWaylandKeyboardGrabHandler, XWaylandKeyboardGrabState},
xwayland::{X11Wm, XWayland, XWaylandEvent},
Expand Down Expand Up @@ -148,7 +148,7 @@ pub struct AnvilState<BackendData: Backend + 'static> {
pub presentation_state: PresentationState,
pub fractional_scale_manager_state: FractionalScaleManagerState,

pub dnd_icon: Option<WlSurface>,
pub dnd_icon: Option<DndIcon>,

// input-related fields
pub suppressed_keys: Vec<Keysym>,
Expand All @@ -171,6 +171,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> {
Expand All @@ -181,7 +187,24 @@ 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 cursor_status = self.cursor_status.lock().unwrap();
let cursor_hotspot = if let CursorImageStatus::Surface(ref surface) = *cursor_status {
with_states(surface, |states| {
states
.data_map
.get::<Mutex<CursorImageAttributes>>()
.unwrap()
.lock()
.unwrap()
.hotspot
})
} else {
(0, 0).into()
};
self.dnd_icon = icon.map(|surface| DndIcon {
surface,
offset: cursor_hotspot,
});
}
fn dropped(&mut self, _seat: Seat<Self>) {
self.dnd_icon = None;
Expand Down
15 changes: 9 additions & 6 deletions anvil/src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
time::{Duration, Instant},
};

use crate::state::SurfaceDmabufFeedback;
use crate::state::{DndIcon, SurfaceDmabufFeedback};
use crate::{
drawing::*,
render::*,
Expand Down Expand Up @@ -1566,7 +1566,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,
Expand Down Expand Up @@ -1614,12 +1614,15 @@ fn render_surface<'a>(

// 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,
));
Expand Down
11 changes: 7 additions & 4 deletions anvil/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,15 @@ pub fn run_winit() {
elements.extend(pointer_element.render_elements(renderer, cursor_pos_scaled, 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,
));
Expand Down
11 changes: 7 additions & 4 deletions anvil/src/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,15 @@ pub fn run_x11() {
));

// 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,
));
Expand Down
31 changes: 3 additions & 28 deletions src/backend/renderer/utils/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,13 @@ pub struct RendererSurfaceState {
pub(crate) buffer_dimensions: Option<Size<i32, BufferCoord>>,
pub(crate) buffer_scale: i32,
pub(crate) buffer_transform: Transform,
pub(crate) buffer_delta: Option<Point<i32, Logical>>,
pub(crate) buffer_has_alpha: Option<bool>,
pub(crate) buffer: Option<Buffer>,
pub(crate) damage: DamageBag<i32, BufferCoord>,
pub(crate) renderer_seen: HashMap<(TypeId, usize), CommitCounter>,
pub(crate) textures: HashMap<(TypeId, usize), Box<dyn std::any::Any>>,
pub(crate) surface_view: Option<SurfaceView>,
pub(crate) opaque_regions: Vec<Rectangle<i32, Logical>>,

accumulated_buffer_delta: Point<i32, Logical>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -96,12 +93,6 @@ impl RendererSurfaceState {
#[profiling::function]
pub(crate) fn update_buffer(&mut self, states: &SurfaceData) {
let mut attrs = states.cached_state.current::<SurfaceAttributes>();
self.buffer_delta = attrs.buffer_delta.take();

if let Some(delta) = self.buffer_delta {
self.accumulated_buffer_delta += delta;
}

match attrs.buffer.take() {
Some(BufferAssignment::NewBuffer(buffer)) => {
// new contents
Expand All @@ -126,8 +117,7 @@ impl RendererSurfaceState {
.buffer_dimensions
.unwrap()
.to_logical(self.buffer_scale, self.buffer_transform);
let surface_view =
SurfaceView::from_states(states, surface_size, self.accumulated_buffer_delta);
let surface_view = SurfaceView::from_states(states, surface_size);
self.surface_view = Some(surface_view);

let mut buffer_damage = attrs
Expand Down Expand Up @@ -266,16 +256,6 @@ impl RendererSurfaceState {
self.textures.get(&texture_id).and_then(|e| e.downcast_ref())
}

/// Location of the buffer relative to the previous call of take_accumulated_buffer_delta
///
/// In other words, the x and y, combined with the new surface size define in which directions
/// the surface's size changed since last call to this method.
///
/// Once delta is taken this method returns `None` to avoid processing it several times.
pub fn take_accumulated_buffer_delta(&mut self) -> Point<i32, Logical> {
std::mem::take(&mut self.accumulated_buffer_delta)
}

/// Gets the opaque regions of this surface
pub fn opaque_regions(&self) -> Option<&[Rectangle<i32, Logical>]> {
// If the surface is unmapped there can be no opaque regions
Expand Down Expand Up @@ -359,23 +339,18 @@ pub fn on_commit_buffer_handler<D: 'static>(surface: &WlSurface) {
}

impl SurfaceView {
fn from_states(
states: &SurfaceData,
surface_size: Size<i32, Logical>,
buffer_delta: Point<i32, Logical>,
) -> SurfaceView {
fn from_states(states: &SurfaceData, surface_size: Size<i32, Logical>) -> SurfaceView {
viewporter::ensure_viewport_valid(states, surface_size);
let viewport = states.cached_state.current::<viewporter::ViewportCachedState>();
let src = viewport
.src
.unwrap_or_else(|| Rectangle::from_loc_and_size((0.0, 0.0), surface_size.to_f64()));
let dst = viewport.size().unwrap_or(surface_size);
let mut offset = if states.role == Some("subsurface") {
let offset = if states.role == Some("subsurface") {
states.cached_state.current::<SubsurfaceCachedState>().location
} else {
Default::default()
};
offset += buffer_delta;
SurfaceView { src, dst, offset }
}

Expand Down
28 changes: 26 additions & 2 deletions src/wayland/seat/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,8 @@ where
return;
}

compositor::with_states(&surface, |states| {
states.data_map.insert_if_missing_threadsafe(|| {
let initial = compositor::with_states(&surface, |states| {
let initial = states.data_map.insert_if_missing_threadsafe(|| {
Mutex::new(CursorImageAttributes {
hotspot: (0, 0).into(),
})
Expand All @@ -541,8 +541,32 @@ where
.lock()
.unwrap()
.hotspot = (hotspot_x, hotspot_y).into();
initial
});

if initial {
compositor::add_post_commit_hook::<D, _>(&surface, |_, _, surface| {
compositor::with_states(surface, |states| {
let cursor_image_attributes =
states.data_map.get::<Mutex<CursorImageAttributes>>();

if let Some(mut cursor_image_attributes) =
cursor_image_attributes.map(|attrs| attrs.lock().unwrap())
{
let buffer_delta = states
.cached_state
.current::<compositor::SurfaceAttributes>()
.buffer_delta
.take();
if let Some(buffer_delta) = buffer_delta {
tracing::trace!(hotspot = ?cursor_image_attributes.hotspot, ?buffer_delta, "decrementing cursor hotspot");
cursor_image_attributes.hotspot -= buffer_delta;
}
}
});
});
}

CursorImageStatus::Surface(surface)
}
None => CursorImageStatus::Hidden,
Expand Down

0 comments on commit 23c9ac9

Please sign in to comment.