Skip to content

Commit 721e9ca

Browse files
committed
feat: use set_keymap and get_keymap to proper handle keymap
1 parent 7bff67b commit 721e9ca

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

src/wayland/virtual_keyboard/virtual_keyboard_handle.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
use std::os::unix::io::OwnedFd;
21
use std::{
32
fmt,
3+
fs::File,
4+
io::Read,
5+
os::unix::io::OwnedFd,
46
sync::{Arc, Mutex},
57
};
68

9+
use memmap2::MmapOptions;
710
use tracing::debug;
811
use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboard_v1::Error::NoKeymap;
912
use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboard_v1::{
1013
self, ZwpVirtualKeyboardV1,
1114
};
12-
use wayland_server::{
13-
backend::ClientId, protocol::wl_keyboard::KeymapFormat, Client, DataInit, Dispatch, DisplayHandle,
14-
Resource,
15-
};
15+
use wayland_server::protocol::wl_keyboard::KeymapFormat;
16+
use wayland_server::{backend::ClientId, Client, DataInit, Dispatch, DisplayHandle, Resource};
1617
use xkbcommon::xkb;
1718

18-
use crate::input::keyboard::{KeyboardTarget, KeymapFile, ModifiersState};
19+
use crate::input::keyboard::{KeyboardTarget, Keymap, ModifiersState};
1920
use crate::wayland::input_method::InputMethodSeat;
2021
use crate::{
2122
input::{Seat, SeatHandler},
@@ -33,15 +34,18 @@ pub(crate) struct VirtualKeyboard {
3334
}
3435

3536
struct VirtualKeyboardState {
36-
keymap: KeymapFile,
37+
keymap: Keymap,
3738
mods: ModifiersState,
3839
state: xkb::State,
3940
}
4041

4142
impl fmt::Debug for VirtualKeyboardState {
4243
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4344
f.debug_struct("VirtualKeyboardState")
44-
.field("keymap", &self.keymap.id())
45+
.field(
46+
"keymap",
47+
&self.keymap.inner.get_as_string(xkb::KEYMAP_FORMAT_USE_ORIGINAL),
48+
)
4549
.field("mods", &self.mods)
4650
.field("state", &self.state.get_raw_ptr())
4751
.finish()
@@ -96,7 +100,7 @@ where
96100
};
97101
match request {
98102
zwp_virtual_keyboard_v1::Request::Keymap { format, fd, size } => {
99-
update_keymap(data, format, fd, size as usize);
103+
update_keymap(user_data, data, format, fd, size as usize);
100104
}
101105

102106
zwp_virtual_keyboard_v1::Request::Key { time, key, state } => {
@@ -116,10 +120,11 @@ where
116120
.map(|grab| grab.client().as_ref() == Some(client))
117121
.unwrap_or(false)
118122
{
123+
let old_keymap = keyboard_handle.get_keymap().clone();
124+
let _ = keyboard_handle.set_keymap(user_data, &vk_state.keymap);
119125
use wayland_server::protocol::wl_keyboard::KeyState;
120126
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
121127
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
122-
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
123128
if let Some(wl_surface) = focus.and_then(|f| f.wl_surface()) {
124129
for_each_focused_kbds(&data.seat, &wl_surface, |kbd| {
125130
// This should be wl_keyboard::KeyState, but the protocol does not state
@@ -133,18 +138,18 @@ where
133138
kbd.key(SERIAL_COUNTER.next_serial().0, time, key, key_state);
134139
});
135140
}
141+
drop(internal);
142+
keyboard_handle.set_keymap(user_data, &old_keymap);
136143
} else {
137-
{
138-
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
139-
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
140-
keyboard_handle.send_keymap(user_data, &focus, &vk_state.keymap, vk_state.mods);
141-
}
144+
let old_keymap = keyboard_handle.get_keymap().clone();
145+
let _ = keyboard_handle.set_keymap(user_data, &vk_state.keymap);
142146
let key_state = if state == 1 {
143147
KeyState::Pressed
144148
} else {
145149
KeyState::Released
146150
};
147-
user_data.on_keyboard_event((key + 8).into(), key_state, time, keyboard_handle);
151+
user_data.on_keyboard_event((key + 8).into(), key_state, time, keyboard_handle.clone());
152+
keyboard_handle.set_keymap(user_data, &old_keymap);
148153
}
149154
}
150155
zwp_virtual_keyboard_v1::Request::Modifiers {
@@ -171,15 +176,13 @@ where
171176

172177
// Ensure virtual keyboard's keymap is active.
173178
let keyboard_handle = data.seat.get_keyboard().unwrap();
179+
let old_keymap = keyboard_handle.get_keymap().clone();
180+
let _ = keyboard_handle.set_keymap(user_data, &state.keymap);
174181
{
175182
let mut internal = keyboard_handle.arc.internal.lock().unwrap();
176183
let focus = internal.focus.as_mut().map(|(focus, _)| focus);
177-
let keymap_changed =
178-
keyboard_handle.send_keymap(user_data, &focus, &state.keymap, state.mods);
179-
if !keymap_changed {
180-
if let Some(focus) = focus {
181-
focus.modifiers(&data.seat, user_data, state.mods, SERIAL_COUNTER.next_serial());
182-
}
184+
if let Some(focus) = focus {
185+
focus.modifiers(&data.seat, user_data, state.mods, SERIAL_COUNTER.next_serial());
183186
}
184187
}
185188
if ime_keyboard_grabbed.is_none()
@@ -189,9 +192,10 @@ where
189192
mods_depressed,
190193
mods_latched,
191194
mods_locked,
192-
keyboard_handle,
195+
keyboard_handle.clone(),
193196
);
194197
}
198+
keyboard_handle.set_keymap(user_data, &old_keymap);
195199
}
196200
zwp_virtual_keyboard_v1::Request::Destroy => {
197201
// Nothing to do
@@ -212,8 +216,13 @@ where
212216
/// Handle the zwp_virtual_keyboard_v1::keymap request.
213217
///
214218
/// The `true` returns when keymap was properly loaded.
215-
fn update_keymap<D>(data: &VirtualKeyboardUserData<D>, format: u32, fd: OwnedFd, size: usize)
216-
where
219+
fn update_keymap<D>(
220+
user_data: &mut D,
221+
data: &VirtualKeyboardUserData<D>,
222+
format: u32,
223+
fd: OwnedFd,
224+
size: usize,
225+
) where
217226
D: SeatHandler + 'static,
218227
{
219228
// Only libxkbcommon compatible keymaps are supported.
@@ -222,34 +231,27 @@ where
222231
return;
223232
}
224233

225-
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
226-
// SAFETY: we can map the keymap into the memory.
227-
let new_keymap = match unsafe {
228-
xkb::Keymap::new_from_fd(
229-
&context,
230-
fd,
231-
size,
232-
xkb::KEYMAP_FORMAT_TEXT_V1,
233-
xkb::KEYMAP_COMPILE_NO_FLAGS,
234-
)
235-
} {
236-
Ok(Some(new_keymap)) => new_keymap,
237-
Ok(None) => {
238-
debug!("Invalid libxkbcommon keymap");
239-
return;
240-
}
241-
Err(err) => {
242-
debug!("Could not map the keymap: {err:?}");
243-
return;
244-
}
234+
let map = unsafe {
235+
MmapOptions::new()
236+
.len(size as usize)
237+
.map_copy_read_only(&File::from(fd))
238+
.unwrap()
245239
};
246-
240+
let keymap_string = String::from_utf8_lossy(&map[..]).to_string();
247241
// Store active virtual keyboard map.
248242
let mut inner = data.handle.inner.lock().unwrap();
249243
let mods = inner.state.take().map(|state| state.mods).unwrap_or_default();
244+
let keyboard_handle = data.seat.get_keyboard().unwrap();
245+
let old_keymap = keyboard_handle.get_keymap().clone();
246+
let keymap = {
247+
let _ = keyboard_handle.set_keymap_from_string(user_data, keymap_string);
248+
keyboard_handle.get_keymap().clone()
249+
};
250+
let state = xkb::State::new(&keymap.inner);
250251
inner.state = Some(VirtualKeyboardState {
251252
mods,
252-
keymap: KeymapFile::new(&new_keymap),
253-
state: xkb::State::new(&new_keymap),
253+
keymap: keymap.clone(),
254+
state,
254255
});
256+
keyboard_handle.set_keymap(user_data, &old_keymap);
255257
}

0 commit comments

Comments
 (0)