<NME> keyboard.rs
<BEF> use slog::{error, trace, warn};
use std::fmt;
use wayland_server::{
    backend::{ClientId, ObjectId},
    protocol::{
        wl_keyboard::{self, KeyState as WlKeyState, WlKeyboard},
        wl_surface::WlSurface,
    },
    Dispatch, DisplayHandle, Resource,
};

use super::WaylandFocus;
use crate::{
    backend::input::KeyState,
    input::{
        keyboard::{KeyboardHandle, KeyboardTarget, KeysymHandle, ModifiersState},
        Seat, SeatHandler, SeatState,
    },
    utils::Serial,
};

impl<D: SeatHandler + 'static> KeyboardHandle<D>
where
    D: SeatHandler + 'static,
    <D as SeatHandler>::KeyboardFocus: WaylandFocus,
{
    /// Check if client of given resource currently has keyboard focus
    pub fn client_of_object_has_focus(&self, id: &ObjectId) -> bool {
        self.arc
            .internal
            .lock()
            .unwrap()
            .focus
            .as_ref()
            .map(|f| f.0.same_client_as(id))
            .unwrap_or(false)
    }

    /// Register a new keyboard to this handler
    ///
    /// The keymap will automatically be sent to it
    ///
    /// This should be done first, before anything else is done with this keyboard.
    pub(crate) fn new_kbd(&self, kbd: WlKeyboard) {
        trace!(self.arc.logger, "Sending keymap to client");

        // prepare a tempfile with the keymap, to send it to the client
        let keymap_file = self.arc.keymap.lock().unwrap();
        let ret = keymap_file.send(&kbd);

        if let Err(e) = ret {
            warn!(self.arc.logger,
                "Failed write keymap to client in a tempfile";
                "err" => format!("{:?}", e)
            );
            return;
        };

        let guard = self.arc.internal.lock().unwrap();
        if kbd.version() >= 4 {
            kbd.repeat_info(guard.repeat_rate, guard.repeat_delay);
        }
        if let Some((focused, serial)) = guard.focus.as_ref() {
            if focused.same_client_as(&kbd.id()) {
                let serialized = guard.mods_state.serialized;
                let keys = serialize_pressed_keys(guard.pressed_keys.iter().cloned().collect());
                kbd.enter((*serial).into(), &focused.wl_surface().unwrap(), keys);
                // Modifiers must be send after enter event.
                kbd.modifiers(
                    (*serial).into(),
                    serialized.depressed,
                    serialized.latched,
                    serialized.locked,
                    serialized.layout_locked,
                );
            }
        }
        self.arc.known_kbds.lock().unwrap().push(kbd);
    }
}

/// User data for keyboard
pub struct KeyboardUserData<D: SeatHandler> {
    pub(crate) handle: Option<KeyboardHandle<D>>,
}

impl<D: SeatHandler> fmt::Debug for KeyboardUserData<D>
where
    <D as SeatHandler>::KeyboardFocus: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("KeyboardUserData")
            .field("handle", &self.handle)

struct KbdInternal {
    known_kbds: Vec<WlKeyboard>,
    focus: Option<WlSurface>,
    pending_focus: Option<WlSurface>,
    pressed_keys: Vec<u32>,
    mods_state: ModifiersState,
    D: SeatHandler,
{
    fn request(
        _state: &mut D,
        _client: &wayland_server::Client,
        _resource: &WlKeyboard,
        _request: wl_keyboard::Request,
        _data: &KeyboardUserData<D>,
        _dhandle: &DisplayHandle,
        _data_init: &mut wayland_server::DataInit<'_, D>,
    ) {
    }

    fn destroyed(_state: &mut D, _client_id: ClientId, object_id: ObjectId, data: &KeyboardUserData<D>) {
        if let Some(ref handle) = data.handle {
            handle
                .arc
                .known_kbds
                .lock()
                .unwrap()
                .retain(|k| k.id() != object_id)
        }
    }
}

pub(crate) fn for_each_focused_kbds<D: SeatHandler + 'static>(
    seat: &Seat<D>,
    surface: &WlSurface,
    mut f: impl FnMut(WlKeyboard),
) {
    if let Some(keyboard) = seat.get_keyboard() {
        let inner = keyboard.arc.known_kbds.lock().unwrap();
        for kbd in &*inner {
            if kbd.id().same_client_as(&surface.id()) {
                f(kbd.clone())
            }
        }
    }
}

