Skip to content

Commit d2399c9

Browse files
committed
wayland/cursor_shape: only test for pointer capability
the cursor shape is only considered inert in case the pointer capability has been removed. the original pointer itself can be released by the client.
1 parent 8694ec2 commit d2399c9

File tree

1 file changed

+51
-31
lines changed

1 file changed

+51
-31
lines changed

src/wayland/cursor_shape.rs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,15 @@ use wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_device_v1::
104104
use wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_manager_v1::Request as ManagerRequest;
105105
use wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_manager_v1::WpCursorShapeManagerV1 as CursorShapeManager;
106106
use wayland_protocols::wp::tablet::zv2::server::zwp_tablet_tool_v2::ZwpTabletToolV2;
107-
use wayland_server::protocol::wl_pointer::WlPointer;
108107
use wayland_server::GlobalDispatch;
109108
use wayland_server::Resource;
110109
use wayland_server::WEnum;
110+
use wayland_server::Weak;
111111
use wayland_server::{backend::GlobalId, Dispatch, DisplayHandle};
112112

113113
use crate::input::pointer::{CursorIcon, CursorImageStatus};
114114
use crate::input::SeatHandler;
115+
use crate::input::WeakSeat;
115116
use crate::utils::Serial;
116117
use crate::wayland::seat::{pointer::allow_setting_cursor, WaylandFocus};
117118

