mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-26 14:45:58 +01:00
Send keyboard enter/leave on capability change
This is more correct according to the protocol and fixes issues with clients that wait for an enter event before processing key events
This commit is contained in:
parent
e0bbafc253
commit
3f617631cb
3 changed files with 50 additions and 10 deletions
|
@ -15,6 +15,8 @@ void seat_client_destroy_pointer(struct wl_resource *resource);
|
||||||
void seat_client_create_keyboard(struct wlr_seat_client *seat_client,
|
void seat_client_create_keyboard(struct wlr_seat_client *seat_client,
|
||||||
uint32_t version, uint32_t id);
|
uint32_t version, uint32_t id);
|
||||||
void seat_client_destroy_keyboard(struct wl_resource *resource);
|
void seat_client_destroy_keyboard(struct wl_resource *resource);
|
||||||
|
void seat_client_send_keyboard_leave_raw(struct wlr_seat_client *seat_client,
|
||||||
|
struct wlr_surface *surface);
|
||||||
|
|
||||||
void seat_client_create_touch(struct wlr_seat_client *seat_client,
|
void seat_client_create_touch(struct wlr_seat_client *seat_client,
|
||||||
uint32_t version, uint32_t id);
|
uint32_t version, uint32_t id);
|
||||||
|
|
|
@ -322,6 +322,19 @@ void wlr_seat_set_capabilities(struct wlr_seat *wlr_seat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) == 0) {
|
if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) == 0) {
|
||||||
|
struct wlr_seat_client *focused_client =
|
||||||
|
wlr_seat->keyboard_state.focused_client;
|
||||||
|
struct wlr_surface *focused_surface =
|
||||||
|
wlr_seat->keyboard_state.focused_surface;
|
||||||
|
|
||||||
|
if (focused_client != NULL && focused_surface != NULL) {
|
||||||
|
seat_client_send_keyboard_leave_raw(focused_client,
|
||||||
|
focused_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: we don't set focused client/surface to NULL since we need
|
||||||
|
// them to send the enter event if the keyboard is recreated
|
||||||
|
|
||||||
struct wl_resource *resource, *tmp;
|
struct wl_resource *resource, *tmp;
|
||||||
wl_resource_for_each_safe(resource, tmp, &client->keyboards) {
|
wl_resource_for_each_safe(resource, tmp, &client->keyboards) {
|
||||||
seat_client_destroy_keyboard(resource);
|
seat_client_destroy_keyboard(resource);
|
||||||
|
|
|
@ -218,6 +218,18 @@ void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seat_client_send_keyboard_leave_raw(struct wlr_seat_client *seat_client,
|
||||||
|
struct wlr_surface *surface) {
|
||||||
|
uint32_t serial = wlr_seat_client_next_serial(seat_client);
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &seat_client->keyboards) {
|
||||||
|
if (seat_client_from_keyboard_resource(resource) == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wl_keyboard_send_leave(resource, serial, surface->resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_seat_keyboard_enter(struct wlr_seat *seat,
|
void wlr_seat_keyboard_enter(struct wlr_seat *seat,
|
||||||
struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
|
struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
|
||||||
struct wlr_keyboard_modifiers *modifiers) {
|
struct wlr_keyboard_modifiers *modifiers) {
|
||||||
|
@ -240,14 +252,7 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat,
|
||||||
|
|
||||||
// leave the previously entered surface
|
// leave the previously entered surface
|
||||||
if (focused_client != NULL && focused_surface != NULL) {
|
if (focused_client != NULL && focused_surface != NULL) {
|
||||||
uint32_t serial = wlr_seat_client_next_serial(focused_client);
|
seat_client_send_keyboard_leave_raw(focused_client, focused_surface);
|
||||||
struct wl_resource *resource;
|
|
||||||
wl_resource_for_each(resource, &focused_client->keyboards) {
|
|
||||||
if (seat_client_from_keyboard_resource(resource) == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wl_keyboard_send_leave(resource, serial, focused_surface->resource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter the current surface
|
// enter the current surface
|
||||||
|
@ -409,8 +414,28 @@ void seat_client_create_keyboard(struct wlr_seat_client *seat_client,
|
||||||
seat_client_send_keymap(seat_client, keyboard);
|
seat_client_send_keymap(seat_client, keyboard);
|
||||||
seat_client_send_repeat_info(seat_client, keyboard);
|
seat_client_send_repeat_info(seat_client, keyboard);
|
||||||
|
|
||||||
// TODO possibly handle the case where this keyboard needs an enter
|
struct wlr_seat_client *focused_client =
|
||||||
// right away
|
seat_client->seat->keyboard_state.focused_client;
|
||||||
|
struct wlr_surface *focused_surface =
|
||||||
|
seat_client->seat->keyboard_state.focused_surface;
|
||||||
|
|
||||||
|
// Send an enter event if there is a focused client/surface stored
|
||||||
|
if (focused_client != NULL && focused_surface != NULL) {
|
||||||
|
struct wl_array keys;
|
||||||
|
wl_array_init(&keys);
|
||||||
|
uint32_t serial = wlr_seat_client_next_serial(focused_client);
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &focused_client->keyboards) {
|
||||||
|
if (wl_resource_get_id(resource) == id) {
|
||||||
|
if (seat_client_from_keyboard_resource(resource) == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wl_keyboard_send_enter(resource, serial,
|
||||||
|
focused_surface->resource, &keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wl_array_release(&keys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void seat_client_destroy_keyboard(struct wl_resource *resource) {
|
void seat_client_destroy_keyboard(struct wl_resource *resource) {
|
||||||
|
|
Loading…
Reference in a new issue