1
1
use std:: sync:: Arc ;
2
2
use std:: { convert:: TryInto , num:: NonZeroU32 } ;
3
3
4
+ use smithay_client_toolkit:: seat:: keyboard:: keysyms;
4
5
use smithay_client_toolkit:: {
5
6
compositor:: { CompositorHandler , CompositorState } ,
6
7
delegate_compositor, delegate_keyboard, delegate_output, delegate_pointer, delegate_registry,
@@ -11,7 +12,8 @@ use smithay_client_toolkit::{
11
12
seat:: {
12
13
keyboard:: { KeyEvent , KeyboardHandler , Modifiers } ,
13
14
pointer:: {
14
- PointerData , PointerEvent , PointerEventKind , PointerHandler , ThemeSpec , ThemedPointer ,
15
+ CursorIcon , PointerData , PointerEvent , PointerEventKind , PointerHandler , ThemeSpec ,
16
+ ThemedPointer ,
15
17
} ,
16
18
Capability , SeatHandler , SeatState ,
17
19
} ,
@@ -36,6 +38,44 @@ use wayland_client::{
36
38
Connection , Proxy , QueueHandle ,
37
39
} ;
38
40
41
+ // Cursor shapes.
42
+ const CURSORS : & [ CursorIcon ] = & [
43
+ CursorIcon :: Default ,
44
+ CursorIcon :: Crosshair ,
45
+ CursorIcon :: Pointer ,
46
+ CursorIcon :: Move ,
47
+ CursorIcon :: Text ,
48
+ CursorIcon :: Wait ,
49
+ CursorIcon :: Help ,
50
+ CursorIcon :: Progress ,
51
+ CursorIcon :: NotAllowed ,
52
+ CursorIcon :: ContextMenu ,
53
+ CursorIcon :: Cell ,
54
+ CursorIcon :: VerticalText ,
55
+ CursorIcon :: Alias ,
56
+ CursorIcon :: Copy ,
57
+ CursorIcon :: NoDrop ,
58
+ CursorIcon :: Grab ,
59
+ CursorIcon :: Grabbing ,
60
+ CursorIcon :: AllScroll ,
61
+ CursorIcon :: ZoomIn ,
62
+ CursorIcon :: ZoomOut ,
63
+ CursorIcon :: EResize ,
64
+ CursorIcon :: NResize ,
65
+ CursorIcon :: NeResize ,
66
+ CursorIcon :: NwResize ,
67
+ CursorIcon :: SResize ,
68
+ CursorIcon :: SeResize ,
69
+ CursorIcon :: SwResize ,
70
+ CursorIcon :: WResize ,
71
+ CursorIcon :: EwResize ,
72
+ CursorIcon :: NsResize ,
73
+ CursorIcon :: NeswResize ,
74
+ CursorIcon :: NwseResize ,
75
+ CursorIcon :: ColResize ,
76
+ CursorIcon :: RowResize ,
77
+ ] ;
78
+
39
79
fn main ( ) {
40
80
env_logger:: init ( ) ;
41
81
@@ -60,7 +100,6 @@ fn main() {
60
100
. expect ( "Failed to create pool" ) ;
61
101
62
102
let window_surface = compositor_state. create_surface ( & qh) ;
63
- let pointer_surface = compositor_state. create_surface ( & qh) ;
64
103
65
104
let window =
66
105
xdg_shell_state. create_window ( window_surface, WindowDecorations :: ServerDefault , & qh) ;
@@ -76,11 +115,13 @@ fn main() {
76
115
// the correct options.
77
116
window. commit ( ) ;
78
117
118
+ println ! ( "Press `n` to cycle through cursor icons." ) ;
119
+
79
120
let mut simple_window = SimpleWindow {
80
121
registry_state,
81
122
seat_state,
82
123
output_state,
83
- _compositor_state : compositor_state,
124
+ compositor_state,
84
125
subcompositor_state : Arc :: new ( subcompositor_state) ,
85
126
shm_state,
86
127
_xdg_shell_state : xdg_shell_state,
@@ -94,21 +135,20 @@ fn main() {
94
135
buffer : None ,
95
136
window,
96
137
window_frame : None ,
97
- pointer_surface,
98
138
keyboard : None ,
99
139
keyboard_focus : false ,
100
140
themed_pointer : None ,
101
141
set_cursor : false ,
102
- cursor_icon : String :: from ( "diamond_cross" ) ,
142
+ window_cursor_icon_idx : 0 ,
143
+ decorations_cursor : None ,
103
144
} ;
104
145
105
146
// We don't draw immediately, the configure will notify us when to first draw.
106
-
107
147
loop {
108
148
event_queue. blocking_dispatch ( & mut simple_window) . unwrap ( ) ;
109
149
110
150
if simple_window. exit {
111
- println ! ( "exiting example" ) ;
151
+ println ! ( "Exiting example. " ) ;
112
152
break ;
113
153
}
114
154
}
@@ -118,7 +158,7 @@ struct SimpleWindow {
118
158
registry_state : RegistryState ,
119
159
seat_state : SeatState ,
120
160
output_state : OutputState ,
121
- _compositor_state : CompositorState ,
161
+ compositor_state : CompositorState ,
122
162
subcompositor_state : Arc < SubcompositorState > ,
123
163
shm_state : Shm ,
124
164
_xdg_shell_state : XdgShell ,
@@ -132,12 +172,12 @@ struct SimpleWindow {
132
172
buffer : Option < Buffer > ,
133
173
window : Window ,
134
174
window_frame : Option < FallbackFrame < Self > > ,
135
- pointer_surface : wl_surface:: WlSurface ,
136
175
keyboard : Option < wl_keyboard:: WlKeyboard > ,
137
176
keyboard_focus : bool ,
138
177
themed_pointer : Option < ThemedPointer > ,
139
178
set_cursor : bool ,
140
- cursor_icon : String ,
179
+ window_cursor_icon_idx : usize ,
180
+ decorations_cursor : Option < CursorIcon > ,
141
181
}
142
182
143
183
impl CompositorHandler for SimpleWindow {
@@ -247,7 +287,7 @@ impl WindowHandler for SimpleWindow {
247
287
let width = width. unwrap_or ( NonZeroU32 :: new ( 1 ) . unwrap ( ) ) ;
248
288
let height = height. unwrap_or ( NonZeroU32 :: new ( 1 ) . unwrap ( ) ) ;
249
289
250
- println ! ( "{width}, {height}" ) ;
290
+ println ! ( "New dimentions: {width}, {height}" ) ;
251
291
window_frame. resize ( width, height) ;
252
292
253
293
let ( x, y) = window_frame. location ( ) ;
@@ -311,10 +351,16 @@ impl SeatHandler for SimpleWindow {
311
351
312
352
if capability == Capability :: Pointer && self . themed_pointer . is_none ( ) {
313
353
println ! ( "Set pointer capability" ) ;
314
- println ! ( "Creating pointer theme" ) ;
354
+ let surface = self . compositor_state . create_surface ( qh ) ;
315
355
let themed_pointer = self
316
356
. seat_state
317
- . get_pointer_with_theme ( qh, & seat, ThemeSpec :: default ( ) )
357
+ . get_pointer_with_theme (
358
+ qh,
359
+ & seat,
360
+ self . shm_state . wl_shm ( ) ,
361
+ surface,
362
+ ThemeSpec :: default ( ) ,
363
+ )
318
364
. expect ( "Failed to create pointer" ) ;
319
365
self . themed_pointer . replace ( themed_pointer) ;
320
366
}
@@ -367,7 +413,6 @@ impl KeyboardHandler for SimpleWindow {
367
413
_: u32 ,
368
414
) {
369
415
if self . window . wl_surface ( ) == surface {
370
- println ! ( "Release keyboard focus on window" ) ;
371
416
self . keyboard_focus = false ;
372
417
}
373
418
}
@@ -380,7 +425,12 @@ impl KeyboardHandler for SimpleWindow {
380
425
_: u32 ,
381
426
event : KeyEvent ,
382
427
) {
383
- println ! ( "Key press: {event:?}" ) ;
428
+ if event. keysym == keysyms:: XKB_KEY_n {
429
+ // Cycle through cursor icons.
430
+ self . window_cursor_icon_idx = ( self . window_cursor_icon_idx + 1 ) % CURSORS . len ( ) ;
431
+ println ! ( "Setting cursor icon to: {}" , CURSORS [ self . window_cursor_icon_idx] . name( ) ) ;
432
+ self . set_cursor = true ;
433
+ }
384
434
}
385
435
386
436
fn release_key (
@@ -389,9 +439,8 @@ impl KeyboardHandler for SimpleWindow {
389
439
_: & QueueHandle < Self > ,
390
440
_: & wl_keyboard:: WlKeyboard ,
391
441
_: u32 ,
392
- event : KeyEvent ,
442
+ _ : KeyEvent ,
393
443
) {
394
- println ! ( "Key release: {event:?}" ) ;
395
444
}
396
445
397
446
fn update_modifiers (
@@ -400,9 +449,8 @@ impl KeyboardHandler for SimpleWindow {
400
449
_: & QueueHandle < Self > ,
401
450
_: & wl_keyboard:: WlKeyboard ,
402
451
_serial : u32 ,
403
- modifiers : Modifiers ,
452
+ _ : Modifiers ,
404
453
) {
405
- println ! ( "Update modifiers: {modifiers:?}" ) ;
406
454
}
407
455
}
408
456
@@ -420,24 +468,17 @@ impl PointerHandler for SimpleWindow {
420
468
match event. kind {
421
469
Enter { .. } => {
422
470
self . set_cursor = true ;
423
- self . cursor_icon = self
471
+ self . decorations_cursor = self
424
472
. window_frame
425
473
. as_mut ( )
426
- . and_then ( |frame| frame. click_point_moved ( & event. surface , x, y) )
427
- . unwrap_or ( "diamond_cross" )
428
- . to_owned ( ) ;
429
-
430
- if & event. surface == self . window . wl_surface ( ) {
431
- println ! ( "Pointer entered @{:?}" , event. position) ;
432
- }
474
+ . and_then ( |frame| frame. click_point_moved ( & event. surface , x, y) ) ;
433
475
}
434
476
Leave { .. } => {
435
477
if & event. surface != self . window . wl_surface ( ) {
436
478
if let Some ( window_frame) = self . window_frame . as_mut ( ) {
437
479
window_frame. click_point_left ( ) ;
438
480
}
439
481
}
440
- println ! ( "Pointer left" ) ;
441
482
}
442
483
Motion { .. } => {
443
484
if let Some ( new_cursor) = self
@@ -446,11 +487,11 @@ impl PointerHandler for SimpleWindow {
446
487
. and_then ( |frame| frame. click_point_moved ( & event. surface , x, y) )
447
488
{
448
489
self . set_cursor = true ;
449
- self . cursor_icon = new_cursor . to_owned ( ) ;
490
+ self . decorations_cursor = Some ( new_cursor ) ;
450
491
}
451
492
}
452
493
Press { button, serial, .. } | Release { button, serial, .. } => {
453
- let pressed = if matches ! ( event. kind, Press { .. } ) { true } else { false } ;
494
+ let pressed = matches ! ( event. kind, Press { .. } ) ;
454
495
if & event. surface != self . window . wl_surface ( ) {
455
496
let click = match button {
456
497
0x110 => FrameClick :: Normal ,
@@ -466,19 +507,15 @@ impl PointerHandler for SimpleWindow {
466
507
self . frame_action ( pointer, serial, action) ;
467
508
}
468
509
} else if pressed {
469
- println ! ( "Press {:x} @ {:?}" , button, event. position) ;
470
510
self . shift = self . shift . xor ( Some ( 0 ) ) ;
471
511
}
472
512
}
473
- Axis { horizontal, vertical, .. } => {
474
- if & event. surface == self . window . wl_surface ( ) {
475
- println ! ( "Scroll H:{horizontal:?}, V:{vertical:?}" ) ;
476
- }
477
- }
513
+ Axis { .. } => { }
478
514
}
479
515
}
480
516
}
481
517
}
518
+
482
519
impl SimpleWindow {
483
520
fn frame_action ( & mut self , pointer : & wl_pointer:: WlPointer , serial : u32 , action : FrameAction ) {
484
521
let pointer_data = pointer. data :: < PointerData > ( ) . unwrap ( ) ;
@@ -504,13 +541,9 @@ impl ShmHandler for SimpleWindow {
504
541
impl SimpleWindow {
505
542
pub fn draw ( & mut self , conn : & Connection , qh : & QueueHandle < Self > ) {
506
543
if self . set_cursor {
507
- let _ = self . themed_pointer . as_mut ( ) . unwrap ( ) . set_cursor (
508
- conn,
509
- & self . cursor_icon ,
510
- self . shm_state . wl_shm ( ) ,
511
- & self . pointer_surface ,
512
- 1 ,
513
- ) ;
544
+ let cursor_icon =
545
+ self . decorations_cursor . unwrap_or ( CURSORS [ self . window_cursor_icon_idx ] ) ;
546
+ let _ = self . themed_pointer . as_mut ( ) . unwrap ( ) . set_cursor ( conn, cursor_icon) ;
514
547
self . set_cursor = false ;
515
548
}
516
549
@@ -562,11 +595,11 @@ impl SimpleWindow {
562
595
}
563
596
564
597
// Draw the decorations frame.
565
- self . window_frame . as_mut ( ) . map ( |frame| {
598
+ if let Some ( frame ) = self . window_frame . as_mut ( ) {
566
599
if frame. is_dirty ( ) && !frame. is_hidden ( ) {
567
600
frame. draw ( ) ;
568
601
}
569
- } ) ;
602
+ }
570
603
571
604
// Damage the entire window
572
605
self . window . wl_surface ( ) . damage_buffer ( 0 , 0 , width as i32 , height as i32 ) ;
0 commit comments