]> git.mdlowis.com Git - proto/labwc.git/commitdiff
keyboard: set keyboard layout on reconfigure
authorSimon Long <simon@raspberrypi.com>
Tue, 16 Jan 2024 12:43:18 +0000 (12:43 +0000)
committerJohan Malm <johanmalm@users.noreply.github.com>
Fri, 19 Jan 2024 18:59:14 +0000 (18:59 +0000)
If keyboard-layout-per-toplevel-window is used, reset the group (index)
for each window on --reconfigure whenever the keymap has changed.

Refactor to use a common configure function for reconfigure and
keyboard-group creation.

Co-authored-by: @johanmalm
Fixes #1407

include/input/keyboard.h
src/input/input.c
src/input/keyboard.c
src/seat.c
src/server.c

index 38d82b7ad308877a5671e2c4a492ed8370c16a87..ff4fbe60d35ac09335151c00f1c6e3f73e6355ae 100644 (file)
@@ -9,8 +9,11 @@ struct seat;
 struct keyboard;
 struct wlr_keyboard;
 
-void keyboard_init(struct seat *seat);
-void keyboard_finish(struct seat *seat);
+void keyboard_configure(struct seat *seat, struct wlr_keyboard *kb,
+       bool is_virtual);
+
+void keyboard_group_init(struct seat *seat);
+void keyboard_group_finish(struct seat *seat);
 
 void keyboard_setup_handlers(struct keyboard *keyboard);
 void keyboard_set_numlock(struct wlr_keyboard *keyboard);
index ef55ca6910f2ab7bc977f4193ae1a9e22d775564..d78dca1ac6731e44cc334a3011e363bbeac56c32 100644 (file)
@@ -7,12 +7,12 @@ void
 input_handlers_init(struct seat *seat)
 {
        cursor_init(seat);
-       keyboard_init(seat);
+       keyboard_group_init(seat);
 }
 
 void
 input_handlers_finish(struct seat *seat)
 {
        cursor_finish(seat);
-       keyboard_finish(seat);
+       keyboard_group_finish(seat);
 }
index 498596277b22e6aaed7c5d4ba4e49b0847937739..7379a540545ccd838dcb98661a2b423a725208b2 100644 (file)
@@ -592,27 +592,74 @@ keyboard_update_layout(struct seat *seat, xkb_layout_index_t layout)
                kb->modifiers.latched, kb->modifiers.locked, layout);
 }
 
-void
-keyboard_init(struct seat *seat)
+static void
+reset_window_keyboard_layout_groups(struct server *server)
+{
+       if (!rc.kb_layout_per_window) {
+               return;
+       }
+
+       /*
+        * Technically it would be possible to reconcile previous group indices
+        * to new group ones if particular layouts exist in both old and new,
+        * but let's keep it simple for now and just reset them all.
+        */
+       struct view *view;
+       for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NONE) {
+               view->keyboard_layout = 0;
+       }
+
+       struct view *active_view = server->active_view;
+       if (!active_view) {
+               return;
+       }
+       keyboard_update_layout(&server->seat, active_view->keyboard_layout);
+}
+
+/*
+ * Set layout based on environment variables XKB_DEFAULT_LAYOUT,
+ * XKB_DEFAULT_OPTIONS, and friends.
+ */
+static void
+set_layout(struct server *server, struct wlr_keyboard *kb)
 {
-       seat->keyboard_group = wlr_keyboard_group_create();
-       struct wlr_keyboard *kb = &seat->keyboard_group->keyboard;
        struct xkb_rule_names rules = { 0 };
        struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
        struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
                XKB_KEYMAP_COMPILE_NO_FLAGS);
        if (keymap) {
-               wlr_keyboard_set_keymap(kb, keymap);
+               if (!wlr_keyboard_keymaps_match(kb->keymap, keymap)) {
+                       wlr_keyboard_set_keymap(kb, keymap);
+                       reset_window_keyboard_layout_groups(server);
+               }
                xkb_keymap_unref(keymap);
        } else {
                wlr_log(WLR_ERROR, "Failed to create xkb keymap");
        }
        xkb_context_unref(context);
-       wlr_keyboard_set_repeat_info(kb, rc.repeat_rate, rc.repeat_delay);
+}
 
+void
+keyboard_configure(struct seat *seat, struct wlr_keyboard *kb, bool is_virtual)
+{
+       if (!is_virtual) {
+               set_layout(seat->server, kb);
+       }
+       wlr_keyboard_set_repeat_info(kb, rc.repeat_rate, rc.repeat_delay);
        keybind_update_keycodes(seat->server);
 }
 
+void
+keyboard_group_init(struct seat *seat)
+{
+       if (seat->keyboard_group) {
+               return;
+       }
+       seat->keyboard_group = wlr_keyboard_group_create();
+       keyboard_configure(seat, &seat->keyboard_group->keyboard,
+               /* is_virtual */ false);
+}
+
 void
 keyboard_setup_handlers(struct keyboard *keyboard)
 {
@@ -625,7 +672,7 @@ keyboard_setup_handlers(struct keyboard *keyboard)
 }
 
 void
-keyboard_finish(struct seat *seat)
+keyboard_group_finish(struct seat *seat)
 {
        /*
         * All keyboard listeners must be removed before this to avoid use after
index 594cdde9f343bdbd2c3dedf7378338ef9e03cb41..36ecb5d37e4a585adf193d6cc24287069130bcce 100644 (file)
@@ -506,13 +506,16 @@ seat_finish(struct server *server)
 }
 
 static void
-configure_keyboard(struct wlr_input_device *device)
+configure_keyboard(struct seat *seat, struct input *input)
 {
+       struct wlr_input_device *device = input->wlr_input_device;
        assert(device->type == WLR_INPUT_DEVICE_KEYBOARD);
+       struct keyboard *keyboard = (struct keyboard *)input;
        struct wlr_keyboard *kb = wlr_keyboard_from_input_device(device);
-       wlr_keyboard_set_repeat_info(kb, rc.repeat_rate, rc.repeat_delay);
+       keyboard_configure(seat, kb, keyboard->is_virtual);
 }
 
+/* This is called on SIGHUP (generally in response to labwc --reconfigure */
 void
 seat_reconfigure(struct server *server)
 {
@@ -521,7 +524,7 @@ seat_reconfigure(struct server *server)
        wl_list_for_each(input, &seat->inputs, link) {
                switch (input->wlr_input_device->type) {
                case WLR_INPUT_DEVICE_KEYBOARD:
-                       configure_keyboard(input->wlr_input_device);
+                       configure_keyboard(seat, input);
                        break;
                case WLR_INPUT_DEVICE_POINTER:
                        configure_libinput(input->wlr_input_device);
index cd3b62026a35c7fdb8ab2dfc4ef66e4f4c728156..c0ee76827e3f65b7a443a24ac9a69360b6d68767 100644 (file)
@@ -61,7 +61,6 @@ reload_config_and_theme(void)
        regions_reconfigure(g_server);
        resize_indicator_reconfigure(g_server);
        kde_server_decoration_update_default();
-       keybind_update_keycodes(g_server);
 }
 
 static int