Skip to content

Commit

Permalink
native/linux_wayland: add missing insert_char event. We do this by us…
Browse files Browse the repository at this point in the history
…ing keysyms for WaylandEvent::KeyboardKey directly.
  • Loading branch information
rsx authored and not-fl3 committed Jul 14, 2024
1 parent a962bfd commit 9b4072e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
31 changes: 23 additions & 8 deletions src/native/linux_wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ unsafe extern "C" fn seat_handle_capabilities(
}

enum WaylandEvent {
KeyboardKey(KeyCode, bool),
KeyboardKey(u32, bool),
PointerMotion(f32, f32),
PointerButton(MouseButton, bool),
PointerAxis(f32, f32),
Expand Down Expand Up @@ -204,8 +204,7 @@ unsafe extern "C" fn keyboard_handle_key(
// https://wayland-book.com/seat/keyboard.html
// To translate this to an XKB scancode, you must add 8 to the evdev scancode.
let keysym = (display.xkb.xkb_state_key_get_one_sym)(display.xkb_state, key + 8);
let keycode = keycodes::translate(keysym);
EVENTS.push(WaylandEvent::KeyboardKey(keycode, state == 1));
EVENTS.push(WaylandEvent::KeyboardKey(keysym, state == 1));
}
unsafe extern "C" fn keyboard_handle_modifiers(
data: *mut ::std::os::raw::c_void,
Expand Down Expand Up @@ -759,15 +758,23 @@ where
alt: false,
logo: false,
};
let mut repeated_keys: HashSet<KeyCode> = HashSet::new();
let mut repeated_keys: HashSet<u32> = HashSet::new();
let (mut last_mouse_x, mut last_mouse_y) = (0.0, 0.0);

while display.closed == false {
(client.wl_display_dispatch_pending)(wdisplay);

if let Some(ref mut event_handler) = display.event_handler {
for keycode in &repeated_keys {
for keysym in &repeated_keys {
let keycode = keycodes::translate(*keysym);
event_handler.key_down_event(keycode.clone(), keymods, true);

let chr = keycodes::keysym_to_unicode(&mut display.xkb, *keysym);
if chr > 0 {
if let Some(chr) = std::char::from_u32(chr as u32) {
event_handler.char_event(chr, keymods, true);
}
}
}

while let Ok(request) = rx.try_recv() {
Expand Down Expand Up @@ -796,7 +803,8 @@ where

for event in EVENTS.drain(..) {
match event {
WaylandEvent::KeyboardKey(keycode, state) => {
WaylandEvent::KeyboardKey(keysym, state) => {
let keycode = keycodes::translate(keysym);
match keycode {
KeyCode::LeftShift | KeyCode::RightShift => keymods.shift = state,
KeyCode::LeftControl | KeyCode::RightControl => {
Expand All @@ -809,10 +817,17 @@ where

if state {
event_handler.key_down_event(keycode, keymods, false);
repeated_keys.insert(keycode);
repeated_keys.insert(keysym);

let chr = keycodes::keysym_to_unicode(&mut display.xkb, keysym);
if chr > 0 {
if let Some(chr) = std::char::from_u32(chr as u32) {
event_handler.char_event(chr, keymods, false);
}
}
} else {
event_handler.key_up_event(keycode, keymods);
repeated_keys.remove(&keycode);
repeated_keys.remove(&keysym);
}
}
WaylandEvent::PointerMotion(x, y) => {
Expand Down
5 changes: 5 additions & 0 deletions src/native/linux_wayland/keycodes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::event::KeyCode;
use crate::native::linux_wayland::libxkbcommon::LibXkbCommon;

pub fn translate(keysym: u32) -> KeyCode {
// See xkbcommon/xkbcommon-keysyms.h
Expand Down Expand Up @@ -125,3 +126,7 @@ pub fn translate(keysym: u32) -> KeyCode {
_ => return KeyCode::Unknown,
};
}

pub unsafe extern "C" fn keysym_to_unicode(libxkbcommon: &mut LibXkbCommon, keysym: u32) -> i32 {
return (libxkbcommon.xkb_keysym_to_utf32)(keysym as u32) as i32;
}
6 changes: 6 additions & 0 deletions src/native/linux_wayland/libxkbcommon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub type xkb_state_update_mask = unsafe extern "C" fn(
locked_layout: u32,
) -> ::std::os::raw::c_int;

pub type xkb_keysym_to_utf32 = unsafe extern "C" fn(_: u32) -> u32;

#[derive(Clone)]
pub struct LibXkbCommon {
_module: std::rc::Rc<crate::native::module::Module>,
Expand All @@ -51,12 +53,15 @@ pub struct LibXkbCommon {
pub xkb_state_unref: xkb_state_unref,
pub xkb_state_key_get_one_sym: xkb_state_key_get_one_sym,
pub xkb_state_update_mask: xkb_state_update_mask,
pub xkb_keysym_to_utf32: xkb_keysym_to_utf32,
}

impl LibXkbCommon {
pub fn try_load() -> Option<LibXkbCommon> {
crate::native::module::Module::load("libxkbcommon.so")
.or_else(|_| crate::native::module::Module::load("libxkbcommon.so.0"))
.or_else(|_| crate::native::module::Module::load("libxkbcommon.so.0.0.0"))
.or_else(|_| crate::native::module::Module::load("libxkbcommon.so.0.0.0.0"))
.map(|module| LibXkbCommon {
xkb_context_new: module.get_symbol("xkb_context_new").unwrap(),
xkb_context_unref: module.get_symbol("xkb_context_unref").unwrap(),
Expand All @@ -68,6 +73,7 @@ impl LibXkbCommon {
xkb_state_unref: module.get_symbol("xkb_state_unref").unwrap(),
xkb_state_key_get_one_sym: module.get_symbol("xkb_state_key_get_one_sym").unwrap(),
xkb_state_update_mask: module.get_symbol("xkb_state_update_mask").unwrap(),
xkb_keysym_to_utf32: module.get_symbol("xkb_keysym_to_utf32").unwrap(),

_module: std::rc::Rc::new(module),
})
Expand Down

0 comments on commit 9b4072e

Please sign in to comment.