@@ -104,14 +104,15 @@ use wayland_protocols::wp::cursor_shape::v1::server::wp_cursor_shape_device_v1::
104104use wayland_protocols:: wp:: cursor_shape:: v1:: server:: wp_cursor_shape_manager_v1:: Request as ManagerRequest ;
105105use wayland_protocols:: wp:: cursor_shape:: v1:: server:: wp_cursor_shape_manager_v1:: WpCursorShapeManagerV1 as CursorShapeManager ;
106106use wayland_protocols:: wp:: tablet:: zv2:: server:: zwp_tablet_tool_v2:: ZwpTabletToolV2 ;
107- use wayland_server:: protocol:: wl_pointer:: WlPointer ;
108107use wayland_server:: GlobalDispatch ;
109108use wayland_server:: Resource ;
110109use wayland_server:: WEnum ;
110+ use wayland_server:: Weak ;
111111use wayland_server:: { backend:: GlobalId , Dispatch , DisplayHandle } ;
112112
113113use crate :: input:: pointer:: { CursorIcon , CursorImageStatus } ;
114114use crate :: input:: SeatHandler ;
115+ use crate :: input:: WeakSeat ;
115116use crate :: utils:: Serial ;
116117use crate :: wayland:: seat:: { pointer:: allow_setting_cursor, WaylandFocus } ;
117118
@@ -165,12 +166,12 @@ where
165166impl < D > Dispatch < CursorShapeManager , ( ) , D > for CursorShapeManagerState
166167where
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
219240where
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