Make cursor_geometry() return a CursorGeometry struct

A bit better than just a tuple.
This commit is contained in:
Ian Douglas Scott 2026-06-15 13:52:32 -07:00 committed by Victoria Brekenfeld
parent dd6ebd03c9
commit 27956e6e00
5 changed files with 33 additions and 21 deletions

View file

@ -11,7 +11,7 @@ use crate::{
}, },
input::gestures::{GestureState, SwipeAction}, input::gestures::{GestureState, SwipeAction},
shell::{ shell::{
LastModifierChange, SeatExt, Trigger, CursorGeometry, LastModifierChange, SeatExt, Trigger,
focus::{ focus::{
Stage, render_input_order, Stage, render_input_order,
target::{KeyboardFocusTarget, PointerFocusTarget}, target::{KeyboardFocusTarget, PointerFocusTarget},
@ -651,7 +651,7 @@ impl State {
} }
for session in cursor_sessions_for_output(&shell, &output) { for session in cursor_sessions_for_output(&shell, &output) {
if let Some((geometry, offset)) = seat.cursor_geometry( if let Some(CursorGeometry { geometry, hotspot }) = seat.cursor_geometry(
(position - output_geometry.loc.to_f64()) (position - output_geometry.loc.to_f64())
.as_logical() .as_logical()
.to_buffer( .to_buffer(
@ -677,7 +677,7 @@ impl State {
dma: None, dma: None,
}); });
} }
session.set_cursor_hotspot(offset); session.set_cursor_hotspot(hotspot);
session.set_cursor_pos(Some(geometry.loc)); session.set_cursor_pos(Some(geometry.loc));
} }
} }
@ -720,7 +720,7 @@ impl State {
let shell = self.common.shell.read(); let shell = self.common.shell.read();
for session in cursor_sessions_for_output(&shell, &output) { for session in cursor_sessions_for_output(&shell, &output) {
if let Some((geometry, offset)) = seat.cursor_geometry( if let Some(CursorGeometry { geometry, hotspot }) = seat.cursor_geometry(
(position - output_geometry.loc.to_f64()) (position - output_geometry.loc.to_f64())
.as_logical() .as_logical()
.to_buffer( .to_buffer(
@ -746,7 +746,7 @@ impl State {
dma: None, dma: None,
}); });
} }
session.set_cursor_hotspot(offset); session.set_cursor_hotspot(hotspot);
session.set_cursor_pos(Some(geometry.loc)); session.set_cursor_pos(Some(geometry.loc));
} }
} }
@ -2482,7 +2482,7 @@ impl State {
let output_geometry = output.geometry(); let output_geometry = output.geometry();
for session in cursor_sessions_for_output(&shell, &output) { for session in cursor_sessions_for_output(&shell, &output) {
if let Some((geometry, offset)) = seat.cursor_geometry( if let Some(CursorGeometry { geometry, hotspot }) = seat.cursor_geometry(
point.to_buffer( point.to_buffer(
output.current_scale().fractional_scale(), output.current_scale().fractional_scale(),
output.current_transform(), output.current_transform(),
@ -2501,7 +2501,7 @@ impl State {
dma: None, dma: None,
}); });
} }
session.set_cursor_hotspot(offset); session.set_cursor_hotspot(hotspot);
session.set_cursor_pos(Some(geometry.loc)); session.set_cursor_pos(Some(geometry.loc));
} }
} }

View file

