<NME> mod.rs
<BEF> //! Utilities for input method support
//!
//! This module provides you with utilities to handle input methods,
//! it must be used in conjunction with the text input module to work.
//!
//! ```
//! use smithay::{
//!     delegate_seat, delegate_tablet_manager, delegate_input_method_manager,
//!     delegate_text_input_manager,
//! };
//! use smithay::input::{Seat, SeatState, SeatHandler, keyboard::XkbConfig, pointer::CursorImageStatus};
//! use smithay::wayland::input_method::{
//!     InputMethodManagerState,
//!     InputMethodSeat
//! };
//! use smithay::wayland::text_input::TextInputManagerState;
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
//!
//! # struct State { seat_state: SeatState<Self> };
//!
//! delegate_seat!(State);
//! // Delegate input method handling for State to InputMethodManagerState.
//! delegate_input_method_manager!(State);
//! delegate_text_input_manager!(State);
//!
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
//!
//! let mut seat_state = SeatState::<State>::new();
//!
//! // 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>) { unimplemented!() }
//!     fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
//! }
//!
//! // Add the seat state to your state and create manager globals
//! InputMethodManagerState::new::<State>(&display_handle);
//! // Add text input capabilities, needed for the input method to work
//! TextInputManagerState::new::<State>(&display_handle);
//!
//! // create the 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
//! );
//!
//! seat.add_input_method(XkbConfig::default(), 200, 25);
//! // Add input method capabilities to a seat
//!
//! ```
//! ### Run usage
//!
//! Once the input method and text input cabailities have been added to a seat,
//! use the [`seat.input_method().set_point`] function to set the top left point
//! of a focused surface. This is used to calculate the popup surface location.
//!
//! Then use the [`seat.input_method().coordinates`] and [`seat.input_method().with_surface`]
//! functions to draw the popup surface.

const INPUT_METHOD_VERSION: u32 = 1;

#[derive(Default, Clone)]
struct InputMethod {
    keyboard: Option<Main<ZwpInputMethodKeyboardGrabV2>>,
    instance: Option<Main<ZwpInputMethodV2>>,
    popup_surface: Option<Main<ZwpInputPopupSurfaceV2>>,
    surface: Option<WlSurface>,
    keyboard_state: Option<KeyboardState>,
}

#[derive(Clone)]
struct KeyboardState {
    xkbstate: xkb::State,
    zwp_input_method_v2::ZwpInputMethodV2,
};
    keymap: String,
}

impl InputMethod {
    fn config(&mut self, rate: i32, delay: i32, xkb_config: XkbConfig<'_>) {
        let (keymap, xkbstate) = xkb_handler(xkb_config);
}

impl<D: SeatHandler + 'static> InputMethodSeat for Seat<D> {
    fn add_input_method(&self, xkb_config: XkbConfig<'_>, repeat_delay: i32, repeat_rate: i32) {
        let user_data = self.user_data();
        user_data.insert_if_missing(InputMethodHandle::default);
        let input_method = user_data.get::<InputMethodHandle>().unwrap().clone();
        input_method.configure_keyboard(xkb_config, repeat_delay, repeat_rate);
    }

    fn input_method(&self) -> Option<&InputMethodHandle> {
        let user_data = self.user_data();
        user_data.get::<InputMethodHandle>()
    }
}

/// State of wp misc input method protocol
#[derive(Debug)]
pub struct InputMethodManagerState {
    global: GlobalId,
}

impl InputMethodManagerState {
    /// Initialize a text input manager global.
    pub fn new<D>(display: &DisplayHandle) -> Self
    where
        D: GlobalDispatch<ZwpInputMethodManagerV2, ()>,
        D: Dispatch<ZwpInputMethodManagerV2, ()>,
        D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
        D: SeatHandler,
        D: 'static,
    {
        let global = display.create_global::<D, ZwpInputMethodManagerV2, _>(MANAGER_VERSION, ());

        Self { global }
    }

    /// Get the id of ZwpTextInputManagerV3 global
    pub fn global(&self) -> GlobalId {
        self.global.clone()
    }
}

impl<D> GlobalDispatch<ZwpInputMethodManagerV2, (), D> for InputMethodManagerState
where
    D: GlobalDispatch<ZwpInputMethodManagerV2, ()>,
    D: Dispatch<ZwpInputMethodManagerV2, ()>,
    D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
    D: SeatHandler,
    D: 'static,
{
    fn bind(
        _: &mut D,
        _: &DisplayHandle,
        _: &Client,
        resource: New<ZwpInputMethodManagerV2>,
        _: &(),
        data_init: &mut DataInit<'_, D>,
    ) {
        data_init.init(resource, ());
    }
}

