Skip to content

Commit 5479612

Browse files
committed
feat: allow handle virtual keyboard input by WM
1 parent a92540d commit 5479612

File tree

4 files changed

+110
-27
lines changed

4 files changed

+110
-27
lines changed

anvil/src/input_handler.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ use crate::udev::UdevData;
77
#[cfg(feature = "udev")]
88
use smithay::backend::renderer::DebugFlags;
99

10+
#[cfg(any(feature = "winit", feature = "x11", feature = "udev"))]
11+
use smithay::backend::input::AbsolutePositionEvent;
12+
use smithay::input::keyboard::KeyboardHandle;
13+
use smithay::input::keyboard::Keycode;
14+
use smithay::utils::SERIAL_COUNTER;
15+
use smithay::wayland::virtual_keyboard::VirtualKeyboardHandler;
1016
use smithay::{
1117
backend::input::{
1218
self, Axis, AxisSource, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent,
@@ -31,9 +37,6 @@ use smithay::{
3137
},
3238
};
3339

34-
#[cfg(any(feature = "winit", feature = "x11", feature = "udev"))]
35-
use smithay::backend::input::AbsolutePositionEvent;
36-
3740
#[cfg(any(feature = "winit", feature = "x11"))]
3841
use smithay::output::Output;
3942
use tracing::{debug, error, info};
@@ -1329,3 +1332,18 @@ fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Optio
13291332
None
13301333
}
13311334
}
1335+
1336+
impl<BackendData: Backend> VirtualKeyboardHandler for AnvilState<BackendData> {
1337+
fn on_keyboard_event(
1338+
&mut self,
1339+
keycode: Keycode,
1340+
state: KeyState,
1341+
time: u32,
1342+
keyboard: KeyboardHandle<Self>,
1343+
) {
1344+
let serial = SERIAL_COUNTER.next_serial();
1345+
keyboard.input(self, keycode, state, serial, time, |_, _, _| {
1346+
FilterResult::Forward::<bool>
1347+
});
1348+
}
1349+
}

src/input/keyboard/keymap_file.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ impl KeymapFile {
8585
Ok(())
8686
}
8787

88+
#[cfg(feature = "wayland_frontend")]
89+
/// Send keymap string for processing
90+
pub fn keymap_string(&self) -> String {
91+
self.keymap.clone()
92+
}
93+
8894
/// Send the keymap contained within to a WlKeyboard
8995
pub fn send(
9096
&self,

src/wayland/virtual_keyboard/mod.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
1414
//! use smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState;
1515
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
16+
//! use smithay::input::keyboard::KeyboardHandle;
17+
//! use smithay::backend::input::{KeyState, Keycode};
18+
//! use smithay::wayland::virtual_keyboard::VirtualKeyboardHandler;
1619
//! # use smithay::reexports::wayland_server::Client;
1720
//!
1821
//! # struct State { seat_state: SeatState<Self> };
@@ -47,6 +50,15 @@
4750
//! # fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { unimplemented!() }
4851
//! # fn commit(&mut self, surface: &WlSurface) {}
4952
//! # }
53+
//! impl VirtualKeyboardHandler for State {
54+
//! fn on_keyboard_event(
55+
//! &mut self,
56+
//! keycode: Keycode,
57+
//! state: KeyState,
58+
//! time: u32,
59+
//! keyboard: KeyboardHandle<Self>,
60+
//! ) { }
61+
//! }
5062
//! # delegate_compositor!(State);
5163
//! ```
5264
//!
@@ -57,9 +69,10 @@ use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::{
5769
};
5870
use wayland_server::{backend::GlobalId, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New};
5971

60-
use crate::input::{Seat, SeatHandler};
61-
6272
use self::virtual_keyboard_handle::VirtualKeyboardHandle;
73+
use crate::backend::input::{KeyState, Keycode};
74+
use crate::input::keyboard::KeyboardHandle;
75+
use crate::input::{Seat, SeatHandler};
6376

6477
const MANAGER_VERSION: u32 = 1;
6578

@@ -91,6 +104,18 @@ where
91104
display.create_global::<D, ZwpVirtualKeyboardManagerV1, _>(MANAGER_VERSION, data)
92105
}
93106

