<NME> mod.rs
<BEF> //! Seat global utilities
//!
//! This module provides you with utilities for handling the seat globals
//! and the associated input Wayland objects.
//!
//! ## How to use it
//!
//! ### Initialization
//!
//! ```
//! use smithay::delegate_seat;
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
//!
//! # struct State { seat_state: SeatState<Self> };
//! # let mut display = Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
//!
//! let mut seat_state = SeatState::<State>::new();
//! // add the seat state to your state
//! // ...
//!
//! // create the wl_seat
//! let seat = seat_state.new_wl_seat(
//!     &display_handle,          // the display
//!     "seat-0",                 // the name of the seat, will be advertized to clients
//!     None                      // insert a logger here
//! );
//!
//! // implement the required traits
//! impl SeatHandler for State {
//!     type KeyboardFocus = WlSurface;
//!     type PointerFocus = WlSurface;
//!     fn seat_state(&mut self) -> &mut SeatState<Self> {
//!         &mut self.seat_state
//!     }
//!     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) {
mod pointer;
// mod touch;

use std::sync::{Arc, Mutex};

use crate::utils::user_data::UserDataMap;

//!
//! Once the seat is initialized, you can add capabilities to it.
//!
//! Currently, only pointer and keyboard capabilities are supported by smithay.
//!
//! You can add these capabilities via methods of the [`Seat`] struct:
//! [`Seat::add_keyboard`] and [`Seat::add_pointer`].
//! These methods return handles that can be cloned and sent across thread, so you can keep one around
//! in your event-handling code to forward inputs to your clients.
//!
//! This module further defines the `"cursor_image"` role, that is assigned to surfaces used by clients
//! to change the cursor icon.

pub(crate) mod keyboard;
mod pointer;
mod touch;

use std::{fmt, sync::Arc};

use crate::input::{Inner, Seat, SeatHandler, SeatRc, SeatState};

pub use self::{
    keyboard::KeyboardUserData,
    pointer::{PointerUserData, CURSOR_IMAGE_ROLE},
    touch::{TouchHandle, TouchUserData},
};

