From a4f7958fab88acb2da2488ad1b8dbbf71bb20e73 Mon Sep 17 00:00:00 2001 From: Mara Huldra <43048142+vmedea@users.noreply.github.com> Date: Sat, 16 Apr 2022 06:47:25 +0200 Subject: [PATCH] wayland: Fix key character callback (#290) - Make the character callback use the key converted through the keymap, instead of trying to perform a direct conversion. - Store a persistent keymap_state, instead of creating a new one every time. This makes sure that modifiers such as shift/capslock/ctrl are taken into account. Closes #288. --- src/os/posix/wayland.rs | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/os/posix/wayland.rs b/src/os/posix/wayland.rs index 1783d51..c91f629 100644 --- a/src/os/posix/wayland.rs +++ b/src/os/posix/wayland.rs @@ -26,6 +26,7 @@ use wayland_protocols::xdg_shell::client::xdg_surface::XdgSurface; use wayland_protocols::xdg_shell::client::xdg_toplevel::XdgToplevel; use wayland_protocols::xdg_shell::client::xdg_wm_base::XdgWmBase; use xkb::keymap::Keymap; +use xkb::state::State; use std::cell::RefCell; use std::ffi::c_void; @@ -489,6 +490,7 @@ pub struct Window { key_handler: KeyHandler, // Option because MaybeUninit's get_ref() is nightly-only keymap: Option, + keymap_state: Option, update_rate: UpdateRate, menu_counter: MenuHandle, menus: Vec, @@ -553,6 +555,7 @@ impl Window { key_handler: KeyHandler::new(), keymap: None, + keymap_state: None, update_rate: UpdateRate::new(), menu_counter: MenuHandle(0), menus: Vec::new(), @@ -761,7 +764,9 @@ impl Window { match event { Event::Keymap { format, fd, size } => { - self.keymap = Some(Self::handle_keymap(format, fd, size).unwrap()); + let keymap = Self::handle_keymap(format, fd, size).unwrap(); + self.keymap_state = Some(keymap.state()); + self.keymap = Some(keymap); } Event::Enter { .. } => { self.active = true; @@ -770,27 +775,14 @@ impl Window { self.active = false; } Event::Key { key, state, .. } => { - if let Some(ref keymap) = self.keymap { + if let Some(ref keymap_state) = self.keymap_state { Self::handle_key( - keymap, + keymap_state, key + KEY_XKB_OFFSET, state, &mut self.key_handler, ); } - - if state == wl_keyboard::KeyState::Pressed { - let keysym = xkb::Keysym(key); - let code_point = keysym.utf32(); - if code_point != 0 { - // Taken from GLFW - if !(code_point < 32 || (code_point > 126 && code_point < 160)) { - if let Some(ref mut callback) = self.key_handler.key_callback { - callback.add_char(code_point); - } - } - } - } } Event::Modifiers { mods_depressed, @@ -799,8 +791,7 @@ impl Window { group, .. } => { - if let Some(ref keymap) = self.keymap { - let mut state = keymap.state(); + if let Some(ref mut state) = self.keymap_state { let mut update = state.update(); update.mask(mods_depressed, mods_latched, mods_locked, 0, 0, group); } @@ -937,18 +928,27 @@ impl Window { } fn handle_key( - keymap: &Keymap, + keymap_state: &State, key: u32, state: wl_keyboard::KeyState, key_handler: &mut KeyHandler, ) { let is_down = state == wl_keyboard::KeyState::Pressed; - let state = keymap.state(); - let key_xkb = state.key(key); + let key_xkb = keymap_state.key(key); if let Some(keysym) = key_xkb.sym() { use xkb::key; + if state == wl_keyboard::KeyState::Pressed { + // Taken from GLFW + let code_point = keysym.utf32(); + if !(code_point < 32 || (code_point > 126 && code_point < 160)) { + if let Some(ref mut callback) = key_handler.key_callback { + callback.add_char(code_point); + } + } + } + let key_i = match keysym { key::_0 => Key::Key0, key::_1 => Key::Key1,