fn serialize_pressed_keys(keys: Vec<u32>) -> Vec<u8> {
    let serialized = unsafe { ::std::slice::from_raw_parts(keys.as_ptr() as *const u8, keys.len() * 4) };
    serialized.into()
}

impl<D: SeatHandler + 'static> KeyboardTarget<D> for WlSurface {
    fn enter(&self, seat: &Seat<D>, _data: &mut D, keys: Vec<KeysymHandle<'_>>, serial: Serial) {
        for_each_focused_kbds(seat, self, |kbd| {
            kbd.enter(
                serial.into(),
                self,
                serialize_pressed_keys(keys.iter().map(|h| h.raw_code() - 8).collect()),
            )
        })
    }

    fn leave(&self, seat: &Seat<D>, _data: &mut D, serial: Serial) {
        for_each_focused_kbds(seat, self, |kbd| kbd.leave(serial.into(), self))
    }

    fn key(
        &self,
        seat: &Seat<D>,
        _data: &mut D,
        key: KeysymHandle<'_>,
        state: KeyState,
        serial: Serial,
        time: u32,
    ) {
        for_each_focused_kbds(seat, self, |kbd| {
            kbd.key(serial.into(), time, key.raw_code() - 8, state.into())
        })
    }

    fn modifiers(&self, seat: &Seat<D>, _data: &mut D, modifiers: ModifiersState, serial: Serial) {
        for_each_focused_kbds(seat, self, |kbd| {
            let modifiers = modifiers.serialized;
            kbd.modifiers(
                serial.into(),
                modifiers.depressed,
                modifiers.latched,
                modifiers.locked,
                modifiers.layout_locked,
            );
        })
    }
}

impl From<KeyState> for WlKeyState {
    fn from(state: KeyState) -> WlKeyState {
        match state {
            KeyState::Pressed => WlKeyState::Pressed,
            KeyState::Released => WlKeyState::Released,
        }
    }
}

#[derive(Debug, thiserror::Error)]
#[error("Unknown KeyState {0:?}")]
pub struct UnknownKeyState(WlKeyState);