107+
/// Handle keyboard event
108+
pub trait VirtualKeyboardHandler: SeatHandler {
109+
/// Handle KeyboardEvent as usual
110+
fn on_keyboard_event(
111+
&mut self,
112+
keycode: Keycode,
113+
state: KeyState,
114+
time: u32,
115+
keyboard: KeyboardHandle<Self>,
116+
);
117+
}
118+
94119
impl VirtualKeyboardManagerState {
95120
/// Initialize a virtual keyboard manager global.
96121
pub fn new<D, F>(display: &DisplayHandle, filter: F) -> Self

src/wayland/virtual_keyboard/virtual_keyboard_handle.rs

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,22 @@ use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboar
1010
self, ZwpVirtualKeyboardV1,
1111
};
1212
use wayland_server::{
13-
backend::ClientId,
14-
protocol::wl_keyboard::{KeyState, KeymapFormat},
15-
Client, DataInit, Dispatch, DisplayHandle, Resource,
13+
backend::ClientId, protocol::wl_keyboard::KeymapFormat, Client, DataInit, Dispatch, DisplayHandle,
14+
Resource,
1615
};
1716
use xkbcommon::xkb;
1817

1918
use crate::input::keyboard::{KeyboardTarget, KeymapFile, ModifiersState};
19+
use crate::wayland::input_method::InputMethodSeat;
2020
use crate::{
2121
input::{Seat, SeatHandler},
2222
utils::SERIAL_COUNTER,
2323
wayland::seat::{keyboard::for_each_focused_kbds, WaylandFocus},
2424
};
2525

26-
use super::VirtualKeyboardManagerState;
26+
use crate::backend::input::KeyState;
27+
28+
use super::{VirtualKeyboardHandler, VirtualKeyboardManagerState};
2729

2830
#[derive(Debug, Default)]
2931
pub(crate) struct VirtualKeyboard {
@@ -75,11 +77,12 @@ impl<D> Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>, D> for Virtua
7577
where
7678
D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
7779
D: SeatHandler + 'static,
80+
D: VirtualKeyboardHandler,
7881
<D as SeatHandler>::KeyboardFocus: WaylandFocus,
7982
{
8083
fn request(
8184
user_data: &mut D,
82-
_client: &Client,
85+
client: &Client,
8386
virtual_keyboard: &ZwpVirtualKeyboardV1,
8487
request: zwp_virtual_keyboard_v1::Request,
8588
data: &VirtualKeyboardUserData<D>,
@@ -100,25 +103,56 @@ where
100103
return;
101104
}
102105
};
103-
104106
// Ensure virtual keyboard's keymap is active.
105107
let keyboard_handle = data.seat.get_keyboard().unwrap();
106-
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
107-
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
108-
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
109-
110-
if let Some(wl_surface) = focus.and_then(|f| f.wl_surface()) {
111-
for_each_focused_kbds(&data.seat, &wl_surface, |kbd| {
112-
// This should be wl_keyboard::KeyState, but the protocol does not state
113-
// the parameter is an enum.
114-
let key_state = if state == 1 {
115-
KeyState::Pressed
116-
} else {
117-
KeyState::Released
118-
};
119-
120-
kbd.key(SERIAL_COUNTER.next_serial().0, time, key, key_state);
121-
});
108+
109+
let ime_keyboard_grabbed = data
110+
.seat
111+
.input_method()
112+
.inner
113+
.lock()
114+
.unwrap()
115+
.keyboard_grab
116+
.inner
117+
.lock()
118+
.unwrap()
119+
.grab
120+
.clone();
121+
if ime_keyboard_grabbed.is_some()
122+
&& ime_keyboard_grabbed.unwrap().client().unwrap() == *client
123+
{
124+
use wayland_server::protocol::wl_keyboard::KeyState;
125+
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
126+
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
127+
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
128+
keyboard_handle
129+
.set_keymap_from_string(user_data, vk_state.keymap.keymap_string())
130+
.unwrap();
131+
if let Some(wl_surface) = focus.and_then(|f| f.wl_surface()) {
132+
for_each_focused_kbds(&data.seat, &wl_surface, |kbd| {
133+
// This should be wl_keyboard::KeyState, but the protocol does not state
134+
// the parameter is an enum.
135+
let key_state = if state == 1 {
136+
KeyState::Pressed
137+
} else {
138+
KeyState::Released
139+
};
140+
141+
kbd.key(SERIAL_COUNTER.next_serial().0, time, key, key_state);
142+
});
143+
}
144+
} else {
145+
{
146+
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
147+
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
148+
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
149+
}
150+
let key_state = if state == 1 {
151+
KeyState::Pressed
152+
} else {
153+
KeyState::Released
154+
};
155+
user_data.on_keyboard_event((key + 8).into(), key_state, time, keyboard_handle);
122156
}
123157
}
124158
zwp_virtual_keyboard_v1::Request::Modifiers {

0 commit comments

Comments
 (0)