extern int randr_base;
+/**
+ * Adds the given sequence to the list of events which are ignored.
+ * If this ignore should only affect a specific response_type, pass
+ * response_type, otherwise, pass -1.
+ *
+ * Every ignored sequence number gets garbage collected after 5 seconds.
+ *
+ */
void add_ignore_event(const int sequence, const int response_type);
+/**
+ * Checks if the given sequence is ignored and returns true if so.
+ *
+ */
+bool event_is_ignored(const int sequence, const int response_type);
+
/**
* Takes an xcb_generic_event_t and calls the appropriate handler, based on the
* event type.
changing workspaces */
static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
+/*
+ * Adds the given sequence to the list of events which are ignored.
+ * If this ignore should only affect a specific response_type, pass
+ * response_type, otherwise, pass -1.
+ *
+ * Every ignored sequence number gets garbage collected after 5 seconds.
+ *
+ */
void add_ignore_event(const int sequence, const int response_type) {
struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
* Checks if the given sequence is ignored and returns true if so.
*
*/
-static bool event_is_ignored(const int sequence, const int response_type) {
+bool event_is_ignored(const int sequence, const int response_type) {
struct Ignore_Event *event;
time_t now = time(NULL);
for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
if (event->sequence != sequence)
continue;
- if (event->response_type != 0 &&
+ if (event->response_type != -1 &&
event->response_type != response_type)
continue;
cookie = xcb_get_window_attributes_unchecked(conn, event->window);
DLOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence);
- add_ignore_event(event->sequence, 0);
+ add_ignore_event(event->sequence, -1);
manage_window(event->window, cookie, false);
x_push_changes(croot);
while ((event = xcb_poll_for_event(conn)) != NULL) {
if (event->response_type == 0) {
- ELOG("X11 Error received! sequence %x\n", event->sequence);
+ if (event_is_ignored(event->sequence, 0))
+ DLOG("Expected X11 Error received for sequence %x\n", event->sequence);
+ else ELOG("X11 Error received! sequence %x\n", event->sequence);
continue;
}
x_window_kill(con->window->id, kill_window);
return false;
} else {
+ xcb_void_cookie_t cookie;
/* un-parent the window */
- xcb_reparent_window(conn, con->window->id, root, 0, 0);
+ cookie = xcb_reparent_window(conn, con->window->id, root, 0, 0);
+
+ /* Ignore X11 errors for the ReparentWindow request.
+ * X11 Errors are returned when the window was already destroyed */
+ add_ignore_event(cookie.sequence, 0);
+
/* We are no longer handling this window, thus set WM_STATE to
* WM_STATE_WITHDRAWN (see ICCCM 4.1.3.1) */
long data[] = { XCB_ICCCM_WM_STATE_WITHDRAWN, XCB_NONE };
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
- A_WM_STATE, A_WM_STATE, 32, 2, data);
+ cookie = xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
+ con->window->id, A_WM_STATE, A_WM_STATE, 32, 2, data);
+
+ /* Ignore X11 errors for the ReparentWindow request.
+ * X11 Errors are returned when the window was already destroyed */
+ add_ignore_event(cookie.sequence, 0);
}
FREE(con->window->class_class);
FREE(con->window->class_instance);
XCB_CONFIG_WINDOW_HEIGHT,
&(r.x));
/* ignore events which are generated because we configured a window */
- add_ignore_event(cookie.sequence, 0);
+ add_ignore_event(cookie.sequence, -1);
}
/*