input: don't reset the XKB compose state in keymap()

When the compositor sends a new keymap, don't reset the XKB compose
state.

This is done by initializing the XKB context, along with the compose
state, when binding the seat, instead of in keymap().

Then, in keymap(), simply stop destroying the old xkb state. Only
destroy, and re-create the keymap state.

Closes #1744
This commit is contained in:
Daniel Eklöf 2024-06-22 07:58:43 +02:00
parent aea16ba5d2
commit c45231ef89
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 22 additions and 27 deletions

View file

@ -95,11 +95,14 @@
* IME interfering in URL-mode ([#1718][1718]).
* OSC-52 reply interleaved with other data sent to the client
([#1734][1734]).
* XKB compose state being reset when foot receives a new keymap
([#1744][1744]).
[1694]: https://codeberg.org/dnkl/foot/issues/1694
[1717]: https://codeberg.org/dnkl/foot/issues/1717
[1718]: https://codeberg.org/dnkl/foot/issues/1718
[1734]: https://codeberg.org/dnkl/foot/issues/1734
[1744]: https://codeberg.org/dnkl/foot/issues/1744
### Security

24
input.c
View file

@ -513,14 +513,6 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
* Free old keymap state
*/
if (seat->kbd.xkb_compose_state != NULL) {
xkb_compose_state_unref(seat->kbd.xkb_compose_state);
seat->kbd.xkb_compose_state = NULL;
}
if (seat->kbd.xkb_compose_table != NULL) {
xkb_compose_table_unref(seat->kbd.xkb_compose_table);
seat->kbd.xkb_compose_table = NULL;
}
if (seat->kbd.xkb_keymap != NULL) {
xkb_keymap_unref(seat->kbd.xkb_keymap);
seat->kbd.xkb_keymap = NULL;
@ -529,10 +521,6 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
xkb_state_unref(seat->kbd.xkb_state);
seat->kbd.xkb_state = NULL;
}
if (seat->kbd.xkb != NULL) {
xkb_context_unref(seat->kbd.xkb);
seat->kbd.xkb = NULL;
}
key_binding_unload_keymap(wayl->key_binding_manager, seat);
@ -559,23 +547,11 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
while (map_str[size - 1] == '\0')
size--;
seat->kbd.xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (seat->kbd.xkb != NULL) {
seat->kbd.xkb_keymap = xkb_keymap_new_from_buffer(
seat->kbd.xkb, map_str, size, XKB_KEYMAP_FORMAT_TEXT_V1,
XKB_KEYMAP_COMPILE_NO_FLAGS);
/* Compose (dead keys) */
seat->kbd.xkb_compose_table = xkb_compose_table_new_from_locale(
seat->kbd.xkb, setlocale(LC_CTYPE, NULL), XKB_COMPOSE_COMPILE_NO_FLAGS);
if (seat->kbd.xkb_compose_table == NULL) {
LOG_WARN("failed to instantiate compose table; dead keys will not work");
} else {
seat->kbd.xkb_compose_state = xkb_compose_state_new(
seat->kbd.xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
}
}
if (seat->kbd.xkb_keymap != NULL) {

View file

@ -1,11 +1,12 @@
#include "wayland.h"
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <fcntl.h>
#include <sys/timerfd.h>
#include <sys/epoll.h>
@ -13,6 +14,8 @@
#include <cursor-shape-v1.h>
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <tllist.h>
@ -1195,6 +1198,19 @@ handle_global(void *data, struct wl_registry *registry,
return;
}
seat->kbd.xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (seat->kbd.xkb != NULL) {
seat->kbd.xkb_compose_table = xkb_compose_table_new_from_locale(
seat->kbd.xkb, setlocale(LC_CTYPE, NULL), XKB_COMPOSE_COMPILE_NO_FLAGS);
if (seat->kbd.xkb_compose_table != NULL) {
seat->kbd.xkb_compose_state = xkb_compose_state_new(
seat->kbd.xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
} else {
LOG_WARN("failed to instantiate compose table; dead keys (compose) will not work");
}
}
seat_add_data_device(seat);
seat_add_primary_selection(seat);
seat_add_text_input(seat);