diff --git a/backend/x11/backend.c b/backend/x11/backend.c index a218c589..f6f9cfa8 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -244,6 +244,17 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { struct wlr_x11_output *output = &x11->output; wlr_output_destroy(&output->wlr_output); + wl_signal_emit(&backend->events.input_remove, &x11->pointer_dev); + wl_signal_emit(&backend->events.input_remove, &x11->keyboard_dev); + // TODO probably need to use wlr_keyboard_destroy, but the devices need to + // be malloced for that to work + if (x11->keyboard_dev.keyboard->keymap) { + xkb_keymap_unref(x11->keyboard_dev.keyboard->keymap); + } + if (x11->keyboard_dev.keyboard->xkb_state) { + xkb_state_unref(x11->keyboard_dev.keyboard->xkb_state); + } + wl_list_remove(&x11->display_destroy.link); wl_event_source_remove(x11->frame_timer); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 758a49fb..16071c0c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -364,6 +364,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, } wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); int repeat_rate = (config->repeat_rate > 0) ? config->repeat_rate : 25; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index ef577e01..5ec8c043 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -118,7 +118,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *kb) { wl_list_remove(&kb->events.key.listener_list); } xkb_state_unref(kb->xkb_state); - xkb_map_unref(kb->keymap); + xkb_keymap_unref(kb->keymap); close(kb->keymap_fd); free(kb); } @@ -131,12 +131,21 @@ void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap) { + if (kb->keymap) { + xkb_keymap_unref(kb->keymap); + } + xkb_keymap_ref(keymap); + kb->keymap = keymap; + + if (kb->xkb_state) { + xkb_state_unref(kb->xkb_state); + } + kb->xkb_state = xkb_state_new(kb->keymap); if (kb->xkb_state == NULL) { wlr_log(L_ERROR, "Failed to create XKB state"); return; } - kb->keymap = keymap; const char *led_names[WLR_LED_COUNT] = { XKB_LED_NAME_NUM, @@ -165,9 +174,18 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, char *keymap_str = xkb_keymap_get_as_string(kb->keymap, XKB_KEYMAP_FORMAT_TEXT_V1); kb->keymap_size = strlen(keymap_str) + 1; + if (kb->keymap_fd) { + close(kb->keymap_fd); + } kb->keymap_fd = os_create_anonymous_file(kb->keymap_size); + if (kb->keymap_fd < 0) { + wlr_log(L_ERROR, "creating a keymap file for %lu bytes failed", kb->keymap_size); + } void *ptr = mmap(NULL, kb->keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0); + if (ptr == (void*)-1) { + wlr_log(L_ERROR, "failed to mmap() %lu bytes", kb->keymap_size); + } strcpy(ptr, keymap_str); free(keymap_str); diff --git a/types/wlr_output.c b/types/wlr_output.c index 923f8f52..f7b88444 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -301,6 +301,8 @@ void wlr_output_destroy(struct wlr_output *output) { } else { free(output); } + + wl_list_remove(&output->display_destroy.link); } void wlr_output_effective_resolution(struct wlr_output *output, diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 2a931241..25b1fcd4 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -710,8 +710,11 @@ static void handle_keyboard_keymap(struct wl_listener *listener, void *data) { struct wlr_seat_keyboard_state *state = wl_container_of(listener, state, keyboard_keymap); struct wlr_seat_client *client; - wl_list_for_each(client, &state->seat->clients, link) { - seat_client_send_keymap(client, state->keyboard); + struct wlr_keyboard *keyboard = data; + if (keyboard == state->keyboard) { + wl_list_for_each(client, &state->seat->clients, link) { + seat_client_send_keymap(client, state->keyboard); + } } } @@ -736,7 +739,8 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat, // TODO call this on device key event before the event reaches the // compositor and set a pending keyboard and then send the new keyboard // state on the next keyboard notify event. - if (seat->keyboard_state.keyboard == device->keyboard) { + struct wlr_keyboard *keyboard = (device ? device->keyboard : NULL); + if (seat->keyboard_state.keyboard == keyboard) { return; } @@ -747,7 +751,7 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat, seat->keyboard_state.keyboard = NULL; } - if (device) { + if (keyboard) { assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); wl_signal_add(&device->events.destroy, @@ -767,8 +771,9 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat, seat_client_send_repeat_info(client, device->keyboard); } - seat->keyboard_state.keyboard = device->keyboard; } + + seat->keyboard_state.keyboard = keyboard; } void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat,