gioser

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Definiciones

⎇ main vendor/smithay/src/input/mod.rs Rust · 695 líneas · 28.8 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0) a91da3fea · Sergio ·

1//!
2//! Input abstractions
3//!
4//! This module provides some types loosely resembling instances of wayland seats, pointers, touch and keyboards.
5//! It is however not directly tied to wayland and can be used to multiplex various input operations
6//! between different handlers.
7//!
8//! If the `wayland_frontend`-feature is enabled the `smithay::wayland::seat`-module provides additional
9//! functionality for the provided types of this module to map them to advertised wayland globals and objects.
10//!
11//! ## How to use it
12//!
13//! To start using this module you need to create a [`SeatState`] and use that to create [`Seat`]s.
14//! Additionally you need to implement the [`SeatHandler`] trait.
15//!
16//! ### Initialization
17//!
18//! ```
19//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
20//! # use smithay::backend::input::KeyState;
21//! # use smithay::input::{
22//! #   pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
23//! #             GestureSwipeBeginEvent, GestureSwipeUpdateEvent, GestureSwipeEndEvent,
24//! #             GesturePinchBeginEvent, GesturePinchUpdateEvent, GesturePinchEndEvent,
25//! #             GestureHoldBeginEvent, GestureHoldEndEvent},
26//! #   keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
27//! #   touch::{DownEvent, UpEvent, MotionEvent as TouchMotionEvent, ShapeEvent, OrientationEvent, TouchTarget},
28//! # };
29//! # use smithay::utils::{IsAlive, Serial};
30//!
31//! struct State {
32//!     seat_state: SeatState<Self>,
33//!     // ...
34//! };
35//!
36//! let mut seat_state = SeatState::<State>::new();
37//!
38//! // create the seat
39//! let seat = seat_state.new_seat(
40//!     "seat-0",  // the name of the seat, will be advertized to clients
41//! );
42//!
43//! # #[derive(Debug, Clone, PartialEq)]
44//! # struct Target;
45//! # impl IsAlive for Target {
46//! #   fn alive(&self) -> bool { true }
47//! # }
48//! # impl PointerTarget<State> for Target {
49//! #   fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
50//! #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
51//! #   fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {}
52//! #   fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {}
53//! #   fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {}
54//! #   fn frame(&self, seat: &Seat<State>, data: &mut State) {}
55//! #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {}
56//! #   fn gesture_swipe_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeBeginEvent) {}
57//! #   fn gesture_swipe_update(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeUpdateEvent) {}
58//! #   fn gesture_swipe_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeEndEvent) {}
59//! #   fn gesture_pinch_begin(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchBeginEvent) {}
60//! #   fn gesture_pinch_update(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchUpdateEvent) {}
61//! #   fn gesture_pinch_end(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchEndEvent) {}
62//! #   fn gesture_hold_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldBeginEvent) {}
63//! #   fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {}
64//! # }
65//! # impl KeyboardTarget<State> for Target {
66//! #   fn enter(&self, seat: &Seat<State>, data: &mut State, keys: Vec<KeysymHandle<'_>>, serial: Serial) {}
67//! #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial) {}
68//! #   fn key(
69//! #       &self,
70//! #       seat: &Seat<State>,
71//! #       data: &mut State,
72//! #       key: KeysymHandle<'_>,
73//! #       state: KeyState,
74//! #       serial: Serial,
75//! #       time: u32,
76//! #   ) {}
77//! #   fn modifiers(&self, seat: &Seat<State>, data: &mut State, modifiers: ModifiersState, serial: Serial) {}
78//! # }
79//! # impl TouchTarget<State> for Target {
80//! #   fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {}
81//! #   fn up(&self, seat: &Seat<State>, data: &mut State, event: &UpEvent, seq: Serial) {}
82//! #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &TouchMotionEvent, seq: Serial) {}
83//! #   fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
84//! #   fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
85//! #   fn shape(&self, seat: &Seat<State>, data: &mut State, event: &ShapeEvent, seq: Serial) {}
86//! #   fn orientation(&self, seat: &Seat<State>, data: &mut State, event: &OrientationEvent, seq: Serial) {}
87//! # }
88//!
89//! // implement the required traits
90//! impl SeatHandler for State {
91//!     type KeyboardFocus = Target;
92//!     type PointerFocus = Target;
93//!     type TouchFocus = Target;
94//!
95//!     fn seat_state(&mut self) -> &mut SeatState<Self> {
96//!         &mut self.seat_state
97//!     }
98//!
99//!     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Target>) {
100//!         // handle focus changes, if you need to ...
101//!     }
102//!     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) {
103//!         // handle new images for the cursor ...
104//!     }
105//! }
106//! ```
107//!
108//! ### Run usage
109//!
110//! Once the seat is initialized, you can add capabilities to it.
111//!
112//! Currently, pointer, touch and keyboard capabilities are supported by this module.
113//! [`tablet_manager`](crate::wayland::tablet_manager) also provides client interaction for drawing tablets.
114//!
115//! You can add these capabilities via methods of the [`Seat`] struct:
116//! [`Seat::add_keyboard`], [`Seat::add_pointer`] and [`Seat::add_touch`].
117//! These methods return handles that can be cloned and sent across thread, so you can keep one around
118//! in your event-handling code to forward inputs to your clients.
119//!
120
121use std::{
122    fmt,
123    hash::Hash,
124    sync::{Arc, Mutex, Weak},
125};
126
127use tracing::{info_span, instrument};
128
129use self::touch::TouchTarget;
130use self::{
131    keyboard::{Error as KeyboardError, KeyboardHandle, KeyboardTarget, LedState},
132    touch::TouchHandle,
133};
134use self::{
135    pointer::{CursorImageStatus, PointerHandle, PointerTarget},
136    touch::TouchGrab,
137};
138use crate::utils::{user_data::UserDataMap, Serial};
139
140pub mod keyboard;
141pub mod pointer;
142pub mod touch;
143
144/// Handler trait for Seats
145pub trait SeatHandler: Sized {
146    /// Type used to represent the target currently holding the keyboard focus
147    type KeyboardFocus: KeyboardTarget<Self> + 'static;
148    /// Type used to represent the target currently holding the pointer focus
149    type PointerFocus: PointerTarget<Self> + 'static;
150    /// Type used to represent the target currently holding the touch focus
151    type TouchFocus: TouchTarget<Self> + 'static;
152
153    /// [SeatState] getter
154    fn seat_state(&mut self) -> &mut SeatState<Self>;
155
156    /// Callback that will be notified whenever the focus of the seat changes.
157    fn focus_changed(&mut self, _seat: &Seat<Self>, _focused: Option<&Self::KeyboardFocus>) {}
158
159    /// Callback that will be notified whenever a client requests to set a custom cursor image.
160    fn cursor_image(&mut self, _seat: &Seat<Self>, _image: CursorImageStatus) {}
161
162    /// Callback that will be notified whenever the keyboard led state changes.
163    fn led_state_changed(&mut self, _seat: &Seat<Self>, _led_state: LedState) {}
164}
165/// Delegate type for all [Seat] globals.
166///
167/// Events will be forwarded to an instance of the Seat global.
168pub struct SeatState<D: SeatHandler> {
169    pub(crate) seats: Vec<Seat<D>>,
170}
171
172impl<D: SeatHandler> fmt::Debug for SeatState<D> {
173    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174        f.debug_struct("SeatState").field("seats", &self.seats).finish()
175    }
176}
177
178/// A Seat handle
179///
180/// This struct gives you access to the control of the
181/// capabilities of the associated seat.
182///
183/// This is an handle to the inner logic, it can be cloned.
184///
185/// See module-level documentation for details of use.
186pub struct Seat<D: SeatHandler> {
187    pub(crate) arc: Arc<SeatRc<D>>,
188}
189
190/// Weak variant of an [`Seat`]
191///
192/// Does not keep associated user data alive,
193/// and can be used to refer to a potentially already destroyed seat.
194#[derive(Debug, Clone)]
195pub struct WeakSeat<D: SeatHandler>(Weak<SeatRc<D>>);
196
197impl<D: SeatHandler> WeakSeat<D> {
198    /// Try to retrieve the original `Seat`, if it still exists
199    pub fn upgrade(&self) -> Option<Seat<D>> {
200        self.0.upgrade().map(|arc| Seat { arc })
201    }
202
203    /// Check if the seat is still alive
204    pub fn is_alive(&self) -> bool {
205        self.0.strong_count() != 0
206    }
207}
208
209impl<D: SeatHandler> Seat<D> {
210    /// Create a weak reference to this seat
211    pub fn downgrade(&self) -> WeakSeat<D> {
212        WeakSeat(Arc::downgrade(&self.arc))
213    }
214}
215
216impl<D: SeatHandler> fmt::Debug for Seat<D> {
217    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218        f.debug_struct("Seat").field("arc", &self.arc).finish()
219    }
220}
221
222impl<D: SeatHandler> PartialEq for Seat<D> {
223    #[inline]
224    fn eq(&self, other: &Self) -> bool {
225        Arc::ptr_eq(&self.arc, &other.arc)
226    }
227}
228impl<D: SeatHandler> Eq for Seat<D> {}
229
230impl<D: SeatHandler> Hash for Seat<D> {
231    #[inline]
232    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
233        Arc::as_ptr(&self.arc).hash(state)
234    }
235}
236
237pub(crate) struct Inner<D: SeatHandler> {
238    pub(crate) pointer: Option<PointerHandle<D>>,
239    pub(crate) keyboard: Option<KeyboardHandle<D>>,
240    pub(crate) touch: Option<TouchHandle<D>>,
241
242    #[cfg(feature = "wayland_frontend")]
243    pub(crate) global: Option<wayland_server::backend::GlobalId>,
244    #[cfg(feature = "wayland_frontend")]
245    pub(crate) known_seats: Vec<wayland_server::Weak<wayland_server::protocol::wl_seat::WlSeat>>,
246}
247
248#[cfg(not(feature = "wayland_frontend"))]
249impl<D: SeatHandler> fmt::Debug for Inner<D> {
250    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251        f.debug_struct("Inner")
252            .field("pointer", &self.pointer)
253            .field("keyboard", &self.keyboard)
254            .finish()
255    }
256}
257
258#[cfg(feature = "wayland_frontend")]
259impl<D: SeatHandler> fmt::Debug for Inner<D> {
260    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261        f.debug_struct("Inner")
262            .field("pointer", &self.pointer)
263            .field("keyboard", &self.keyboard)
264            .field("touch", &self.touch)
265            .field("global", &self.global)
266            .field("known_seats", &self.known_seats)
267            .finish()
268    }
269}
270
271pub(crate) struct SeatRc<D: SeatHandler> {
272    #[allow(dead_code)]
273    pub(crate) name: String,
274    pub(crate) inner: Mutex<Inner<D>>,
275    span: tracing::Span,
276    user_data_map: UserDataMap,
277}
278
279impl<D: SeatHandler> fmt::Debug for SeatRc<D> {
280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281        f.debug_struct("SeatRc")
282            .field("name", &self.name)
283            .field("inner", &self.inner)
284            .field("user_data_map", &self.user_data_map)
285            .finish()
286    }
287}
288
289impl<D: SeatHandler> Clone for Seat<D> {
290    #[inline]
291    fn clone(&self) -> Self {
292        Self {
293            arc: self.arc.clone(),
294        }
295    }
296}
297
298impl<D: SeatHandler> Default for SeatState<D> {
299    #[inline]
300    fn default() -> Self {
301        Self::new()
302    }
303}
304
305impl<D: SeatHandler> SeatState<D> {
306    /// Create new delegate SeatState
307    pub fn new() -> Self {
308        Self { seats: Vec::new() }
309    }
310
311    /// Create a new seat
312    pub fn new_seat<N>(&mut self, name: N) -> Seat<D>
313    where
314        N: Into<String>,
315    {
316        let name = name.into();
317        let span = info_span!("input_seat", name);
318
319        let arc = Arc::new(SeatRc {
320            name,
321            inner: Mutex::new(Inner {
322                pointer: None,
323                keyboard: None,
324                touch: None,
325
326                #[cfg(feature = "wayland_frontend")]
327                global: None,
328                #[cfg(feature = "wayland_frontend")]
329                known_seats: Vec::new(),
330            }),
331            span,
332            user_data_map: UserDataMap::new(),
333        });
334        self.seats.push(Seat { arc: arc.clone() });
335
336        Seat { arc }
337    }
338}
339
340impl<D: SeatHandler + 'static> Seat<D> {
341    /// Access the `UserDataMap` associated with this `Seat`
342    pub fn user_data(&self) -> &UserDataMap {
343        &self.arc.user_data_map
344    }
345
346    /// Adds the pointer capability to this seat
347    ///
348    /// You are provided a [`PointerHandle`], which allows you to send input events
349    /// to this pointer. This handle can be cloned.
350    ///
351    /// Calling this method on a seat that already has a pointer capability
352    /// will overwrite it, and will be seen by the clients as if the
353    /// mouse was unplugged and a new one was plugged.
354    ///
355    /// # Examples
356    ///
357    /// ```no_run
358    /// # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
359    /// # use smithay::backend::input::KeyState;
360    /// # use smithay::input::{
361    /// #   pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
362    /// #             GestureSwipeBeginEvent, GestureSwipeUpdateEvent, GestureSwipeEndEvent,
363    /// #             GesturePinchBeginEvent, GesturePinchUpdateEvent, GesturePinchEndEvent,
364    /// #             GestureHoldBeginEvent, GestureHoldEndEvent},
365    /// #   keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
366    /// #   touch::{DownEvent, UpEvent, MotionEvent as TouchMotionEvent, ShapeEvent, OrientationEvent, TouchTarget},
367    /// # };
368    /// # use smithay::utils::{IsAlive, Serial};
369    /// #
370    /// # #[derive(Debug, Clone, PartialEq)]
371    /// # struct Target;
372    /// # impl IsAlive for Target {
373    /// #   fn alive(&self) -> bool { true }
374    /// # }
375    /// # impl PointerTarget<State> for Target {
376    /// #   fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
377    /// #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
378    /// #   fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {}
379    /// #   fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {}
380    /// #   fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {}
381    /// #   fn frame(&self, seat: &Seat<State>, data: &mut State) {}
382    /// #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {}
383    /// #   fn gesture_swipe_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeBeginEvent) {}
384    /// #   fn gesture_swipe_update(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeUpdateEvent) {}
385    /// #   fn gesture_swipe_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeEndEvent) {}
386    /// #   fn gesture_pinch_begin(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchBeginEvent) {}
387    /// #   fn gesture_pinch_update(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchUpdateEvent) {}
388    /// #   fn gesture_pinch_end(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchEndEvent) {}
389    /// #   fn gesture_hold_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldBeginEvent) {}
390    /// #   fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {}
391    /// # }
392    /// # impl KeyboardTarget<State> for Target {
393    /// #   fn enter(&self, seat: &Seat<State>, data: &mut State, keys: Vec<KeysymHandle<'_>>, serial: Serial) {}
394    /// #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial) {}
395    /// #   fn key(
396    /// #       &self,
397    /// #       seat: &Seat<State>,
398    /// #       data: &mut State,
399    /// #       key: KeysymHandle<'_>,
400    /// #       state: KeyState,
401    /// #       serial: Serial,
402    /// #       time: u32,
403    /// #   ) {}
404    /// #   fn modifiers(&self, seat: &Seat<State>, data: &mut State, modifiers: ModifiersState, serial: Serial) {}
405    /// # }
406    /// # impl TouchTarget<State> for Target {
407    /// #   fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {}
408    /// #   fn up(&self, seat: &Seat<State>, data: &mut State, event: &UpEvent, seq: Serial) {}
409    /// #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &TouchMotionEvent, seq: Serial) {}
410    /// #   fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
411    /// #   fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
412    /// #   fn shape(&self, seat: &Seat<State>, data: &mut State, event: &ShapeEvent, seq: Serial) {}
413    /// #   fn orientation(&self, seat: &Seat<State>, data: &mut State, event: &OrientationEvent, seq: Serial) {}
414    /// # }
415    /// # struct State;
416    /// # impl SeatHandler for State {
417    /// #     type KeyboardFocus = Target;
418    /// #     type PointerFocus = Target;
419    /// #     type TouchFocus = Target;
420    /// #
421    /// #     fn seat_state(&mut self) -> &mut SeatState<Self> { unimplemented!() }
422    /// #     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Target>) { unimplemented!() }
423    /// #     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
424    /// # }
425    /// # let mut seat: Seat<State> = unimplemented!();
426    /// let pointer_handle = seat.add_pointer();
427    /// ```
428    #[instrument(parent = &self.arc.span, skip(self))]
429    pub fn add_pointer(&mut self) -> PointerHandle<D> {
430        let mut inner = self.arc.inner.lock().unwrap();
431        let pointer = PointerHandle::new();
432        if inner.pointer.is_some() {
433            // there is already a pointer, remove it and notify the clients
434            // of the change
435            inner.pointer = None;
436            #[cfg(feature = "wayland_frontend")]
437            inner.send_all_caps();
438        }
439        inner.pointer = Some(pointer.clone());
440        #[cfg(feature = "wayland_frontend")]
441        inner.send_all_caps();
442        pointer
443    }
444
445    /// Access the pointer of this seat if any
446    pub fn get_pointer(&self) -> Option<PointerHandle<D>> {
447        self.arc.inner.lock().unwrap().pointer.clone()
448    }
449
450    /// Remove the pointer capability from this seat
451    ///
452    /// Clients will be appropriately notified.
453    #[instrument(parent = &self.arc.span, skip(self))]
454    pub fn remove_pointer(&mut self) {
455        let mut inner = self.arc.inner.lock().unwrap();
456        if inner.pointer.is_some() {
457            inner.pointer = None;
458            #[cfg(feature = "wayland_frontend")]
459            inner.send_all_caps();
460        }
461    }
462
463    /// Adds the keyboard capability to this seat
464    ///
465    /// You are provided a [`KeyboardHandle`], which allows you to send input events
466    /// to this keyboard. This handle can be cloned.
467    ///
468    /// You also provide a Model/Layout/Variant/Options specification of the
469    /// keymap to be used for this keyboard, as well as any repeat-info that
470    /// will be forwarded to the clients.
471    ///
472    /// Calling this method on a seat that already has a keyboard capability
473    /// will overwrite it, and will be seen by the clients as if the
474    /// keyboard was unplugged and a new one was plugged.
475    ///
476    /// # Examples
477    ///
478    /// ```no_run
479    /// # use smithay::input::{Seat, SeatState, SeatHandler, keyboard::XkbConfig, pointer::CursorImageStatus};
480    /// # use smithay::backend::input::KeyState;
481    /// # use smithay::input::{
482    /// #   pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
483    /// #             GestureSwipeBeginEvent, GestureSwipeUpdateEvent, GestureSwipeEndEvent,
484    /// #             GesturePinchBeginEvent, GesturePinchUpdateEvent, GesturePinchEndEvent,
485    /// #             GestureHoldBeginEvent, GestureHoldEndEvent},
486    /// #   keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
487    /// #   touch::{DownEvent, UpEvent, MotionEvent as TouchMotionEvent, ShapeEvent, OrientationEvent, TouchTarget},
488    /// # };
489    /// # use smithay::utils::{IsAlive, Serial};
490    /// #
491    /// # #[derive(Debug, Clone, PartialEq)]
492    /// # struct Target;
493    /// # impl IsAlive for Target {
494    /// #   fn alive(&self) -> bool { true }
495    /// # }
496    /// # impl PointerTarget<State> for Target {
497    /// #   fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
498    /// #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
499    /// #   fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {}
500    /// #   fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {}
501    /// #   fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {}
502    /// #   fn frame(&self, seat: &Seat<State>, data: &mut State) {}
503    /// #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {}
504    /// #   fn gesture_swipe_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeBeginEvent) {}
505    /// #   fn gesture_swipe_update(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeUpdateEvent) {}
506    /// #   fn gesture_swipe_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeEndEvent) {}
507    /// #   fn gesture_pinch_begin(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchBeginEvent) {}
508    /// #   fn gesture_pinch_update(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchUpdateEvent) {}
509    /// #   fn gesture_pinch_end(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchEndEvent) {}
510    /// #   fn gesture_hold_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldBeginEvent) {}
511    /// #   fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {}
512    /// # }
513    /// # impl KeyboardTarget<State> for Target {
514    /// #   fn enter(&self, seat: &Seat<State>, data: &mut State, keys: Vec<KeysymHandle<'_>>, serial: Serial) {}
515    /// #   fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial) {}
516    /// #   fn key(
517    /// #       &self,
518    /// #       seat: &Seat<State>,
519    /// #       data: &mut State,
520    /// #       key: KeysymHandle<'_>,
521    /// #       state: KeyState,
522    /// #       serial: Serial,
523    /// #       time: u32,
524    /// #   ) {}
525    /// #   fn modifiers(&self, seat: &Seat<State>, data: &mut State, modifiers: ModifiersState, serial: Serial) {}
526    /// # }
527    /// # impl TouchTarget<State> for Target {
528    /// #   fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {}
529    /// #   fn up(&self, seat: &Seat<State>, data: &mut State, event: &UpEvent, seq: Serial) {}
530    /// #   fn motion(&self, seat: &Seat<State>, data: &mut State, event: &TouchMotionEvent, seq: Serial) {}
531    /// #   fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
532    /// #   fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
533    /// #   fn shape(&self, seat: &Seat<State>, data: &mut State, event: &ShapeEvent, seq: Serial) {}
534    /// #   fn orientation(&self, seat: &Seat<State>, data: &mut State, event: &OrientationEvent, seq: Serial) {}
535    /// # }
536    /// #
537    /// # struct State;
538    /// # impl SeatHandler for State {
539    /// #     type KeyboardFocus = Target;
540    /// #     type PointerFocus = Target;
541    /// #     type TouchFocus = Target;
542    /// #
543    /// #     fn seat_state(&mut self) -> &mut SeatState<Self> { unimplemented!() }
544    /// #     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Target>) { unimplemented!() }
545    /// #     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
546    /// # }
547    /// # let mut seat: Seat<State> = unimplemented!();
548    /// let keyboard = seat
549    ///     .add_keyboard(
550    ///         XkbConfig {
551    ///             layout: "de",
552    ///             variant: "nodeadkeys",
553    ///             ..XkbConfig::default()
554    ///         },
555    ///         200,
556    ///         25,
557    ///     )
558    ///     .expect("Failed to initialize the keyboard");
559    /// ```
560    #[instrument(parent = &self.arc.span, skip(self))]
561    pub fn add_keyboard(
562        &mut self,
563        xkb_config: keyboard::XkbConfig<'_>,
564        repeat_delay: i32,
565        repeat_rate: i32,
566    ) -> Result<KeyboardHandle<D>, KeyboardError> {
567        let mut inner = self.arc.inner.lock().unwrap();
568        let keyboard = self::keyboard::KeyboardHandle::new(xkb_config, repeat_delay, repeat_rate)?;
569        if inner.keyboard.is_some() {
570            // there is already a keyboard, remove it and notify the clients
571            // of the change
572            inner.keyboard = None;
573            #[cfg(feature = "wayland_frontend")]
574            inner.send_all_caps();
575        }
576        inner.keyboard = Some(keyboard.clone());
577        #[cfg(feature = "wayland_frontend")]
578        inner.send_all_caps();
579        Ok(keyboard)
580    }
581
582    /// Access the keyboard of this seat if any
583    pub fn get_keyboard(&self) -> Option<KeyboardHandle<D>> {
584        self.arc.inner.lock().unwrap().keyboard.clone()
585    }
586
587    /// Remove the keyboard capability from this seat
588    ///
589    /// Clients will be appropriately notified.
590    #[instrument(parent = &self.arc.span, skip(self))]
591    pub fn remove_keyboard(&mut self) {
592        let mut inner = self.arc.inner.lock().unwrap();
593        if inner.keyboard.is_some() {
594            inner.keyboard = None;
595            #[cfg(feature = "wayland_frontend")]
596            inner.send_all_caps();
597        }
598    }
599
600    /// Adds the touch capability to this seat
601    ///
602    /// You are provided a [`TouchHandle`], which allows you to send input events
603    /// to this pointer. This handle can be cloned.
604    ///
605    /// Calling this method on a seat that already has a touch capability
606    /// will overwrite it, and will be seen by the clients as if the
607    /// touchscreen was unplugged and a new one was plugged in.
608    ///
609    /// # Examples
610    ///
611    /// ```no_run
612    /// # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
613    /// # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
614    /// #
615    /// # struct State;
616    /// # impl SeatHandler for State {
617    /// #     type KeyboardFocus = WlSurface;
618    /// #     type PointerFocus = WlSurface;
619    /// #     type TouchFocus = WlSurface;
620    /// #     fn seat_state(&mut self) -> &mut SeatState<Self> { unimplemented!() }
621    /// #     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
622    /// #     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
623    /// # }
624    /// # let mut seat: Seat<State> = unimplemented!();
625    /// let touch_handle = seat.add_touch();
626    /// ```
627    pub fn add_touch(&mut self) -> TouchHandle<D> {
628        Self::add_touch_with_default_grab(self, || Box::new(touch::DefaultGrab))
629    }
630
631    /// Adds the touch capability to this seat and allows the use of a custom default [`TouchGrab`]
632    ///
633    /// The default grab is used in case no other grab is currently active. When using [`Seat::add_touch`]
634    /// it will use [`touch::DefaultGrab`] which will install [`touch::TouchDownGrab`] on the first touch point.
635    /// [`touch::TouchDownGrab`] makes sure all further touch points will use the same target until all touch
636    /// points are released again.
637    ///
638    /// See [`Seat::add_touch`] for more information
639    pub fn add_touch_with_default_grab<F>(&mut self, defaut_grab: F) -> TouchHandle<D>
640    where
641        F: Fn() -> Box<dyn TouchGrab<D>> + Send + 'static,
642    {
643        let mut inner = self.arc.inner.lock().unwrap();
644        let touch = TouchHandle::new(defaut_grab);
645        if inner.touch.is_some() {
646            // If there's already a tocuh device, remove it notify the clients about the change.
647            inner.touch = None;
648            #[cfg(feature = "wayland_frontend")]
649            inner.send_all_caps();
650        }
651        inner.touch = Some(touch.clone());
652        #[cfg(feature = "wayland_frontend")]
653        inner.send_all_caps();
654        touch
655    }
656
657    /// Access the touch device of this seat, if any.
658    pub fn get_touch(&self) -> Option<TouchHandle<D>> {
659        self.arc.inner.lock().unwrap().touch.clone()
660    }
661
662    /// Remove the touch capability from this seat
663    ///
664    /// Clients will be appropriately notified.
665    pub fn remove_touch(&mut self) {
666        let mut inner = self.arc.inner.lock().unwrap();
667        if inner.touch.is_some() {
668            inner.touch = None;
669            #[cfg(feature = "wayland_frontend")]
670            inner.send_all_caps();
671        }
672    }
673
674    /// Gets this seat's name
675    pub fn name(&self) -> &str {
676        &self.arc.name
677    }
678}
679
680pub(super) enum GrabStatus<G: ?Sized> {
681    None,
682    Active(Serial, Box<G>),
683    Borrowed,
684}
685
686// `G` is not `Debug`, so we have to impl Debug manually
687impl<G: ?Sized> fmt::Debug for GrabStatus<G> {
688    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
689        match self {
690            GrabStatus::None => f.debug_tuple("GrabStatus::None").finish(),
691            GrabStatus::Active(serial, _) => f.debug_tuple("GrabStatus::Active").field(&serial).finish(),
692            GrabStatus::Borrowed => f.debug_tuple("GrabStatus::Borrowed").finish(),
693        }
694    }
695}