impl<D> Dispatch<ZwpInputMethodManagerV2, (), D> for InputMethodManagerState
where
    D: Dispatch<ZwpInputMethodManagerV2, ()>,
    D: Dispatch<ZwpInputMethodV2, InputMethodUserData<D>>,
    D: SeatHandler,
    D: 'static,
{
    fn request(
        _state: &mut D,
        _client: &Client,
        _: &ZwpInputMethodManagerV2,
        request: zwp_input_method_manager_v2::Request,
        _: &(),
        _dh: &DisplayHandle,
        data_init: &mut DataInit<'_, D>,
    ) {
        match request {
            zwp_input_method_manager_v2::Request::GetInputMethod { seat, input_method } => {
                let seat = Seat::<D>::from_resource(&seat).unwrap();

                let user_data = seat.user_data();
                user_data.insert_if_missing(TextInputHandle::default);
                let handle = user_data.get::<InputMethodHandle>().unwrap();
                let text_input_handle = user_data.get::<TextInputHandle>().unwrap();
                text_input_handle.with_focused_text_input(|ti, surface, _| {
                    ti.enter(surface);
                });
                let keyboard_handle = seat.get_keyboard().unwrap();
    (keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1), state)
}

impl fmt::Debug for InputMethod {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("InputMethod").finish()
    }
}

/// Handle to an input method
#[derive(Default, Debug, Clone)]
pub struct InputMethodHandle {
                    },
                );
                handle.add_instance::<InputMethodHandle>(&instance);
            }
            zwp_input_method_manager_v2::Request::Destroy => {
                // Nothing to do
            }
            _ => unreachable!(),
        }
    }
}

#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_input_method_manager {
    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
        $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_method_manager_v2::ZwpInputMethodManagerV2: ()
        ] => $crate::wayland::input_method::InputMethodManagerState);

        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_method_manager_v2::ZwpInputMethodManagerV2: ()
        ] => $crate::wayland::input_method::InputMethodManagerState);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_method_v2::ZwpInputMethodV2: $crate::wayland::input_method::InputMethodUserData<Self>
        ] => $crate::wayland::input_method::InputMethodManagerState);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_method_keyboard_grab_v2::ZwpInputMethodKeyboardGrabV2: $crate::wayland::input_method::InputMethodKeyboardUserData<Self>
        ] => $crate::wayland::input_method::InputMethodManagerState);
        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols_misc::zwp_input_method_v2::server::zwp_input_popup_surface_v2::ZwpInputPopupSurfaceV2: $crate::wayland::input_method::InputMethodPopupSurfaceUserData
        ] => $crate::wayland::input_method::InputMethodManagerState);
    };
}

<MSG> Moved manual implementation of Debug to keyboardState struct

<DFF> @@ -66,15 +66,6 @@ use super::{seat::XkbConfig, text_input::TextInputHandle, Serial};
 
 const INPUT_METHOD_VERSION: u32 = 1;
 
-#[derive(Default, Clone)]
-struct InputMethod {
-    keyboard: Option<Main<ZwpInputMethodKeyboardGrabV2>>,
-    instance: Option<Main<ZwpInputMethodV2>>,
-    popup_surface: Option<Main<ZwpInputPopupSurfaceV2>>,
-    surface: Option<WlSurface>,
-    keyboard_state: Option<KeyboardState>,
-}
-
 #[derive(Clone)]
 struct KeyboardState {
     xkbstate: xkb::State,
@@ -83,6 +74,25 @@ struct KeyboardState {
     keymap: String,
 }
 
+impl fmt::Debug for KeyboardState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("KeyboardState")
+            .field("rate", &self.rate)
+            .field("delay", &self.delay)
+            .field("keymap", &self.keymap)
+            .finish()
+    }
+}
+
+#[derive(Default, Clone, Debug)]
+struct InputMethod {
+    keyboard: Option<Main<ZwpInputMethodKeyboardGrabV2>>,
+    instance: Option<Main<ZwpInputMethodV2>>,
+    popup_surface: Option<Main<ZwpInputPopupSurfaceV2>>,
+    surface: Option<WlSurface>,
+    keyboard_state: Option<KeyboardState>,
+}
+
 impl InputMethod {
     fn config(&mut self, rate: i32, delay: i32, xkb_config: XkbConfig<'_>) {
         let (keymap, xkbstate) = xkb_handler(xkb_config);
@@ -180,12 +190,6 @@ fn xkb_handler(xkb_config: XkbConfig<'_>) -> (String, xkb::State) {
     (keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1), state)
 }
 
-impl fmt::Debug for InputMethod {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("InputMethod").finish()
-    }
-}
-
 /// Handle to an input method
 #[derive(Default, Debug, Clone)]
 pub struct InputMethodHandle {

Moved manual implementation of Debug to keyboardState struct