@@ -3,15 +3,23 @@ use std::{
3
3
env, mem,
4
4
sync:: { Arc , Mutex } ,
5
5
} ;
6
- use wayland_backend:: { client:: InvalidId , smallvec:: SmallVec } ;
7
6
7
+ use wayland_backend:: { client:: InvalidId , smallvec:: SmallVec } ;
8
8
use wayland_client:: {
9
- protocol:: { wl_pointer, wl_seat:: WlSeat , wl_shm, wl_surface} ,
9
+ protocol:: {
10
+ wl_pointer:: { self , WlPointer } ,
11
+ wl_seat:: WlSeat ,
12
+ wl_shm:: WlShm ,
13
+ wl_surface:: WlSurface ,
14
+ } ,
10
15
Connection , Dispatch , Proxy , QueueHandle , WEnum ,
11
16
} ;
12
17
use wayland_cursor:: { Cursor , CursorTheme } ;
13
18
14
- use crate :: error:: GlobalError ;
19
+ use crate :: {
20
+ compositor:: { SurfaceData , SurfaceDataExt } ,
21
+ error:: GlobalError ,
22
+ } ;
15
23
16
24
use super :: SeatState ;
17
25
@@ -64,7 +72,7 @@ impl AxisScroll {
64
72
/// A single pointer event.
65
73
#[ derive( Debug , Clone ) ]
66
74
pub struct PointerEvent {
67
- pub surface : wl_surface :: WlSurface ,
75
+ pub surface : WlSurface ,
68
76
pub position : ( f64 , f64 ) ,
69
77
pub kind : PointerEventKind ,
70
78
}
@@ -109,7 +117,7 @@ pub trait PointerHandler: Sized {
109
117
& mut self ,
110
118
conn : & Connection ,
111
119
qh : & QueueHandle < Self > ,
112
- pointer : & wl_pointer :: WlPointer ,
120
+ pointer : & WlPointer ,
113
121
events : & [ PointerEvent ] ,
114
122
) ;
115
123
}
@@ -169,7 +177,7 @@ macro_rules! delegate_pointer {
169
177
#[ derive( Debug , Default ) ]
170
178
pub ( crate ) struct PointerDataInner {
171
179
/// Surface the pointer most recently entered
172
- pub ( crate ) surface : Option < wl_surface :: WlSurface > ,
180
+ pub ( crate ) surface : Option < WlSurface > ,
173
181
/// Position relative to the surface
174
182
pub ( crate ) position : ( f64 , f64 ) ,
175
183
@@ -180,14 +188,14 @@ pub(crate) struct PointerDataInner {
180
188
pub ( crate ) latest_enter : Option < u32 > ,
181
189
}
182
190
183
- impl < D , U > Dispatch < wl_pointer :: WlPointer , U , D > for SeatState
191
+ impl < D , U > Dispatch < WlPointer , U , D > for SeatState
184
192
where
185
- D : Dispatch < wl_pointer :: WlPointer , U > + PointerHandler ,
193
+ D : Dispatch < WlPointer , U > + PointerHandler ,
186
194
U : PointerDataExt ,
187
195
{
188
196
fn event (
189
197
data : & mut D ,
190
- pointer : & wl_pointer :: WlPointer ,
198
+ pointer : & WlPointer ,
191
199
event : wl_pointer:: Event ,
192
200
udata : & U ,
193
201
conn : & Connection ,
@@ -372,59 +380,77 @@ where
372
380
373
381
/// Pointer themeing
374
382
#[ derive( Debug ) ]
375
- pub struct ThemedPointer < U = PointerData > {
383
+ pub struct ThemedPointer < U = PointerData , S = SurfaceData > {
376
384
pub ( super ) themes : Arc < Mutex < Themes > > ,
377
- pub ( super ) pointer : wl_pointer:: WlPointer ,
385
+ /// The underlying wl_pointer.
386
+ pub ( super ) pointer : WlPointer ,
387
+ pub ( super ) shm : WlShm ,
388
+ /// The surface owned by the cursor to present the icon.
389
+ pub ( super ) surface : WlSurface ,
378
390
pub ( super ) _marker : std:: marker:: PhantomData < U > ,
391
+ pub ( super ) _surface_data : std:: marker:: PhantomData < S > ,
379
392
}
380
393
381
- impl < U : PointerDataExt + ' static > ThemedPointer < U > {
382
- pub fn set_cursor (
383
- & self ,
384
- conn : & Connection ,
385
- name : & str ,
386
- shm : & wl_shm:: WlShm ,
387
- surface : & wl_surface:: WlSurface ,
388
- scale : i32 ,
389
- ) -> Result < ( ) , PointerThemeError > {
394
+ impl < U : PointerDataExt + ' static , S : SurfaceDataExt + ' static > ThemedPointer < U , S > {
395
+ pub fn set_cursor ( & self , conn : & Connection , name : & str ) -> Result < ( ) , PointerThemeError > {
390
396
let mut themes = self . themes . lock ( ) . unwrap ( ) ;
391
397
398
+ let scale = self . surface . data :: < S > ( ) . unwrap ( ) . surface_data ( ) . scale_factor ( ) ;
392
399
let cursor = themes
393
- . get_cursor ( conn, name, scale as u32 , shm)
400
+ . get_cursor ( conn, name, scale as u32 , & self . shm )
394
401
. map_err ( PointerThemeError :: InvalidId ) ?
395
402
. ok_or ( PointerThemeError :: CursorNotFound ) ?;
396
403
397
404
let image = & cursor[ 0 ] ;
398
405
let ( w, h) = image. dimensions ( ) ;
399
406
let ( hx, hy) = image. hotspot ( ) ;
400
407
401
- surface. set_buffer_scale ( scale) ;
402
- surface. attach ( Some ( image) , 0 , 0 ) ;
408
+ self . surface . set_buffer_scale ( scale) ;
409
+ self . surface . attach ( Some ( image) , 0 , 0 ) ;
403
410
404
- if surface. version ( ) >= 4 {
405
- surface. damage_buffer ( 0 , 0 , w as i32 , h as i32 ) ;
411
+ if self . surface . version ( ) >= 4 {
412
+ self . surface . damage_buffer ( 0 , 0 , w as i32 , h as i32 ) ;
406
413
} else {
407
- // surface is old and does not support damage_buffer, so we damage
408
- // in surface coordinates and hope it is not rescaled
409
- surface. damage ( 0 , 0 , w as i32 / scale, h as i32 / scale) ;
414
+ // Fallback for the old old surface.
415
+ self . surface . damage ( 0 , 0 , w as i32 / scale, h as i32 / scale) ;
410
416
}
411
417
412
418
// Commit the surface to place the cursor image in the compositor's memory.
413
- surface. commit ( ) ;
419
+ self . surface . commit ( ) ;
414
420
415
421
// Set the pointer surface to change the pointer.
416
422
let data = self . pointer . data :: < U > ( ) ;
417
423
if let Some ( serial) = data. and_then ( |data| data. pointer_data ( ) . latest_enter_serial ( ) ) {
418
- self . pointer . set_cursor ( serial, Some ( surface) , hx as i32 / scale, hy as i32 / scale) ;
424
+ self . pointer . set_cursor (
425
+ serial,
426
+ Some ( & self . surface ) ,
427
+ hx as i32 / scale,
428
+ hy as i32 / scale,
429
+ ) ;
419
430
Ok ( ( ) )
420
431
} else {
421
432
Err ( PointerThemeError :: MissingEnterSerial )
422
433
}
423
434
}
424
435
425
- pub fn pointer ( & self ) -> & wl_pointer:: WlPointer {
436
+ /// The [`WlPointer`] associated with this [`ThemedPointer`].
437
+ pub fn pointer ( & self ) -> & WlPointer {
426
438
& self . pointer
427
439
}
440
+
441
+ /// The associated [`WlSurface`] with this [`ThemedPointer`].
442
+ pub fn surface ( & self ) -> & WlSurface {
443
+ & self . surface
444
+ }
445
+ }
446
+
447
+ impl < U , S > Drop for ThemedPointer < U , S > {
448
+ fn drop ( & mut self ) {
449
+ if self . pointer . version ( ) >= 3 {
450
+ self . pointer . release ( ) ;
451
+ }
452
+ self . surface . destroy ( ) ;
453
+ }
428
454
}
429
455
430
456
/// Specifies which cursor theme should be used by the theme manager.
@@ -509,7 +535,7 @@ impl Themes {
509
535
conn : & Connection ,
510
536
name : & str ,
511
537
scale : u32 ,
512
- shm : & wl_shm :: WlShm ,
538
+ shm : & WlShm ,
513
539
) -> Result < Option < & Cursor > , InvalidId > {
514
540
// Check if the theme has been initialized at the specified scale.
515
541
if let Entry :: Vacant ( e) = self . themes . entry ( scale) {
0 commit comments