use wayland_server::{
    backend::{ClientId, GlobalId, ObjectId},
    protocol::{
    keyboard: Option<KeyboardHandle>,
    // touch: Option<TouchHandle>,
    known_seats: Vec<wl_seat::WlSeat>,
}

#[derive(Debug)]
struct SeatRc<T> {
    name: String,
    inner: Mutex<Inner<T>>,
    seat: GlobalId,
    user_data_map: UserDataMap,

    log: ::slog::Logger,
    /// for any provided `ObjectId`
    fn wl_surface(&self) -> Option<wl_surface::WlSurface>;
    /// Returns true, if the underlying wayland object originates from
    /// the same client connection as the provided `ObjectId`.
    ///
    /// *Must* return false, if there is not underlying wayland object.
    fn same_client_as(&self, object_id: &ObjectId) -> bool {
        self.wl_surface()
            .map(|s| s.id().same_client_as(object_id))
            .unwrap_or(false)
    }
}

impl WaylandFocus for wl_surface::WlSurface {
    fn wl_surface(&self) -> Option<wl_surface::WlSurface> {
        Some(self.clone())
    }
}

impl<D: SeatHandler> Inner<D> {
    fn compute_caps(&self) -> wl_seat::Capability {
        let mut caps = wl_seat::Capability::empty();
        if self.pointer.is_some() {
            caps |= wl_seat::Capability::Pointer;
        }
        if self.keyboard.is_some() {
            caps |= wl_seat::Capability::Keyboard;
        }
    fn seat_state(&mut self) -> &mut SeatState<T>;
}

/// A Seat handle
///
/// This struct gives you access to the control of the
/// capabilities of the associated seat.
///

/// Global data of WlSeat
pub struct SeatGlobalData<D: SeatHandler> {
///
/// See module-level documentation for details of use.
#[derive(Debug)]
pub struct SeatState<T> {
    arc: Arc<SeatRc<T>>,
}

impl<T> Clone for SeatState<T> {
    fn clone(&self) -> Self {
        Self {
            arc: self.arc.clone(),
}
    }
}

impl<T: 'static> SeatState<T> {
    /// Create a new seat global
    ///
    /// A new seat global is created with given name and inserted
    /// You are provided with the state token to retrieve it (allowing
    /// you to add or remove capabilities from it), and the global handle,
    /// You are provided with the state token to retrieve it (allowing
    /// you to add or remove capabilities from it), and the global handle,
    /// in case you want to remove it.
    pub fn new<L, D>(display: &mut Display<D>, name: String, logger: L) -> Self
    where
        L: Into<Option<::slog::Logger>>,
        D: GlobalDispatch<WlSeat, GlobalData = ()> + 'static,
    {
        let log = crate::slog_or_fallback(logger);
        let log = log.new(slog::o!("smithay_module" => "seat_handler", "seat_name" => name.clone()));

        let seat = display.create_global(5, ());

        Self {
            arc: Arc::new(SeatRc {
                name,
                inner: Mutex::new(Inner {
                    pointer: None,
                    keyboard: None,
                    known_seats: Default::default(),
                }),
                seat,
                user_data_map: UserDataMap::new(),
                log,
            }),
        }
    }

    /// Get id of WlSeat global
    pub fn seat_global(&self) -> GlobalId {
        self.arc.seat.clone()
    }

    /// Attempt to retrieve a [`Seat`] from an existing resource
    pub fn from_resource(seat: &WlSeat) -> Option<Self> {
        seat.data::<SeatUserData<T>>()
            .map(|d| d.seat.clone())
            .map(|arc| Self { arc })
    }

    pub fn global(&self) -> Option<GlobalId> {
        self.arc.inner.lock().unwrap().global.as_ref().cloned()
        &self.arc.user_data_map
    }

    /// Adds the pointer capability to this seat
    ///
    /// You are provided a [`PointerHandle`], which allows you to send input events
    /// # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
    /// # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
    /// #
    /// # struct State;
    /// # impl SeatHandler for State {
    /// #     type KeyboardFocus = WlSurface;
    /// #     type PointerFocus = WlSurface;
    /// #     fn seat_state(&mut self) -> &mut SeatState<Self> { unimplemented!() }
    /// #     fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
    /// #     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
    /// # }
    /// # let mut seat: Seat<State> = unimplemented!();
    /// let touch_handle = seat.add_touch();
    /// ```
    pub fn add_touch(&mut self) -> TouchHandle {
        let mut inner = self.arc.inner.lock().unwrap();
        let touch = TouchHandle::new();
        if inner.touch.is_some() {
            // If there's already a tocuh device, remove it notify the clients about the change.
            inner.touch = None;
            inner.send_all_caps();
        }
        inner.touch = Some(touch.clone());
        inner.send_all_caps();
        touch
    }

    /// Access the touch device of this seat, if any.
    pub fn get_touch(&self) -> Option<TouchHandle> {
        self.arc.inner.lock().unwrap().touch.clone()
    }

    /// Remove the touch capability from this seat
    ///
    /// Clients will be appropriately notified.
    pub fn remove_touch(&mut self) {
        let mut inner = self.arc.inner.lock().unwrap();
        if inner.touch.is_some() {
            inner.touch = None;
            inner.send_all_caps();
        }
    }
}

/// User data for seat
pub struct SeatUserData<D: SeatHandler> {
    arc: Arc<SeatRc<D>>,
}

impl<D: SeatHandler> fmt::Debug for SeatUserData<D>
where
    <D as SeatHandler>::KeyboardFocus: fmt::Debug,
    <D as SeatHandler>::PointerFocus: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            inner.send_all_caps(dh);
        }
    }

    /// Adds the keyboard capability to this seat
    ///
    /// You are provided a [`KeyboardHandle`], which allows you to send input events
        ] => $crate::input::SeatState<$ty>);

        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_server::protocol::wl_seat::WlSeat: $crate::wayland::seat::SeatUserData<$ty>
        ] => $crate::input::SeatState<$ty>);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_server::protocol::wl_pointer::WlPointer: $crate::wayland::seat::PointerUserData<$ty>
        ] => $crate::input::SeatState<$ty>);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_server::protocol::wl_keyboard::WlKeyboard: $crate::wayland::seat::KeyboardUserData<$ty>
        ] => $crate::input::SeatState<$ty>);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?$ty: [
            $crate::reexports::wayland_server::protocol::wl_touch::WlTouch: $crate::wayland::seat::TouchUserData
        ] => $crate::input::SeatState<$ty>);
    };
}

