<NME> mod.rs
<BEF> //! Utilities for text input support
//!
//! This module provides you with utilities to handle text input surfaces,
//! it is usually used in conjunction with the input method module.
//!
//! ```
//! use smithay::{
//!     delegate_seat, delegate_tablet_manager, delegate_text_input_manager,
//! };
//! use smithay::input::{Seat, SeatState, SeatHandler, keyboard::XkbConfig, pointer::CursorImageStatus};
//! 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 text input handling for State to TextInputManagerState.
//! delegate_text_input_manager!(State);
//!
//! # let mut display = Display::<State>::new().unwrap();
//! # let display_handle = display.handle();
//!
//! let 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 global
//! TextInputManagerState::new::<State>(&display_handle);
//!
//! ```
//!

use wayland_protocols::wp::text_input::zv3::server::{
    zwp_text_input_manager_v3::{self, ZwpTextInputManagerV3},
};
use wayland_server::{protocol::wl_surface::WlSurface, Display, Filter, Global, Main};

use crate::wayland::seat::Seat;

use super::input_method::InputMethodHandle;

pub use text_input_handle::TextInputUserData;

use super::input_method::InputMethodHandle;

const MANAGER_VERSION: u32 = 1;
    serial: u32,
    x: i32,
    y: i32,
}

/// Contains all the text input instances
    /// Initialize a text input manager global.
    pub fn new<D>(display: &DisplayHandle) -> Self
    where
        D: GlobalDispatch<ZwpTextInputManagerV3, ()>,
        D: Dispatch<ZwpTextInputManagerV3, ()>,
        D: Dispatch<ZwpTextInputV3, TextInputUserData>,
        D: 'static,
    {
        let global = display.create_global::<D, ZwpTextInputManagerV3, _>(MANAGER_VERSION, ());

        Self { global }
    }

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

impl<D> GlobalDispatch<ZwpTextInputManagerV3, (), D> for TextInputManagerState
where
    D: GlobalDispatch<ZwpTextInputManagerV3, ()>,
    D: Dispatch<ZwpTextInputManagerV3, ()>,
    D: Dispatch<ZwpTextInputV3, TextInputUserData>,
    D: 'static,
{
    fn bind(
        _: &mut D,
        _: &DisplayHandle,
        _: &Client,
        resource: New<ZwpTextInputManagerV3>,
        _: &(),
        data_init: &mut DataInit<'_, D>,
    ) {
        data_init.init(resource, ());
    }
}

impl<D> Dispatch<ZwpTextInputManagerV3, (), D> for TextInputManagerState
where
        }
    }

    fn increment(&mut self){
        if let Some(old_focus) = &self.old_focus {
            if let Some(old_instance) = self
    ) {
        match request {
            zwp_text_input_manager_v3::Request::GetTextInput { id, seat } => {
                let seat = Seat::<D>::from_resource(&seat).unwrap();

                let user_data = seat.user_data();
                user_data.insert_if_missing(TextInputHandle::default);
                user_data.insert_if_missing(InputMethodHandle::default);
                let handle = user_data.get::<TextInputHandle>().unwrap();
                let input_method_handle = user_data.get::<InputMethodHandle>().unwrap();
                let instance = data_init.init(
                    id,
                    TextInputUserData {
                        handle: handle.clone(),
                        input_method_handle: input_method_handle.clone(),
                    },
                );

                handle.add_instance::<D>(&instance);
            }
            zwp_text_input_manager_v3::Request::Destroy => {
                // Nothing to do
            }
            _ => unreachable!(),
        }
    }
}

#[allow(missing_docs)] // TODO
#[macro_export]
macro_rules! delegate_text_input_manager {
    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
        $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols::wp::text_input::zv3::server::zwp_text_input_manager_v3::ZwpTextInputManagerV3: ()
        ] => $crate::wayland::text_input::TextInputManagerState);

        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols::wp::text_input::zv3::server::zwp_text_input_manager_v3::ZwpTextInputManagerV3: ()
        ] => $crate::wayland::text_input::TextInputManagerState);

        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
            $crate::reexports::wayland_protocols::wp::text_input::zv3::server::zwp_text_input_v3::ZwpTextInputV3: $crate::wayland::text_input::TextInputUserData
        ] => $crate::wayland::text_input::TextInputManagerState);
    };
}
        inner.instances.push(instance);
    }

    fn add_coordinates(&self, x: i32, y:i32) {
        let mut inner = self.inner.borrow_mut();
        let focused_instance = inner.focused_text_input();
        if let Some(instance) = focused_instance{
            instance.x = x;
            instance.y = y;
        }
    }

    /// TODO:Document something
    pub fn coordinates(&self) ->(i32, i32) {
        let mut inner = self.inner.borrow_mut();
        let focused_instance = inner.focused_text_input();
        if let Some(instance) = focused_instance {
            (instance.x, instance.y)
        } else {
            (0, 0)
        }
    }

    /// Activates a text input when a surface is focused and deactivates it when
    /// the current surface goes out of focus.
    pub fn set_focus(&mut self, focus: Option<&WlSurface>) {
        let mut inner = self.inner.borrow_mut();
        inner.set_focus(focus);
    }

    /// used to access the Main handle from an input method
                            handle: id.clone(),
                            serial: 0,
                            x: 0,
                            y: 0
                        });
                        let input_method = user_data.get::<InputMethodHandle>().unwrap().clone();
                        let text_input_handle = ti.clone();
                        id.quick_assign(move |_text_input, req, _| match req {
                            zwp_text_input_v3::Request::Enable => {
                                println!("Did we get this?");
                                if let Some(input_method) = input_method.handle() {
                                    input_method.activate();
                                }
                                }
                            }
                            zwp_text_input_v3::Request::SetCursorRectangle { x, y, width, height } => {
                                println!("CursorRectangle: {x}, {y}");
                                ti.add_coordinates(x,y);
                                if let Some(popup_surface) = input_method.popup_surface_handle() {
                                    popup_surface.text_input_rectangle(x, y, width, height);
                                }

<MSG> support for correct placement of popup surface

<DFF> @@ -44,7 +44,7 @@ use wayland_protocols::unstable::text_input::v3::server::{
 };
 use wayland_server::{protocol::wl_surface::WlSurface, Display, Filter, Global, Main};
 
-use crate::wayland::seat::Seat;
+use crate::{wayland::seat::Seat, utils::{Logical, Point}};
 
 use super::input_method::InputMethodHandle;
 
@@ -56,6 +56,10 @@ struct Instance {
     serial: u32,
     x: i32,
     y: i32,
+    width: i32,
+    height: i32,
+    l_x: i32,
+    l_y: i32
 }
 
 /// Contains all the text input instances
@@ -102,6 +106,13 @@ impl TextInput {
         }
     }
 
+    fn set_point(&mut self, point: &Point<i32, Logical>){
+        if let Some(instance) = self.focused_text_input(){
+            instance.l_x = point.x;
+            instance.l_y = point.y;
+        }
+    }
+
     fn increment(&mut self){
         if let Some(old_focus) = &self.old_focus {
             if let Some(old_instance) = self
@@ -154,31 +165,36 @@ impl TextInputHandle {
         inner.instances.push(instance);
     }
 
-    fn add_coordinates(&self, x: i32, y:i32) {
+    fn add_coordinates(&self, x: i32, y:i32, width: i32, height: i32) {
         let mut inner = self.inner.borrow_mut();
         let focused_instance = inner.focused_text_input();
         if let Some(instance) = focused_instance{
             instance.x = x;
             instance.y = y;
+            instance.width = width;
+            instance.height = height;
         }
     }
 
     /// TODO:Document something
-    pub fn coordinates(&self) ->(i32, i32) {
+    pub fn coordinates(&self) ->(i32, i32, i32, i32) {
         let mut inner = self.inner.borrow_mut();
         let focused_instance = inner.focused_text_input();
         if let Some(instance) = focused_instance {
-            (instance.x, instance.y)
+            (instance.x+instance.l_x, instance.y+instance.l_y, instance.width, instance.height)
         } else {
-            (0, 0)
+            (0, 0, 0, 0)
         }
     }
 
     /// Activates a text input when a surface is focused and deactivates it when
     /// the current surface goes out of focus.
-    pub fn set_focus(&mut self, focus: Option<&WlSurface>) {
+    pub fn set_focus(&mut self, focus: Option<&WlSurface>, location: Option<&Point<i32, Logical>>) {
         let mut inner = self.inner.borrow_mut();
         inner.set_focus(focus);
+        if let Some(point) = location{
+            inner.set_point(point);
+        }
     }
 
     /// used to access the Main handle from an input method
@@ -230,13 +246,16 @@ pub fn init_text_input_manager_global(display: &mut Display) -> Global<ZwpTextIn
                             handle: id.clone(),
                             serial: 0,
                             x: 0,
-                            y: 0
+                            y: 0,
+                            width: 0,
+                            height: 0,
+                            l_x: 0,
+                            l_y: 0
                         });
                         let input_method = user_data.get::<InputMethodHandle>().unwrap().clone();
                         let text_input_handle = ti.clone();
                         id.quick_assign(move |_text_input, req, _| match req {
                             zwp_text_input_v3::Request::Enable => {
-                                println!("Did we get this?");
                                 if let Some(input_method) = input_method.handle() {
                                     input_method.activate();
                                 }
@@ -266,8 +285,8 @@ pub fn init_text_input_manager_global(display: &mut Display) -> Global<ZwpTextIn
                                 }
                             }
                             zwp_text_input_v3::Request::SetCursorRectangle { x, y, width, height } => {
-                                println!("CursorRectangle: {x}, {y}");
-                                ti.add_coordinates(x,y);
+                                println!("CursorRectangle: {x}, {y}, {width}, {height}");
+                                ti.add_coordinates(x, y, width, height);
                                 if let Some(popup_surface) = input_method.popup_surface_handle() {
                                     popup_surface.text_input_rectangle(x, y, width, height);
                                 }

support for correct placement of popup surface