From b86d8d73e8dd6574fc04d5d02b61ce4a24aab5b2 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 19 Apr 2019 01:56:53 +0100 Subject: [PATCH] x: add x_discard_events Also, during session_init, discard old events after we grab the server. If we don't do that, old, out dated CreateNotify will cause us to add the window with the same id multiple times. Here is an explanation of how that could happen: 1. compton connects to X 2. a new window created by someone else, X send us a CreateNotify 3. compton is initializing, so it didn't handle the event. 4. compton pulls a list of all windows from X. This will include that window created in (2) 5. compton starts to handle event. it will handle the CreateNotify sent in (2), thus adds the same window twice. Signed-off-by: Yuxuan Shui --- src/compton.c | 6 ++++++ src/x.h | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/src/compton.c b/src/compton.c index ab4a702e..ffa68844 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2039,6 +2039,12 @@ static session_t *session_init(int argc, char **argv, Display *dpy, xcb_grab_server(ps->c); + // We are going to pull latest information from X server now, events sent by X + // earlier is irrelavant at this point. + // A better solution is probably grabbing the server from the very start. But I + // think there still could be race condition that mandates discarding the events. + x_discard_events(ps->c); + // Initialize DBus. We need to do this early, because add_win might call dbus // functions if (ps->o.dbus) { diff --git a/src/x.h b/src/x.h index df281428..fbaa2fdf 100644 --- a/src/x.h +++ b/src/x.h @@ -110,6 +110,15 @@ static inline winprop_t wid_get_prop(const session_t *ps, xcb_window_t wid, xcb_ return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat); } +/// Discard all X events in queue or in flight. Should only be used when the server is +/// grabbed +static inline void x_discard_events(xcb_connection_t *c) { + xcb_generic_event_t *e; + while ((e = xcb_poll_for_event(c))) { + free(e); + } +} + /** * Get the value of a type-xcb_window_t property of a window. *