impl<D> Dispatch<WlSeat, SeatUserData<D>, D> for SeatState<D>
where
    D: Dispatch<WlSeat, SeatUserData<D>>,
    D: Dispatch<WlKeyboard, KeyboardUserData<D>>,
    D: Dispatch<WlPointer, PointerUserData<D>>,
    D: Dispatch<WlTouch, TouchUserData>,
    D: SeatHandler,
    <D as SeatHandler>::KeyboardFocus: WaylandFocus,
    D: 'static,
{
    fn request(
        _state: &mut D,
        _client: &wayland_server::Client,
        _resource: &WlSeat,
        request: wl_seat::Request,
        data: &SeatUserData<D>,
        _dh: &DisplayHandle,
        data_init: &mut wayland_server::DataInit<'_, D>,
    ) {
        match request {
            wl_seat::Request::GetPointer { id } => {
                let inner = data.arc.inner.lock().unwrap();

                let pointer = data_init.init(
                    id,
                    PointerUserData {
                        handle: inner.pointer.clone(),
                    },
                );

                if let Some(ref ptr_handle) = inner.pointer {
                    ptr_handle.new_pointer(pointer);
                } else {
                    // we should send a protocol error... but the protocol does not allow
                    // us, so this pointer will just remain inactive ¯\_(ツ)_/¯
                }
            }
            wl_seat::Request::GetKeyboard { id } => {
                let inner = data.arc.inner.lock().unwrap();

                let keyboard = data_init.init(
                    id,
                    KeyboardUserData {
                        handle: inner.keyboard.clone(),
                    },
                );

                if let Some(ref h) = inner.keyboard {
                    h.new_kbd(keyboard);
                } else {
                    // same as pointer, should error but cannot
                }
            }
            wl_seat::Request::GetTouch { id } => {
                let inner = data.arc.inner.lock().unwrap();

                let touch = data_init.init(
                    id,
            inner.send_all_caps(dh);
        }
    }

    // /// Adds the touch capability to this seat
    // ///
    // /// You are provided a [`TouchHandle`], which allows you to send input events
            }
            wl_seat::Request::Release => {
                // Our destructors already handle it
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(_state: &mut D, _: ClientId, object_id: ObjectId, data: &SeatUserData<D>) {
        data.arc
            .inner
            .lock()
            .unwrap()
            .known_seats
            .retain(|s| s.id() != object_id);
    }
}

impl<D> GlobalDispatch<WlSeat, SeatGlobalData<D>, D> for SeatState<D>
where
    D: GlobalDispatch<WlSeat, SeatGlobalData<D>>,
    D: Dispatch<WlSeat, SeatUserData<D>>,
    D: Dispatch<WlKeyboard, KeyboardUserData<D>>,
    D: Dispatch<WlPointer, PointerUserData<D>>,
    D: Dispatch<WlTouch, TouchUserData>,
    D: SeatHandler,
    D: 'static,
{
    fn bind(
        _state: &mut D,
        _dh: &DisplayHandle,
        _client: &wayland_server::Client,
        resource: New<WlSeat>,
        global_data: &SeatGlobalData<D>,
        data_init: &mut DataInit<'_, D>,
    ) {
        let data = SeatUserData {
            arc: global_data.arc.clone(),
        };

        let resource = data_init.init(resource, data);

        if resource.version() >= 2 {
            resource.name(global_data.arc.name.clone());
        }

    //         inner.send_all_caps();
    //     }
    // }

    /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`]
    pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool {
        let inner = self.arc.inner.lock().unwrap();
        inner.known_seats.iter().any(|s| s == seat)
    }
}

impl<T> ::std::cmp::PartialEq for SeatState<T> {
    fn eq(&self, other: &Self) -> bool {
        Arc::ptr_eq(&self.arc, &other.arc)
    }
}

/// User data for seat
#[derive(Debug)]
pub struct SeatUserData<T> {
    seat: Arc<SeatRc<T>>,
}

#[allow(missing_docs)] // TODO
    T: 'static,
{
    fn request(
        state: &mut D,
        _client: &wayland_server::Client,
        _resource: &WlSeat,
        request: wl_seat::Request,
        _data: &Self::UserData,
        dh: &mut DisplayHandle<'_>,
        data_init: &mut wayland_server::DataInit<'_, D>,
    ) {
        match request {
            wl_seat::Request::GetPointer { id } => {
                let inner = state.seat_state().arc.inner.lock().unwrap();

                let pointer = data_init.init(
                    id,
                }
            }
            wl_seat::Request::GetKeyboard { id } => {
                let inner = state.seat_state().arc.inner.lock().unwrap();

                let keyboard = data_init.init(
                    id,
    }

    fn destroyed(_state: &mut D, _: ClientId, object_id: ObjectId, data: &Self::UserData) {
        data.seat
            .inner
            .lock()
            .unwrap()
}

impl<T: 'static> DelegateGlobalDispatchBase<WlSeat> for SeatState<T> {
    type GlobalData = ();
}

impl<T, D> DelegateGlobalDispatch<WlSeat, D> for SeatState<T>
where
    D: GlobalDispatch<WlSeat, GlobalData = ()>,
    D: Dispatch<WlSeat, UserData = SeatUserData<T>>,
    D: Dispatch<WlKeyboard, UserData = KeyboardUserData>,
    D: Dispatch<WlPointer, UserData = PointerUserData<T>>,
    T: 'static,
{
    fn bind(
        state: &mut D,
        handle: &mut wayland_server::DisplayHandle<'_>,
        _client: &wayland_server::Client,
        resource: New<WlSeat>,
        _global_data: &Self::GlobalData,
        data_init: &mut DataInit<'_, D>,
    ) {
        let state = state.seat_state();

        let data = SeatUserData {
            seat: state.arc.clone(),
        };

        let resource = data_init.init(resource, data);

        if resource.version() >= 2 {
            resource.name(handle, state.arc.name.clone());
        }

        let mut inner = state.arc.inner.lock().unwrap();
        resource.capabilities(handle, inner.compute_caps());

        inner.known_seats.push(resource.clone());

<MSG> Add Multiseat support


<DFF> @@ -38,7 +38,10 @@ mod keyboard;
 mod pointer;
 // mod touch;
 
-use std::sync::{Arc, Mutex};
+use std::{
+    marker::PhantomData,
+    sync::{Arc, Mutex},
+};
 
 use crate::utils::user_data::UserDataMap;
 
@@ -75,13 +78,14 @@ struct Inner<T> {
     keyboard: Option<KeyboardHandle>,
     // touch: Option<TouchHandle>,
     known_seats: Vec<wl_seat::WlSeat>,
+
+    global_id: Option<GlobalId>,
 }
 
 #[derive(Debug)]
 struct SeatRc<T> {
     name: String,
     inner: Mutex<Inner<T>>,
-    seat: GlobalId,
     user_data_map: UserDataMap,
 
     log: ::slog::Logger,
@@ -116,8 +120,13 @@ pub trait SeatHandler<T> {
     fn seat_state(&mut self) -> &mut SeatState<T>;
 }
 
+/// Global data of WlSeat
+#[derive(Debug)]
+pub struct SeatGlobalData<T> {
+    arc: Arc<SeatRc<T>>,
+}
+
 /// A Seat handle
-///
 /// This struct gives you access to the control of the
 /// capabilities of the associated seat.
 ///
@@ -127,11 +136,11 @@ pub trait SeatHandler<T> {
 ///
 /// See module-level documentation for details of use.
 #[derive(Debug)]
-pub struct SeatState<T> {
+pub struct Seat<T> {
     arc: Arc<SeatRc<T>>,
 }
 
-impl<T> Clone for SeatState<T> {
+impl<T> Clone for Seat<T> {
     fn clone(&self) -> Self {
         Self {
             arc: self.arc.clone(),
@@ -139,7 +148,7 @@ impl<T> Clone for SeatState<T> {
     }
 }
 
-impl<T: 'static> SeatState<T> {
+impl<T: 'static> Seat<T> {
     /// Create a new seat global
     ///
     /// A new seat global is created with given name and inserted
@@ -148,40 +157,46 @@ impl<T: 'static> SeatState<T> {
     /// You are provided with the state token to retrieve it (allowing
     /// you to add or remove capabilities from it), and the global handle,
     /// in case you want to remove it.
-    pub fn new<L, D>(display: &mut Display<D>, name: String, logger: L) -> Self
+    pub fn new<D, N, L>(display: &mut Display<D>, name: N, logger: L) -> Self
     where
+        D: GlobalDispatch<WlSeat, GlobalData = SeatGlobalData<T>> + 'static,
+        N: Into<String>,
         L: Into<Option<::slog::Logger>>,
-        D: GlobalDispatch<WlSeat, GlobalData = ()> + 'static,
     {
+        let name = name.into();
+
         let log = crate::slog_or_fallback(logger);
         let log = log.new(slog::o!("smithay_module" => "seat_handler", "seat_name" => name.clone()));
 
-        let seat = display.create_global(5, ());
+        let arc = Arc::new(SeatRc {
+            name,
+            inner: Mutex::new(Inner {
+                pointer: None,
+                keyboard: None,
+                known_seats: Default::default(),
 
-        Self {
-            arc: Arc::new(SeatRc {
-                name,
-                inner: Mutex::new(Inner {
-                    pointer: None,
-                    keyboard: None,
-                    known_seats: Default::default(),
-                }),
-                seat,
-                user_data_map: UserDataMap::new(),
-                log,
+                global_id: None,
             }),
-        }
+            user_data_map: UserDataMap::new(),
+            log,
+        });
+
+        let global_id = display.create_global(5, SeatGlobalData { arc: arc.clone() });
+        arc.inner.lock().unwrap().global_id = Some(global_id);
+
+        Self { arc }
     }
 
-    /// Get id of WlSeat global
-    pub fn seat_global(&self) -> GlobalId {
-        self.arc.seat.clone()
+    /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`]
+    pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool {
+        let inner = self.arc.inner.lock().unwrap();
+        inner.known_seats.iter().any(|s| s == seat)
     }
 
     /// Attempt to retrieve a [`Seat`] from an existing resource
     pub fn from_resource(seat: &WlSeat) -> Option<Self> {
         seat.data::<SeatUserData<T>>()
-            .map(|d| d.seat.clone())
+            .map(|d| d.arc.clone())
             .map(|arc| Self { arc })
     }
 
@@ -190,6 +205,14 @@ impl<T: 'static> SeatState<T> {
         &self.arc.user_data_map
     }
 
+    /// Get the id of WlSeta global
+    pub fn global_id(&self) -> GlobalId {
+        self.arc.inner.lock().unwrap().global_id.as_ref().unwrap().clone()
+    }
+}
+
+// Pointer
+impl<T> Seat<T> {
     /// Adds the pointer capability to this seat
     ///
     /// You are provided a [`PointerHandle`], which allows you to send input events
@@ -251,7 +274,10 @@ impl<T: 'static> SeatState<T> {
             inner.send_all_caps(dh);
         }
     }
