mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 11:21:30 +11:00
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:
parent
f42f516339
commit
a4f7958fab
|
@ -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>,
|
||||
keymap_state: Option<State>,
|
||||
update_rate: UpdateRate,
|
||||
menu_counter: MenuHandle,
|
||||
menus: Vec<UnixMenu>,
|
||||
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue