Use Keycode type consistently for representing keycode

It seems good to use a dedicated type for keycodes, particularly given
there's two conventions for keycodes, offset by 8. So there's ambiguity
about what the numberic value of the keycode actually represents.

We might prefer to use the Wayland value rather than the X11 version
like `xkeysym::KeyCode` uses. But it would complicate things to have two
different keycode types, and the code that calls `kbd.key` already is
converting from `Keycode`.
This commit is contained in:
Ian Douglas Scott 2024-09-16 19:17:06 -07:00 committed by Victoria Brekenfeld
parent 1259a69992
commit 566e176b44
12 changed files with 68 additions and 78 deletions

View file

@ -148,7 +148,7 @@ impl<BackendData: Backend> AnvilState<BackendData> {
fn keyboard_key_to_action<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) -> KeyAction {
let keycode = evt.key_code();
let state = evt.state();
debug!(keycode, ?state, "key");
debug!(?keycode, ?state, "key");
let serial = SCOUNTER.next_serial();
let time = Event::time_msec(&evt);
let mut suppressed_keys = self.suppressed_keys.clone();
@ -571,7 +571,7 @@ impl<BackendData: Backend> AnvilState<BackendData> {
for keycode in keyboard.pressed_keys() {
keyboard.input(
self,
keycode.raw(),
keycode,
KeyState::Released,
SCOUNTER.next_serial(),
0,

View file

@ -61,7 +61,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
keyboard.input(
&mut state,
1,
smithay::backend::input::Keycode::from(9u32),
smithay::backend::input::KeyState::Pressed,
0.into(),
0,

View file

@ -2,6 +2,8 @@
use std::path::PathBuf;
pub use xkbcommon::xkb::Keycode;
mod tablet;
pub use tablet::{
@ -102,7 +104,7 @@ pub trait KeyboardKeyEvent<B: InputBackend>: Event<B> {
/// `input-event-codes.h`.
///
/// [input event codes]: https://gitlab.freedesktop.org/libinput/libinput/-/blob/main/include/linux/linux/input-event-codes.h
fn key_code(&self) -> u32;
fn key_code(&self) -> Keycode;
/// State of the key
fn state(&self) -> KeyState;
@ -112,7 +114,7 @@ pub trait KeyboardKeyEvent<B: InputBackend>: Event<B> {
}
impl<B: InputBackend> KeyboardKeyEvent<B> for UnusedEvent {
fn key_code(&self) -> u32 {
fn key_code(&self) -> Keycode {
match *self {}
}

View file

@ -111,9 +111,9 @@ impl backend::Event<LibinputInputBackend> for event::keyboard::KeyboardKeyEvent
}
impl backend::KeyboardKeyEvent<LibinputInputBackend> for event::keyboard::KeyboardKeyEvent {
fn key_code(&self) -> u32 {
fn key_code(&self) -> backend::Keycode {
use input::event::keyboard::KeyboardEventTrait;
self.key()
(self.key() + 8).into()
}
fn state(&self) -> backend::KeyState {

View file

@ -7,9 +7,9 @@ use winit::{
use crate::backend::input::{
self, AbsolutePositionEvent, Axis, AxisRelativeDirection, AxisSource, ButtonState, Device,
DeviceCapability, Event, InputBackend, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
PointerMotionAbsoluteEvent, TouchCancelEvent, TouchDownEvent, TouchEvent, TouchMotionEvent, TouchSlot,
TouchUpEvent, UnusedEvent,
DeviceCapability, Event, InputBackend, KeyState, KeyboardKeyEvent, Keycode, PointerAxisEvent,
PointerButtonEvent, PointerMotionAbsoluteEvent, TouchCancelEvent, TouchDownEvent, TouchEvent,
TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent,
};
/// Marker used to define the `InputBackend` types for the winit backend.
@ -65,8 +65,8 @@ impl Event<WinitInput> for WinitKeyboardInputEvent {
}
impl KeyboardKeyEvent<WinitInput> for WinitKeyboardInputEvent {
fn key_code(&self) -> u32 {
self.key
fn key_code(&self) -> Keycode {
(self.key + 8).into()
}
fn state(&self) -> KeyState {

View file

@ -4,8 +4,8 @@ use super::{window_inner::WindowInner, Window, WindowTemporary};
use crate::{
backend::input::{
self, AbsolutePositionEvent, Axis, AxisRelativeDirection, AxisSource, ButtonState, Device,
DeviceCapability, InputBackend, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
PointerMotionAbsoluteEvent, UnusedEvent,
DeviceCapability, InputBackend, KeyState, KeyboardKeyEvent, Keycode, PointerAxisEvent,
PointerButtonEvent, PointerMotionAbsoluteEvent, UnusedEvent,
},
utils::{Logical, Size},
};
@ -48,7 +48,7 @@ impl Device for X11VirtualDevice {
#[derive(Debug, Clone)]
pub struct X11KeyboardInputEvent {
pub(crate) time: u32,
pub(crate) key: u32,
pub(crate) key: Keycode,
pub(crate) count: u32,
pub(crate) state: KeyState,
pub(crate) window: Weak<WindowInner>,
@ -74,7 +74,7 @@ impl input::Event<X11Input> for X11KeyboardInputEvent {
}
impl KeyboardKeyEvent<X11Input> for X11KeyboardInputEvent {
fn key_code(&self) -> u32 {
fn key_code(&self) -> Keycode {
self.key
}

View file

@ -82,7 +82,7 @@ use crate::{
allocator::{Allocator, Swapchain},
drm::{node::path_to_type, CreateDrmNodeError, DrmNode, NodeType},
egl::{native::X11DefaultDisplay, EGLDevice, EGLDisplay, Error as EGLError},
input::{Axis, ButtonState, InputEvent, KeyState},
input::{Axis, ButtonState, InputEvent, KeyState, Keycode},
},
utils::{x11rb::X11Source, Logical, Size},
};
@ -801,12 +801,7 @@ impl X11Inner {
event: InputEvent::Keyboard {
event: X11KeyboardInputEvent {
time: key_press.time,
// X11's keycodes are +8 relative to the libinput keycodes
// that are expected, so subtract 8 from each keycode to
// match libinput.
//
// https://github.com/freedesktop/xorg-xf86-input-libinput/blob/master/src/xf86libinput.c#L54
key: key_press.detail as u32 - 8,
key: Keycode::from(key_press.detail),
count,
state: KeyState::Pressed,
window,
@ -837,12 +832,7 @@ impl X11Inner {
event: InputEvent::Keyboard {
event: X11KeyboardInputEvent {
time: key_release.time,
// X11's keycodes are +8 relative to the libinput keycodes
// that are expected, so subtract 8 from each keycode to
// match libinput.
//
// https://github.com/freedesktop/xorg-xf86-input-libinput/blob/master/src/xf86libinput.c#L54
key: key_release.detail as u32 - 8,
key: Keycode::from(key_release.detail),
count,
state: KeyState::Released,
window,

View file

@ -6,7 +6,7 @@ use std::{
use wayland_server::{protocol::wl_surface::WlSurface, Resource};
use crate::{
backend::input::{ButtonState, KeyState},
backend::input::{ButtonState, KeyState, Keycode},
input::{
keyboard::{
GrabStartData as KeyboardGrabStartData, KeyboardGrab, KeyboardHandle, KeyboardInnerHandle,
@ -441,7 +441,7 @@ where
&mut self,
data: &mut D,
handle: &mut KeyboardInnerHandle<'_, D>,
keycode: u32,
keycode: Keycode,
state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,

View file

@ -133,8 +133,8 @@ impl LedState {
pub(crate) struct KbdInternal<D: SeatHandler> {
pub(crate) focus: Option<(<D as SeatHandler>::KeyboardFocus, Serial)>,
pending_focus: Option<<D as SeatHandler>::KeyboardFocus>,
pub(crate) pressed_keys: HashSet<u32>,
pub(crate) forwarded_pressed_keys: HashSet<u32>,
pub(crate) pressed_keys: HashSet<Keycode>,
pub(crate) forwarded_pressed_keys: HashSet<Keycode>,
pub(crate) mods_state: ModifiersState,
context: xkb::Context,
pub(crate) keymap: xkb::Keymap,
@ -198,7 +198,7 @@ impl<D: SeatHandler + 'static> KbdInternal<D> {
}
// returns whether the modifiers or led state has changed
fn key_input(&mut self, keycode: u32, state: KeyState) -> (bool, bool) {
fn key_input(&mut self, keycode: Keycode, state: KeyState) -> (bool, bool) {
// track pressed keys as xkbcommon does not seem to expose it :(
let direction = match state {
KeyState::Pressed => {
@ -214,7 +214,7 @@ impl<D: SeatHandler + 'static> KbdInternal<D> {
// update state
// Offset the keycode by 8, as the evdev XKB rules reflect X's
// broken keycode system, which starts at 8.
let state_components = self.state.update_key((keycode + 8).into(), direction);
let state_components = self.state.update_key(keycode, direction);
let modifiers_changed = state_components != 0;
if modifiers_changed {
self.mods_state.update_with(&self.state);
@ -560,7 +560,7 @@ pub trait KeyboardGrab<D: SeatHandler> {
&mut self,
data: &mut D,
handle: &mut KeyboardInnerHandle<'_, D>,
keycode: u32,
keycode: Keycode,
state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,
@ -726,7 +726,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
let mut state = xkb::State::new(&keymap);
for key in &internal.pressed_keys {
state.update_key((key + 8).into(), xkb::KeyDirection::Down);
state.update_key(*key, xkb::KeyDirection::Down);
}
let led_mapping = LedMapping::from_keymap(&keymap);
@ -891,7 +891,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
pub fn input<T, F>(
&self,
data: &mut D,
keycode: u32,
keycode: Keycode,
state: KeyState,
serial: Serial,
time: u32,
@ -918,7 +918,13 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
///
/// Prefer using [`KeyboardHandle::input`] if this decision can be done synchronously
/// in the `filter` closure.
pub fn input_intercept<T, F>(&self, data: &mut D, keycode: u32, state: KeyState, filter: F) -> (T, bool)
pub fn input_intercept<T, F>(
&self,
data: &mut D,
keycode: Keycode,
state: KeyState,
filter: F,
) -> (T, bool)
where
F: FnOnce(&mut D, &ModifiersState, KeysymHandle<'_>) -> T,
{
@ -927,9 +933,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
let mut guard = self.arc.internal.lock().unwrap();
let (mods_changed, leds_changed) = guard.key_input(keycode, state);
let key_handle = KeysymHandle {
// Offset the keycode by 8, as the evdev XKB rules reflect X's
// broken keycode system, which starts at 8.
keycode: (keycode + 8).into(),
keycode,
state: &guard.state,
keymap: &guard.keymap,
};
@ -953,7 +957,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
pub fn input_forward(
&self,
data: &mut D,
keycode: u32,
keycode: Keycode,
state: KeyState,
serial: Serial,
time: u32,
@ -1001,7 +1005,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
/// Return the key codes of the currently pressed keys.
pub fn pressed_keys(&self) -> HashSet<Keycode> {
let guard = self.arc.internal.lock().unwrap();
guard.pressed_keys.iter().map(|&code| code.into()).collect()
guard.pressed_keys.clone()
}
/// Iterate over the keysyms of the currently pressed keys.
@ -1015,8 +1019,8 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
let handles = guard
.pressed_keys
.iter()
.map(|code| KeysymHandle {
keycode: (code + 8).into(),
.map(|keycode| KeysymHandle {
keycode: *keycode,
state: &guard.state,
keymap: &guard.keymap,
})
@ -1150,9 +1154,9 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
}
/// Convert a given keycode as a [`KeysymHandle`] modified by this keyboards state
pub fn keysym_handle(&self, keycode: u32) -> KeysymHandle<'_> {
pub fn keysym_handle(&self, keycode: Keycode) -> KeysymHandle<'_> {
KeysymHandle {
keycode: (keycode + 8).into(),
keycode,
state: &self.inner.state,
keymap: &self.inner.keymap,
}
@ -1167,7 +1171,7 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
pub fn input(
&mut self,
data: &mut D,
keycode: u32,
keycode: Keycode,
key_state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,
@ -1189,7 +1193,7 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
// key event must be sent before modifiers event for libxkbcommon
// to process them correctly
let key = KeysymHandle {
keycode: (keycode + 8).into(),
keycode,
state: &self.inner.state,
keymap: &self.inner.keymap,
};
@ -1239,14 +1243,10 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
.inner
.forwarded_pressed_keys
.iter()
.map(|keycode| {
KeysymHandle {
// Offset the keycode by 8, as the evdev XKB rules reflect X's
// broken keycode system, which starts at 8.
keycode: (keycode + 8).into(),
.map(|keycode| KeysymHandle {
keycode: *keycode,
state: &self.inner.state,
keymap: &self.inner.keymap,
}
})
.collect();
@ -1258,14 +1258,10 @@ impl<'a, D: SeatHandler + 'static> KeyboardInnerHandle<'a, D> {
.inner
.forwarded_pressed_keys
.iter()
.map(|keycode| {
KeysymHandle {
// Offset the keycode by 8, as the evdev XKB rules reflect X's
// broken keycode system, which starts at 8.
keycode: (keycode + 8).into(),
.map(|keycode| KeysymHandle {
keycode: *keycode,
state: &self.inner.state,
keymap: &self.inner.keymap,
}
})
.collect();
@ -1289,7 +1285,7 @@ impl<D: SeatHandler + 'static> KeyboardGrab<D> for DefaultGrab {
&mut self,
data: &mut D,
handle: &mut KeyboardInnerHandle<'_, D>,
keycode: u32,
keycode: Keycode,
state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,

View file

@ -17,7 +17,10 @@ use crate::input::{
SeatHandler,
};
use crate::wayland::text_input::TextInputHandle;
use crate::{backend::input::KeyState, utils::Serial};
use crate::{
backend::input::{KeyState, Keycode},
utils::Serial,
};
use super::InputMethodManagerState;
@ -41,7 +44,7 @@ where
&mut self,
_data: &mut D,
_handle: &mut KeyboardInnerHandle<'_, D>,
keycode: u32,
keycode: Keycode,
key_state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,
@ -52,7 +55,7 @@ where
inner
.text_input_handle
.focused_text_input_serial_or_default(serial.0, |serial| {
keyboard.key(serial, time, keycode, key_state.into());
keyboard.key(serial, time, keycode.raw() - 8, key_state.into());
if let Some(serialized) = modifiers.map(|m| m.serialized) {
keyboard.modifiers(
serial,

View file

@ -12,7 +12,7 @@ use wayland_server::{
use super::WaylandFocus;
use crate::{
backend::input::KeyState,
backend::input::{KeyState, Keycode},
input::{
keyboard::{KeyboardHandle, KeyboardTarget, KeysymHandle, ModifiersState},
Seat, SeatHandler, SeatState,
@ -66,7 +66,7 @@ where
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());
let keys = serialize_pressed_keys(guard.pressed_keys.iter().copied());
kbd.enter((*serial).into(), &focused.wl_surface().unwrap(), keys);
// Modifiers must be send after enter event.
kbd.modifiers(
@ -152,9 +152,8 @@ pub(crate) fn for_each_focused_kbds<D: SeatHandler + 'static>(
}
}
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()
fn serialize_pressed_keys(keys: impl Iterator<Item = Keycode>) -> Vec<u8> {
keys.flat_map(|key| (key.raw() - 8).to_ne_bytes()).collect()
}
impl<D: SeatHandler + 'static> KeyboardTarget<D> for WlSurface {
@ -164,7 +163,7 @@ impl<D: SeatHandler + 'static> KeyboardTarget<D> for WlSurface {
kbd.enter(
serial.into(),
self,
serialize_pressed_keys(keys.iter().map(|h| h.raw_code().raw() - 8).collect()),
serialize_pressed_keys(keys.iter().map(|h| h.raw_code())),
)
});

View file

@ -47,7 +47,7 @@ use wayland_server::{
};
use crate::{
backend::input::KeyState,
backend::input::{KeyState, Keycode},
input::{
keyboard::{self, KeyboardGrab, KeyboardInnerHandle},
Seat, SeatHandler,
@ -92,7 +92,7 @@ impl<D: XWaylandKeyboardGrabHandler + 'static> KeyboardGrab<D> for XWaylandKeybo
&mut self,
data: &mut D,
handle: &mut KeyboardInnerHandle<'_, D>,
keycode: u32,
keycode: Keycode,
state: KeyState,
modifiers: Option<keyboard::ModifiersState>,
serial: Serial,