+}
 
+// Keyboard
+impl<T: 'static> Seat<T> {
     /// Adds the keyboard capability to this seat
     ///
     /// You are provided a [`KeyboardHandle`], which allows you to send input events
@@ -333,7 +359,10 @@ impl<T: 'static> SeatState<T> {
             inner.send_all_caps(dh);
         }
     }
+}
 
+// Touch
+impl<T> Seat<T> {
     // /// Adds the touch capability to this seat
     // ///
     // /// You are provided a [`TouchHandle`], which allows you to send input events
@@ -386,24 +415,52 @@ impl<T: 'static> SeatState<T> {
     //         inner.send_all_caps();
     //     }
     // }
-
-    /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`]
-    pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool {
-        let inner = self.arc.inner.lock().unwrap();
-        inner.known_seats.iter().any(|s| s == seat)
-    }
 }
 
-impl<T> ::std::cmp::PartialEq for SeatState<T> {
+impl<T> ::std::cmp::PartialEq for Seat<T> {
     fn eq(&self, other: &Self) -> bool {
         Arc::ptr_eq(&self.arc, &other.arc)
     }
 }
 
+/// A Seat handle
+/// This struct gives you access to the control of the
+/// capabilities of the associated seat.
+///
+/// It is directly inserted in the wayland display by its [`new`](Seat::new) method.
+///
+/// This is an handle to the inner logic, it can be cloned.
+///
+/// See module-level documentation for details of use.
+#[derive(Debug)]
+pub struct SeatState<T> {
+    pd: PhantomData<T>,
+}
+
+impl<T> Clone for SeatState<T> {
+    fn clone(&self) -> Self {
+        Self { pd: self.pd }
+    }
+}
+
+impl<T: 'static> SeatState<T> {
+    /// Create a new seat global
+    ///
+    /// A new seat global is created with given name and inserted
+    /// into this wayland display.
+    ///
+    /// You are provided with the state token to retrieve it (allowing
+    /// you to add or remove capabilities from it), and the global handle,
+    /// in case you want to remove it.
+    pub fn new() -> Self {
+        Self { pd: PhantomData }
+    }
+}
+
 /// User data for seat
 #[derive(Debug)]
 pub struct SeatUserData<T> {
-    seat: Arc<SeatRc<T>>,
+    arc: Arc<SeatRc<T>>,
 }
 
 #[allow(missing_docs)] // TODO
@@ -438,17 +495,17 @@ where
     T: 'static,
 {
     fn request(
-        state: &mut D,
+        _state: &mut D,
         _client: &wayland_server::Client,
         _resource: &WlSeat,
         request: wl_seat::Request,
-        _data: &Self::UserData,
+        data: &Self::UserData,
         dh: &mut DisplayHandle<'_>,
         data_init: &mut wayland_server::DataInit<'_, D>,
     ) {
         match request {
             wl_seat::Request::GetPointer { id } => {
-                let inner = state.seat_state().arc.inner.lock().unwrap();
+                let inner = data.arc.inner.lock().unwrap();
 
                 let pointer = data_init.init(
                     id,
@@ -465,7 +522,7 @@ where
                 }
             }
             wl_seat::Request::GetKeyboard { id } => {
-                let inner = state.seat_state().arc.inner.lock().unwrap();
+                let inner = data.arc.inner.lock().unwrap();
 
                 let keyboard = data_init.init(
                     id,
@@ -497,7 +554,7 @@ where
     }
 
     fn destroyed(_state: &mut D, _: ClientId, object_id: ObjectId, data: &Self::UserData) {
-        data.seat
+        data.arc
             .inner
             .lock()
             .unwrap()
@@ -507,12 +564,12 @@ where
 }
 
 impl<T: 'static> DelegateGlobalDispatchBase<WlSeat> for SeatState<T> {
-    type GlobalData = ();
+    type GlobalData = SeatGlobalData<T>;
 }
 
 impl<T, D> DelegateGlobalDispatch<WlSeat, D> for SeatState<T>
 where
-    D: GlobalDispatch<WlSeat, GlobalData = ()>,
+    D: GlobalDispatch<WlSeat, GlobalData = <Self as DelegateGlobalDispatchBase<WlSeat>>::GlobalData>,
     D: Dispatch<WlSeat, UserData = SeatUserData<T>>,
     D: Dispatch<WlKeyboard, UserData = KeyboardUserData>,
     D: Dispatch<WlPointer, UserData = PointerUserData<T>>,
@@ -521,26 +578,24 @@ where
     T: 'static,
 {
     fn bind(
-        state: &mut D,
+        _state: &mut D,
         handle: &mut wayland_server::DisplayHandle<'_>,
         _client: &wayland_server::Client,
         resource: New<WlSeat>,
-        _global_data: &Self::GlobalData,
+        global_data: &Self::GlobalData,
         data_init: &mut DataInit<'_, D>,
     ) {
-        let state = state.seat_state();
-
         let data = SeatUserData {
-            seat: state.arc.clone(),
+            arc: global_data.arc.clone(),
         };
 
         let resource = data_init.init(resource, data);
 
         if resource.version() >= 2 {
-            resource.name(handle, state.arc.name.clone());
+            resource.name(handle, global_data.arc.name.clone());
         }
 
-        let mut inner = state.arc.inner.lock().unwrap();
+        let mut inner = global_data.arc.inner.lock().unwrap();
         resource.capabilities(handle, inner.compute_caps());
 
         inner.known_seats.push(resource.clone());

Add Multiseat support