impl TryFrom<WlKeyState> for KeyState {
    type Error = UnknownKeyState;
    fn try_from(state: WlKeyState) -> Result<Self, Self::Error> {
        match state {
            WlKeyState::Pressed => Ok(KeyState::Pressed),
            WlKeyState::Released => Ok(KeyState::Released),
            x => Err(UnknownKeyState(x)),
        }
    }
}
    {
        if let Some(ref surface) = self.focus {
            for kbd in &self.known_kbds {
                if kbd.as_ref().same_client_as(surface.as_ref()) {
                    f(kbd, surface);
                }
            }
        }
            .borrow_mut()
            .focus
            .as_ref()
            .and_then(|f| f.as_ref().client())
            .map(|c| c.equals(client))
            .unwrap_or(false)
    }
        if kbd.as_ref().version() >= 4 {
            kbd.repeat_info(guard.repeat_rate, guard.repeat_delay);
        }
        guard.known_kbds.push(kbd);
    }


    /// Access the current focus of this keyboard
    pub fn current_focus(&self) -> Option<&WlSurface> {
        self.inner.focus.as_ref()
    }

    /// Send the input to the focused keyboards
            .inner
            .focus
            .as_ref()
            .and_then(|f| focus.map(|s| s.as_ref().equals(f.as_ref())))
            .unwrap_or(false);

        if !same {
            });

            // set new focus
            self.inner.focus = focus.cloned();
            let (dep, la, lo, gr) = self.inner.serialize_modifiers();
            let keys = self.inner.serialize_pressed_keys();
            self.inner.with_focused_kbds(|kbd, surface| {
                    ref mut focus_hook,
                    ..
                } = *self.inner;
                focus_hook(focus.as_ref());
            }
            if self.inner.focus.is_some() {
                trace!(self.logger, "Focus set to new surface");

<MSG> Merge pull request #549 from Smithay/fix/new_kbd_enter

seat: Send enter events to new keyboard instances
<DFF> @@ -94,7 +94,7 @@ enum GrabStatus {
 
 struct KbdInternal {
     known_kbds: Vec<WlKeyboard>,
-    focus: Option<WlSurface>,
+    focus: Option<(WlSurface, Serial)>,
     pending_focus: Option<WlSurface>,
     pressed_keys: Vec<u32>,
     mods_state: ModifiersState,
@@ -219,8 +219,8 @@ impl KbdInternal {
     {
         if let Some(ref surface) = self.focus {
             for kbd in &self.known_kbds {
-                if kbd.as_ref().same_client_as(surface.as_ref()) {
-                    f(kbd, surface);
+                if kbd.as_ref().same_client_as(surface.0.as_ref()) {
+                    f(kbd, &surface.0);
                 }
             }
         }
@@ -547,7 +547,7 @@ impl KeyboardHandle {
             .borrow_mut()
             .focus
             .as_ref()
-            .and_then(|f| f.as_ref().client())
+            .and_then(|f| f.0.as_ref().client())
             .map(|c| c.equals(client))
             .unwrap_or(false)
     }
@@ -590,6 +590,15 @@ impl KeyboardHandle {
         if kbd.as_ref().version() >= 4 {
             kbd.repeat_info(guard.repeat_rate, guard.repeat_delay);
         }
+        if let Some((focused, serial)) = guard.focus.as_ref() {
+            if focused.as_ref().same_client_as(kbd.as_ref()) {
+                let (dep, la, lo, gr) = guard.serialize_modifiers();
+                let keys = guard.serialize_pressed_keys();
+                kbd.enter((*serial).into(), focused, keys);
+                // Modifiers must be send after enter event.
+                kbd.modifiers((*serial).into(), dep, la, lo, gr);
+            }
+        }
         guard.known_kbds.push(kbd);
     }
 
@@ -658,7 +667,7 @@ impl<'a> KeyboardInnerHandle<'a> {
 
     /// Access the current focus of this keyboard
     pub fn current_focus(&self) -> Option<&WlSurface> {
-        self.inner.focus.as_ref()
+        self.inner.focus.as_ref().map(|f| &f.0)
     }
 
     /// Send the input to the focused keyboards
@@ -691,7 +700,7 @@ impl<'a> KeyboardInnerHandle<'a> {
             .inner
             .focus
             .as_ref()
-            .and_then(|f| focus.map(|s| s.as_ref().equals(f.as_ref())))
+            .and_then(|f| focus.map(|s| s.as_ref().equals(f.0.as_ref())))
             .unwrap_or(false);
 
         if !same {
@@ -701,7 +710,7 @@ impl<'a> KeyboardInnerHandle<'a> {
             });
 
             // set new focus
-            self.inner.focus = focus.cloned();
+            self.inner.focus = focus.cloned().map(|f| (f, serial));
             let (dep, la, lo, gr) = self.inner.serialize_modifiers();
             let keys = self.inner.serialize_pressed_keys();
             self.inner.with_focused_kbds(|kbd, surface| {
@@ -715,7 +724,7 @@ impl<'a> KeyboardInnerHandle<'a> {
                     ref mut focus_hook,
                     ..
                 } = *self.inner;
-                focus_hook(focus.as_ref());
+                focus_hook(focus.as_ref().map(|f| &f.0));
             }
             if self.inner.focus.is_some() {
                 trace!(self.logger, "Focus set to new surface");

Merge pull request #549 from Smithay/fix/new_kbd_enter