@@ -165,12 +166,12 @@ where
165166
impl<D> Dispatch<CursorShapeManager, (), D> for CursorShapeManagerState
166167
where
167168
D: Dispatch<CursorShapeManager, ()>,
168-
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData>,
169+
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>>,
169170
D: SeatHandler,
170171
D: 'static,
171172
{
172173
fn request(
173-
_state: &mut D,
174+
state: &mut D,
174175
_client: &wayland_server::Client,
175176
_resource: &CursorShapeManager,
176177
request: <CursorShapeManager as wayland_server::Resource>::Request,
@@ -183,9 +184,27 @@ where
183184
cursor_shape_device,
184185
pointer,
185186
} => {
187+
let pointer_data = pointer.data::<PointerUserData<D>>();
188+
let handle = match pointer_data.and_then(|data| data.handle.as_ref()) {
189+
Some(handle) => handle,
190+
None => return,
191+
};
192+
193+
let Some(seat) = state
194+
.seat_state()
195+
.seats
196+
.iter()
197+
.find(|seat| seat.get_pointer().map(|h| &h == handle).unwrap_or(false))
198+
.cloned()
199+
else {
200+
return;
201+
};
202+
186203
data_init.init(
187204
cursor_shape_device,
188-
CursorShapeDeviceUserData(CursorShapeDeviceUserDataInner::Pointer(pointer)),
205+
CursorShapeDeviceUserData(CursorShapeDeviceUserDataInner::Pointer {
206+
seat: seat.downgrade(),
207+
}),
189208
);
190209
}
191210
ManagerRequest::GetTabletToolV2 {
@@ -194,7 +213,9 @@ where
194213
} => {
195214
data_init.init(
196215
cursor_shape_device,
197-
CursorShapeDeviceUserData(CursorShapeDeviceUserDataInner::Tablet(tablet_tool)),
216+
CursorShapeDeviceUserData(CursorShapeDeviceUserDataInner::Tablet(
217+
tablet_tool.downgrade(),
218+
)),
198219
);
199220
}
200221
ManagerRequest::Destroy => {}
@@ -205,30 +226,30 @@ where
205226

206227
#[doc(hidden)]
207228
#[derive(Debug, Clone)]
208-
pub struct CursorShapeDeviceUserData(CursorShapeDeviceUserDataInner);
229+
pub struct CursorShapeDeviceUserData<D: SeatHandler>(CursorShapeDeviceUserDataInner<D>);
209230

210231
#[derive(Debug, Clone)]
211-
pub(crate) enum CursorShapeDeviceUserDataInner {
232+
pub(crate) enum CursorShapeDeviceUserDataInner<D: SeatHandler> {
212233
/// The device was created for the pointer.
213-
Pointer(WlPointer),
234+
Pointer { seat: WeakSeat<D> },
214235
/// The device was created for the tablet tool.
215-
Tablet(ZwpTabletToolV2),
236+
Tablet(Weak<ZwpTabletToolV2>),
216237
}
217238

218-
impl<D> Dispatch<CursorShapeDevice, CursorShapeDeviceUserData, D> for CursorShapeManagerState
239+
impl<D> Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>, D> for CursorShapeManagerState
219240
where
220241
D: Dispatch<CursorShapeManager, ()>,
221-
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData>,
242+
D: Dispatch<CursorShapeDevice, CursorShapeDeviceUserData<D>>,
222243
D: SeatHandler + TabletSeatHandler,
223244
<D as SeatHandler>::PointerFocus: WaylandFocus,
224245
D: 'static,
225246
{
226247
fn request(
227248
state: &mut D,
228249
_client: &wayland_server::Client,
229-
_resource: &CursorShapeDevice,
250+
resource: &CursorShapeDevice,
230251
request: <CursorShapeDevice as wayland_server::Resource>::Request,
231-
data: &CursorShapeDeviceUserData,
252+
data: &CursorShapeDeviceUserData<D>,
232253
_dhandle: &DisplayHandle,
233254
_data_init: &mut wayland_server::DataInit<'_, D>,
234255
) {
@@ -238,30 +259,29 @@ where
238259
shape: WEnum::Value(shape),
239260
} => {
240261
match &data.0 {
241-
CursorShapeDeviceUserDataInner::Pointer(pointer) => {
242-
let pointer_data = pointer.data::<PointerUserData<D>>();
243-
let handle = match pointer_data.and_then(|data| data.handle.as_ref()) {
244-
Some(handle) => handle,
245-
None => return,
262+
CursorShapeDeviceUserDataInner::Pointer { seat } => {
263+
let Some(seat) = seat.upgrade() else {
264+
return;
246265
};
247266

248-
if !allow_setting_cursor(handle, Serial(serial), &pointer.id()) {
267+
let Some(handle) = seat.get_pointer() else {
268+
// When the pointer capability is removed from the wl_seat,
269+
// the wp_cursor_shape_device_v1 object becomes inert.
249270
return;
250-
}
251-
252-
let seat = state
253-
.seat_state()
254-
.seats
255-
.iter()
256-
.find(|seat| seat.get_pointer().map(|h| &h == handle).unwrap_or(false))
257-
.cloned();
271+
};
258272

259-
if let Some(seat) = seat {
260-
let cursor_icon = shape_to_cursor_icon(shape);
261-
state.cursor_image(&seat, CursorImageStatus::Named(cursor_icon));
273+
if !allow_setting_cursor(&handle, Serial(serial), &resource.id()) {
274+
return;
262275
}
276+
277+
let cursor_icon = shape_to_cursor_icon(shape);
278+
state.cursor_image(&seat, CursorImageStatus::Named(cursor_icon));
263279
}
264280
CursorShapeDeviceUserDataInner::Tablet(tablet) => {
281+
let Ok(tablet) = tablet.upgrade() else {
282+
// When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1 object becomes inert.
283+
return;
284+
};
265285
let tablet_data = match tablet.data::<TabletToolUserData>() {
266286
Some(data) => data,
267287
None => return,
@@ -346,7 +366,7 @@ macro_rules! delegate_cursor_shape {
346366
$crate::reexports::wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_manager_v1::WpCursorShapeManagerV1: ()
347367
] => $crate::wayland::cursor_shape::CursorShapeManagerState);
348368
$crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
349-
$crate::reexports::wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1: $crate::wayland::cursor_shape::CursorShapeDeviceUserData
369+
$crate::reexports::wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1: $crate::wayland::cursor_shape::CursorShapeDeviceUserData<$ty>
350370
] => $crate::wayland::cursor_shape::CursorShapeManagerState);
351371
};
352372
}

0 commit comments

Comments
 (0)