summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2022-08-30 20:25:01 +0300
committerMarius Vlad <marius.vlad@collabora.com>2022-09-02 15:45:11 +0300
commitd6ab6da9887353056962343d9dcbfb9610ac889b (patch)
treeb9b565471bc5d5fc5b0ca9eac1e0cf5f0f74157d
parent4cde507be6a116b3828f3a86a0e97639f04d9046 (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.c36
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;