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
master
Isaac Freund 5 years ago committed by Drew DeVault
parent e0bbafc253
commit 3f617631cb

@ -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…
Cancel
Save