diff options
author | Marius Vlad <marius.vlad@collabora.com> | 2022-08-30 20:25:01 +0300 |
---|---|---|
committer | Marius Vlad <marius.vlad@collabora.com> | 2022-09-02 15:45:11 +0300 |
commit | d6ab6da9887353056962343d9dcbfb9610ac889b (patch) | |
tree | b9b565471bc5d5fc5b0ca9eac1e0cf5f0f74157d | |
parent | 4cde507be6a116b3828f3a86a0e97639f04d9046 (diff) |
libweston/backend-x11: Tracking previous events over multiple calls
Rather than doing it with a local variable, track any previous events by
hanging it out of the x11 backend and use it to handle keymap notify
events.
In this way we avoid corrupting the surface destroy signal list, in
notify_keyboard_focus_out(), ultimately leading to a crash.
Fixes #649, #650
Suggested-by: Daniel Stone <daniel.stone@collabora.com>
Reported-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
-rw-r--r-- | libweston/backend-x11/x11.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/libweston/backend-x11/x11.c b/libweston/backend-x11/x11.c index f887961e..34820a06 100644 --- a/libweston/backend-x11/x11.c +++ b/libweston/backend-x11/x11.c @@ -119,6 +119,7 @@ struct x11_backend { xcb_atom_t cardinal; xcb_atom_t xkb_names; } atom; + xcb_generic_event_t *prev_event; }; struct x11_head { @@ -1494,7 +1495,7 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) { struct x11_backend *b = data; struct x11_output *output; - xcb_generic_event_t *event, *prev; + xcb_generic_event_t *event; xcb_client_message_event_t *client_message; xcb_enter_notify_event_t *enter_notify; xcb_key_press_event_t *key_press, *key_release; @@ -1510,16 +1511,15 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) int count; struct timespec time; - prev = NULL; count = 0; while (x11_backend_next_event(b, &event, mask)) { response_type = event->response_type & ~0x80; - switch (prev ? prev->response_type & ~0x80 : 0x80) { + switch (b->prev_event ? b->prev_event->response_type & ~0x80 : 0x80) { case XCB_KEY_RELEASE: /* Suppress key repeat events; this is only used if we * don't have XCB XKB support. */ - key_release = (xcb_key_press_event_t *) prev; + key_release = (xcb_key_press_event_t *) b->prev_event; key_press = (xcb_key_press_event_t *) event; if (response_type == XCB_KEY_PRESS && key_release->time == key_press->time && @@ -1527,8 +1527,8 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) /* Don't deliver the held key release * event or the new key press event. */ free(event); - free(prev); - prev = NULL; + free(b->prev_event); + b->prev_event = NULL; continue; } else { /* Deliver the held key release now @@ -1541,8 +1541,8 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) key_release->detail - 8, WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_AUTOMATIC); - free(prev); - prev = NULL; + free(b->prev_event); + b->prev_event = NULL; break; } @@ -1566,8 +1566,8 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) notify_keyboard_focus_in(&b->core_seat, &b->keys, STATE_UPDATE_AUTOMATIC); - free(prev); - prev = NULL; + free(b->prev_event); + b->prev_event = NULL; break; default: @@ -1592,7 +1592,7 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) /* If we don't have XKB, we need to use the lame * autorepeat detection above. */ if (!b->has_xkb) { - prev = event; + b->prev_event = event; break; } key_release = (xcb_key_press_event_t *) event; @@ -1687,7 +1687,7 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED) break; - prev = event; + b->prev_event = event; break; case XCB_FOCUS_OUT: @@ -1721,13 +1721,13 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) #endif count++; - if (prev != event) - free (event); + if (b->prev_event != event) + free(event); } - switch (prev ? prev->response_type & ~0x80 : 0x80) { + switch (b->prev_event ? b->prev_event->response_type & ~0x80 : 0x80) { case XCB_KEY_RELEASE: - key_release = (xcb_key_press_event_t *) prev; + key_release = (xcb_key_press_event_t *) b->prev_event; update_xkb_state_from_core(b, key_release->state); weston_compositor_get_time(&time); notify_key(&b->core_seat, @@ -1735,8 +1735,8 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) key_release->detail - 8, WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_AUTOMATIC); - free(prev); - prev = NULL; + free(b->prev_event); + b->prev_event = NULL; break; default: break; |