Skip to content

Commit faeae5c

Browse files
committed
Android: Add physical keys support
1 parent 6098b69 commit faeae5c

2 files changed

Lines changed: 24 additions & 11 deletions

File tree

internal/backends/android-activity/androidwindowadapter.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use i_slint_core::api::{
1717
use i_slint_core::input::{InternalKeyEvent, KeyEvent, KeyEventType, TouchPhase};
1818
use i_slint_core::lengths::PhysicalEdges;
1919
use i_slint_core::platform::{
20-
Key, PointerEventButton, WindowAdapter, WindowEvent, WindowProperties,
20+
Key, PointerEventButton, WindowAdapter, WindowEvent, WindowKeyEvent, WindowKeyEventType,
21+
WindowProperties,
2122
};
2223
use i_slint_core::timers::{Timer, TimerMode};
2324
use i_slint_core::window::{InputMethodRequest, WindowInner};
@@ -680,16 +681,27 @@ fn button_for_event(
680681
}
681682

682683
fn map_key_event(key_event: &android_activity::input::KeyEvent) -> Option<WindowEvent> {
683-
let text = map_key_code(key_event.key_code())?;
684-
let repeat = key_event.repeat_count() > 0;
685-
match key_event.action() {
686-
KeyAction::Down if repeat => Some(WindowEvent::KeyPressRepeated { text }),
687-
KeyAction::Down => Some(WindowEvent::KeyPressed { text }),
688-
KeyAction::Up => Some(WindowEvent::KeyReleased { text }),
689-
KeyAction::Multiple if repeat => Some(WindowEvent::KeyPressRepeated { text }),
690-
KeyAction::Multiple => Some(WindowEvent::KeyPressed { text }),
691-
_ => None,
684+
let mut slint_event = KeyEvent::default();
685+
slint_event.text = map_key_code(key_event.key_code())?;
686+
slint_event.physical_key = physical_key_name(key_event.scan_code());
687+
slint_event.repeat = key_event.repeat_count() > 0;
688+
let event_type = match key_event.action() {
689+
KeyAction::Down | KeyAction::Multiple => WindowKeyEventType::Pressed,
690+
KeyAction::Up => WindowKeyEventType::Released,
691+
_ => return None,
692+
};
693+
let slint_event = WindowKeyEvent::new(event_type, slint_event);
694+
Some(WindowEvent::Key(WindowKeyEvent))
695+
}
696+
697+
// The Android scan code is the evdev key code, which maps to XKB with a fixed offset of 8.
698+
fn physical_key_name(scan_code: i32) -> SharedString {
699+
if scan_code <= 0 {
700+
return SharedString::default();
692701
}
702+
i_slint_common::physical_key_codes::physical_key_name_from_xkb(scan_code as u32 + 8)
703+
.unwrap_or_default()
704+
.into()
693705
}
694706

695707
fn map_key_code(code: android_activity::input::Keycode) -> Option<SharedString> {

internal/common/physical_key_codes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ macro_rules! for_each_physical_keys {
121121
/// Maps an XKB keycode (the evdev keycode plus 8) to a Slint physical key name.
122122
///
123123
/// This is what X11, Wayland, and libinput-based backends report as the native key code.
124-
#[cfg(target_os = "linux")]
124+
/// On Android the evdev scan code (plus 8) matches this too.
125+
#[cfg(any(target_os = "linux", target_os = "android"))]
125126
pub fn physical_key_name_from_xkb(keycode: u32) -> Option<&'static str> {
126127
macro_rules! xkb_to_name {
127128
($($name:ident # $_winit:ident # $xkb:literal # $_win:literal # $($_mac:literal)?;)*) => {

0 commit comments

Comments
 (0)