mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-24 08:02:21 +00:00
input-method-v2: set no keymap format if no keymap is set
Also don't copy the keymap each time it gets sent to a client
This commit is contained in:
parent
04525e6f82
commit
bf0cac12a3
@ -1,4 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
@ -306,34 +307,30 @@ void wlr_input_method_keyboard_grab_v2_send_modifiers(
|
||||
modifiers->locked, modifiers->group);
|
||||
}
|
||||
|
||||
static bool keyboard_grab_send_keymap(
|
||||
static void keyboard_grab_send_keymap(
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab,
|
||||
struct wlr_keyboard *keyboard) {
|
||||
int keymap_fd = allocate_shm_file(keyboard->keymap_size);
|
||||
if (keymap_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "creating a keymap file for %zu bytes failed",
|
||||
keyboard->keymap_size);
|
||||
return false;
|
||||
enum wl_keyboard_keymap_format format;
|
||||
int fd, devnull = -1;
|
||||
if (keyboard->keymap != NULL) {
|
||||
format = WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1;
|
||||
fd = keyboard->keymap_fd;
|
||||
} else {
|
||||
format = WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP;
|
||||
devnull = open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
if (devnull < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open /dev/null");
|
||||
return;
|
||||
}
|
||||
fd = devnull;
|
||||
}
|
||||
|
||||
void *ptr = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, keymap_fd, 0);
|
||||
if (ptr == MAP_FAILED) {
|
||||
wlr_log(WLR_ERROR, "failed to mmap() %zu bytes",
|
||||
keyboard->keymap_size);
|
||||
close(keymap_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ptr, keyboard->keymap_string, keyboard->keymap_size);
|
||||
munmap(ptr, keyboard->keymap_size);
|
||||
|
||||
zwp_input_method_keyboard_grab_v2_send_keymap(keyboard_grab->resource,
|
||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd,
|
||||
keyboard->keymap_size);
|
||||
format, fd, keyboard->keymap_size);
|
||||
|
||||
close(keymap_fd);
|
||||
return true;
|
||||
if (devnull >= 0) {
|
||||
close(devnull);
|
||||
}
|
||||
}
|
||||
|
||||
static void keyboard_grab_send_repeat_info(
|
||||
@ -379,15 +376,12 @@ void wlr_input_method_keyboard_grab_v2_set_keyboard(
|
||||
|
||||
if (keyboard) {
|
||||
if (keyboard_grab->keyboard == NULL ||
|
||||
strcmp(keyboard_grab->keyboard->keymap_string,
|
||||
keyboard->keymap_string) != 0) {
|
||||
// send keymap only if it is changed, or if input method is not
|
||||
// aware that it did not change and blindly send it back with
|
||||
// virtual keyboard, it may cause an infinite recursion.
|
||||
if (!keyboard_grab_send_keymap(keyboard_grab, keyboard)) {
|
||||
wlr_log(WLR_ERROR, "Failed to send keymap for input-method keyboard grab");
|
||||
return;
|
||||
}
|
||||
!wlr_keyboard_keymaps_match(keyboard_grab->keyboard->keymap,
|
||||
keyboard->keymap)) {
|
||||
// Only send keymap if it changed, otherwise if the input-method
|
||||
// client sent back the same keymap with virtual-keyboard, it would
|
||||
// result in an infinite loop of keymap updates.
|
||||
keyboard_grab_send_keymap(keyboard_grab, keyboard);
|
||||
}
|
||||
keyboard_grab_send_repeat_info(keyboard_grab, keyboard);
|
||||
keyboard_grab->keyboard_keymap.notify = handle_keyboard_keymap;
|
||||
|
Loading…
Reference in New Issue
Block a user