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 <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-04-19 01:56:53 +01:00
parent 0c992b11d3
commit 883d8c9142
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
2 changed files with 15 additions and 0 deletions

View File

@ -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) {

View File

@ -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-<code>xcb_window_t</code> property of a window.
*