@ -6,7 +6,7 @@ use std::{
use crate::{ use crate::{
shell::{ shell::{
CosmicSurface, SeatExt, CosmicSurface, CursorGeometry, SeatExt,
element::{CosmicMapped, CosmicStack, CosmicWindow}, element::{CosmicMapped, CosmicStack, CosmicWindow},
layout::tiling::ResizeForkTarget, layout::tiling::ResizeForkTarget,
zoom::ZoomFocusTarget, zoom::ZoomFocusTarget,
@ -272,7 +272,7 @@ impl PointerFocusTarget {
None None
}; };
let cursor_hotspot = if let Some((_, hotspot)) = let cursor_hotspot = if let Some(CursorGeometry { hotspot, .. }) =
seat.cursor_geometry((0.0, 0.0), Duration::from_millis(event.time as u64).into()) seat.cursor_geometry((0.0, 0.0), Duration::from_millis(event.time as u64).into())
{ {
hotspot hotspot

View file

@ -243,6 +243,12 @@ pub fn create_seat(
seat seat
} }
#[derive(Debug, Copy, Clone)]
pub struct CursorGeometry {
pub geometry: Rectangle<i32, Buffer>,
pub hotspot: Point<i32, Buffer>,
}
pub trait SeatExt { pub trait SeatExt {
fn id(&self) -> usize; fn id(&self) -> usize;
@ -266,7 +272,7 @@ pub trait SeatExt {
&self, &self,
loc: impl Into<Point<f64, Buffer>>, loc: impl Into<Point<f64, Buffer>>,
time: Time<Monotonic>, time: Time<Monotonic>,
) -> Option<(Rectangle<i32, Buffer>, Point<i32, Buffer>)>; ) -> Option<CursorGeometry>;
fn cursor_image_status(&self) -> CursorImageStatus; fn cursor_image_status(&self) -> CursorImageStatus;
fn set_cursor_image_status(&self, status: CursorImageStatus); fn set_cursor_image_status(&self, status: CursorImageStatus);
} }
@ -367,7 +373,7 @@ impl SeatExt for Seat<State> {
&self, &self,
loc: impl Into<Point<f64, Buffer>>, loc: impl Into<Point<f64, Buffer>>,
time: Time<Monotonic>, time: Time<Monotonic>,
) -> Option<(Rectangle<i32, Buffer>, Point<i32, Buffer>)> { ) -> Option<CursorGeometry> {
let location = loc.into().to_i32_round(); let location = loc.into().to_i32_round();
match self.cursor_image_status() { match self.cursor_image_status() {
@ -386,7 +392,10 @@ impl SeatExt for Seat<State> {
(geo.loc.x, geo.loc.y).into(), (geo.loc.x, geo.loc.y).into(),
geo.size.to_buffer(1, Transform::Normal), geo.size.to_buffer(1, Transform::Normal),
); );
Some((buffer_geo, (hotspot.x, hotspot.y).into())) Some(CursorGeometry {
geometry: buffer_geo,
hotspot: (hotspot.x, hotspot.y).into(),
})
} }
CursorImageStatus::Named(cursor_icon) => { CursorImageStatus::Named(cursor_icon) => {
let seat_userdata = self.user_data(); let seat_userdata = self.user_data();
@ -398,10 +407,13 @@ impl SeatExt for Seat<State> {
.get_named_cursor(cursor_icon) .get_named_cursor(cursor_icon)
.get_image(1, time.as_millis()); .get_image(1, time.as_millis());
Some(( Some(CursorGeometry {
Rectangle::new(location, (frame.width as i32, frame.height as i32).into()), geometry: Rectangle::new(
(frame.xhot as i32, frame.yhot as i32).into(), location,
)) (frame.width as i32, frame.height as i32).into(),
),
hotspot: (frame.xhot as i32, frame.yhot as i32).into(),
})
} }
CursorImageStatus::Hidden => None, CursorImageStatus::Hidden => None,
} }

View file

@ -31,7 +31,7 @@ use smithay::{
}; };
use crate::{ use crate::{
shell::{CosmicSurface, Shell}, shell::{CosmicSurface, CursorGeometry, Shell},
state::{BackendData, State}, state::{BackendData, State},
utils::prelude::{ utils::prelude::{
OutputExt, PointExt, PointGlobalExt, PointLocalExt, RectExt, RectLocalExt, SeatExt, OutputExt, PointExt, PointGlobalExt, PointLocalExt, RectExt, RectLocalExt, SeatExt,
@ -86,7 +86,7 @@ impl ImageCopyCaptureHandler for State {
) -> Option<BufferConstraints> { ) -> Option<BufferConstraints> {
let shell = self.common.shell.read(); let shell = self.common.shell.read();
let seat = seat_for_wl_pointer(&shell, pointer)?; let seat = seat_for_wl_pointer(&shell, pointer)?;
let size = if let Some((geometry, _)) = let size = if let Some(CursorGeometry { geometry, .. }) =
seat.cursor_geometry((0.0, 0.0), self.common.clock.now()) seat.cursor_geometry((0.0, 0.0), self.common.clock.now())
{ {
geometry.size geometry.size
@ -160,7 +160,7 @@ impl ImageCopyCaptureHandler for State {
let pointer = seat.get_pointer().unwrap(); let pointer = seat.get_pointer().unwrap();
let pointer_loc = pointer.current_location().to_i32_round().as_global(); let pointer_loc = pointer.current_location().to_i32_round().as_global();
let (pointer_size, hotspot) = if let Some((geometry, hotspot)) = let (pointer_size, hotspot) = if let Some(CursorGeometry { geometry, hotspot }) =
seat.cursor_geometry((0.0, 0.0), self.common.clock.now()) seat.cursor_geometry((0.0, 0.0), self.common.clock.now())
{ {
(geometry.size, hotspot) (geometry.size, hotspot)

View file

@ -45,7 +45,7 @@ use crate::{
render_workspace, render_workspace,
wayland::SurfaceRenderElement, wayland::SurfaceRenderElement,
}, },
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement}, shell::{CosmicMappedRenderElement, CosmicSurface, CursorGeometry, WorkspaceRenderElement},
state::{Common, KmsNodes, State}, state::{Common, KmsNodes, State},
utils::prelude::{PointExt, PointGlobalExt, RectExt, RectLocalExt, SeatExt}, utils::prelude::{PointExt, PointGlobalExt, RectExt, RectLocalExt, SeatExt},
wayland::{ wayland::{
@ -804,7 +804,7 @@ pub fn render_cursor_to_buffer(
let buffer = frame.buffer(); let buffer = frame.buffer();
let mut cursor_size = seat let mut cursor_size = seat
.cursor_geometry((0.0, 0.0), state.common.clock.now()) .cursor_geometry((0.0, 0.0), state.common.clock.now())
.map(|(geo, _hotspot)| geo.size) .map(|CursorGeometry { geometry, .. }| geometry.size)
.unwrap_or_else(|| Size::from((64, 64))); .unwrap_or_else(|| Size::from((64, 64)));
let buffer_size = buffer_dimensions(&buffer).unwrap(); let buffer_size = buffer_dimensions(&buffer).unwrap();
// Client shouldn't try to allocate 0x0 buffer // Client shouldn't try to allocate 0x0 buffer