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.
This commit is contained in:
Mara Huldra 2022-04-16 06:47:25 +02:00 committed by GitHub
parent f42f516339
commit a4f7958fab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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_toplevel::XdgToplevel;
use wayland_protocols::xdg_shell::client::xdg_wm_base::XdgWmBase; use wayland_protocols::xdg_shell::client::xdg_wm_base::XdgWmBase;
use xkb::keymap::Keymap; use xkb::keymap::Keymap;
use xkb::state::State;
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::c_void; use std::ffi::c_void;
@ -489,6 +490,7 @@ pub struct Window {
key_handler: KeyHandler, key_handler: KeyHandler,
// Option because MaybeUninit's get_ref() is nightly-only // Option because MaybeUninit's get_ref() is nightly-only
keymap: Option<Keymap>, keymap: Option<Keymap>,
keymap_state: Option<State>,
update_rate: UpdateRate, update_rate: UpdateRate,
menu_counter: MenuHandle, menu_counter: MenuHandle,
menus: Vec<UnixMenu>, menus: Vec<UnixMenu>,
@ -553,6 +555,7 @@ impl Window {
key_handler: KeyHandler::new(), key_handler: KeyHandler::new(),
keymap: None, keymap: None,
keymap_state: None,
update_rate: UpdateRate::new(), update_rate: UpdateRate::new(),
menu_counter: MenuHandle(0), menu_counter: MenuHandle(0),
menus: Vec::new(), menus: Vec::new(),
@ -761,7 +764,9 @@ impl Window {
match event { match event {
Event::Keymap { format, fd, size } => { 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 { .. } => { Event::Enter { .. } => {
self.active = true; self.active = true;
@ -770,27 +775,14 @@ impl Window {
self.active = false; self.active = false;
} }
Event::Key { key, state, .. } => { Event::Key { key, state, .. } => {
if let Some(ref keymap) = self.keymap { if let Some(ref keymap_state) = self.keymap_state {
Self::handle_key( Self::handle_key(
keymap, keymap_state,
key + KEY_XKB_OFFSET, key + KEY_XKB_OFFSET,
state, state,
&mut self.key_handler, &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 { Event::Modifiers {
mods_depressed, mods_depressed,
@ -799,8 +791,7 @@ impl Window {
group, group,
.. ..
} => { } => {
if let Some(ref keymap) = self.keymap { if let Some(ref mut state) = self.keymap_state {
let mut state = keymap.state();
let mut update = state.update(); let mut update = state.update();
update.mask(mods_depressed, mods_latched, mods_locked, 0, 0, group); update.mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
} }
@ -937,18 +928,27 @@ impl Window {
} }
fn handle_key( fn handle_key(
keymap: &Keymap, keymap_state: &State,
key: u32, key: u32,
state: wl_keyboard::KeyState, state: wl_keyboard::KeyState,
key_handler: &mut KeyHandler, key_handler: &mut KeyHandler,
) { ) {
let is_down = state == wl_keyboard::KeyState::Pressed; let is_down = state == wl_keyboard::KeyState::Pressed;
let state = keymap.state(); let key_xkb = keymap_state.key(key);
let key_xkb = state.key(key);
if let Some(keysym) = key_xkb.sym() { if let Some(keysym) = key_xkb.sym() {
use xkb::key; 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 { let key_i = match keysym {
key::_0 => Key::Key0, key::_0 => Key::Key0,
key::_1 => Key::Key1, key::_1 => Key::Key1,