Identify virtual keyboard groups by their source
60828505ae327f4cc1a6cd1d858548a2cc5d07eb
1 parent
2f656d6c
swm.c
+9 -11
| 254 | 254 | } key_t; |
|
| 255 | 255 | ||
| 256 | 256 | /* Physical or virtual keyboard group. */ |
|
| 257 | 257 | typedef struct { |
|
| 258 | 258 | struct wlr_keyboard_group *wlr_group; |
|
| 259 | - | bool is_virtual; |
|
| 260 | - | struct wlr_virtual_keyboard_v1 *virtual_keyboard; /* Source of a virtual group. */ |
|
| 259 | + | struct wlr_virtual_keyboard_v1 *virtual_keyboard; /* Null for the physical keyboard group. */ |
|
| 261 | 260 | int nsyms; |
|
| 262 | 261 | uint32_t repeat_keycode; /* Valid only when nsyms is nonzero. */ |
|
| 263 | 262 | const xkb_keysym_t *keysyms; /* Valid only when nsyms is nonzero. */ |
|
| 264 | 263 | uint32_t mods; /* Valid only when nsyms is nonzero. */ |
|
| 265 | 264 | struct wl_event_source *key_repeat_source; |
| 492 | 491 | static void popup_commit(struct wl_listener *listener, void *data); |
|
| 493 | 492 | static void popup_destroy(struct wl_listener *listener, void *data); |
|
| 494 | 493 | static void create_decoration(struct wl_listener *listener, void *data); |
|
| 495 | 494 | static void create_idle_inhibitor(struct wl_listener *listener, void *data); |
|
| 496 | 495 | static void create_keyboard(struct wlr_keyboard *keyboard); |
|
| 497 | - | static keyboard_group_t *create_keyboard_group(bool is_virtual); |
|
| 496 | + | static keyboard_group_t *create_keyboard_group(struct wlr_virtual_keyboard_v1 *virtual_keyboard); |
|
| 498 | 497 | static void create_layer_surface(struct wl_listener *listener, void *data); |
|
| 499 | 498 | static void create_lock_surface(struct wl_listener *listener, void *data); |
|
| 500 | 499 | static void create_monitor(struct wl_listener *listener, void *data); |
|
| 501 | 500 | static void create_notify(struct wl_listener *listener, void *data); |
|
| 502 | 501 | static void create_pointer(struct wlr_pointer *pointer); |
| 2508 | 2507 | /* Add the keyboard to the shared group. */ |
|
| 2509 | 2508 | wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard); |
|
| 2510 | 2509 | } |
|
| 2511 | 2510 | ||
| 2512 | 2511 | /* Create a keyboard group with the configured key map and repeat settings. */ |
|
| 2513 | - | keyboard_group_t *create_keyboard_group(bool is_virtual) { |
|
| 2512 | + | keyboard_group_t *create_keyboard_group(struct wlr_virtual_keyboard_v1 *virtual_keyboard) { |
|
| 2514 | 2513 | keyboard_group_t *group = pool_take(&keyboard_group_pool); |
|
| 2515 | 2514 | struct xkb_context *context; |
|
| 2516 | 2515 | struct xkb_keymap *keymap; |
|
| 2517 | 2516 | ||
| 2518 | 2517 | if (!group) |
| 2521 | 2520 | ||
| 2522 | 2521 | if (!group->wlr_group) { |
|
| 2523 | 2522 | pool_release(&keyboard_group_pool, group); |
|
| 2524 | 2523 | return nullptr; |
|
| 2525 | 2524 | } |
|
| 2526 | - | group->wlr_group->data = group; |
|
| 2527 | - | group->is_virtual = is_virtual; |
|
| 2525 | + | group->wlr_group->data = group; |
|
| 2526 | + | group->virtual_keyboard = virtual_keyboard; |
|
| 2528 | 2527 | ||
| 2529 | 2528 | /* Prepare an XKB keymap and assign it to the keyboard group. */ |
|
| 2530 | 2529 | context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); |
|
| 2531 | 2530 | ||
| 2532 | 2531 | if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS))) |
| 2544 | 2543 | ||
| 2545 | 2544 | group->key_repeat_source = wl_event_loop_add_timer(event_loop, key_repeat, group); |
|
| 2546 | 2545 | ||
| 2547 | 2546 | /* Wayland exposes one active keyboard per seat, so combine physical |
|
| 2548 | 2547 | * keyboards into one group. */ |
|
| 2549 | - | if (!is_virtual) |
|
| 2548 | + | if (!virtual_keyboard) |
|
| 2550 | 2549 | wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); |
|
| 2551 | 2550 | return group; |
|
| 2552 | 2551 | } |
|
| 2553 | 2552 | ||
| 2554 | 2553 | /* Choose the layer that contains popups belonging to a layer-shell surface. */ |
| 3100 | 3099 | void destroy_keyboard_group(struct wl_listener *listener, void *data) { |
|
| 3101 | 3100 | keyboard_group_t *group = wl_container_of(listener, group, destroy); |
|
| 3102 | 3101 | int was_current = wlr_seat_get_keyboard(seat) == &group->wlr_group->keyboard; |
|
| 3103 | 3102 | bool is_main = group == kb_group; |
|
| 3104 | 3103 | ||
| 3105 | - | if (group->is_virtual) |
|
| 3104 | + | if (group->virtual_keyboard) |
|
| 3106 | 3105 | virtual_keyboards--; |
|
| 3107 | 3106 | wl_event_source_remove(group->key_repeat_source); |
|
| 3108 | 3107 | wl_list_remove(&group->key.link); |
|
| 3109 | 3108 | wl_list_remove(&group->modifiers.link); |
|
| 3110 | 3109 | wl_list_remove(&group->destroy.link); |
| 6399 | 6398 | im_mgr = wlr_input_method_manager_v2_create(dpy); |
|
| 6400 | 6399 | listen_global(&im_mgr->events.new_input_method, &new_input_method); |
|
| 6401 | 6400 | ti_mgr = wlr_text_input_manager_v3_create(dpy); |
|
| 6402 | 6401 | listen_global(&ti_mgr->events.new_text_input, &new_text_input); |
|
| 6403 | 6402 | ||
| 6404 | - | kb_group = create_keyboard_group(false); |
|
| 6403 | + | kb_group = create_keyboard_group(nullptr); |
|
| 6405 | 6404 | ||
| 6406 | 6405 | if (!kb_group) |
|
| 6407 | 6406 | die("failed to allocate primary keyboard group"); |
|
| 6408 | 6407 | wl_list_init(&kb_group->destroy.link); |
|
| 6409 | 6408 |
| 6943 | 6942 | /* Create an independent keyboard group for a virtual keyboard. */ |
|
| 6944 | 6943 | void virtual_keyboard(struct wl_listener *listener, void *data) { |
|
| 6945 | 6944 | struct wlr_virtual_keyboard_v1 *kb = data; |
|
| 6946 | 6945 | ||
| 6947 | 6946 | /* Give each virtual keyboard its own group. */ |
|
| 6948 | - | keyboard_group_t *group = create_keyboard_group(true); |
|
| 6947 | + | keyboard_group_t *group = create_keyboard_group(kb); |
|
| 6949 | 6948 | ||
| 6950 | 6949 | if (!group) { |
|
| 6951 | 6950 | wl_resource_post_no_memory(kb->resource); |
|
| 6952 | 6951 | return; |
|
| 6953 | 6952 | } |
|
| 6954 | 6953 | /* Use the virtual keyboard's key mapping. */ |
|
| 6955 | - | group->virtual_keyboard = kb; |
|
| 6956 | 6954 | wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap); |
|
| 6957 | 6955 | LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, destroy_keyboard_group); |
|
| 6958 | 6956 | ||
| 6959 | 6957 | /* Add the virtual keyboard to its group. */ |
|
| 6960 | 6958 | wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard); |