diff --git a/include/data.h b/include/data.h index 843d0c9c..f20d764e 100644 --- a/include/data.h +++ b/include/data.h @@ -115,6 +115,7 @@ struct deco_render_params { struct Ignore_Event { int sequence; + int response_type; time_t added; SLIST_ENTRY(Ignore_Event) ignore_events; diff --git a/include/handlers.h b/include/handlers.h index ff0883d5..839bac61 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -15,7 +15,7 @@ extern int randr_base; -void add_ignore_event(const int sequence); +void add_ignore_event(const int sequence, const int response_type); /** * Takes an xcb_generic_event_t and calls the appropriate handler, based on the diff --git a/src/handlers.c b/src/handlers.c index ac0fd87a..fbd660bc 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -21,10 +21,11 @@ int randr_base = -1; changing workspaces */ static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events; -void add_ignore_event(const int sequence) { +void add_ignore_event(const int sequence, const int response_type) { struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event)); event->sequence = sequence; + event->response_type = response_type; event->added = time(NULL); SLIST_INSERT_HEAD(&ignore_events, event, ignore_events); @@ -34,7 +35,7 @@ void add_ignore_event(const int sequence) { * Checks if the given sequence is ignored and returns true if so. * */ -static bool event_is_ignored(const int sequence) { +static 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);) { @@ -50,6 +51,10 @@ static bool event_is_ignored(const int sequence) { if (event->sequence != sequence) continue; + if (event->response_type != 0 && + event->response_type != response_type) + continue; + /* instead of removing a sequence number we better wait until it gets * garbage collected. it may generate multiple events (there are multiple * enter_notifies for one configure_request, for example). */ @@ -153,8 +158,10 @@ static int handle_enter_notify(xcb_enter_notify_event_t *event) { } /* Some events are not interesting, because they were not generated * actively by the user, but by reconfiguration of windows */ - if (event_is_ignored(event->sequence)) + if (event_is_ignored(event->sequence, XCB_ENTER_NOTIFY)) { + DLOG("Event ignored\n"); return 1; + } bool enter_child = false; /* Get container by frame or by child window */ @@ -285,7 +292,7 @@ static int handle_map_request(xcb_map_request_event_t *event) { 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); + add_ignore_event(event->sequence, 0); manage_window(event->window, cookie, false); x_push_changes(croot); @@ -438,12 +445,9 @@ static int handle_screen_change(xcb_generic_event_t *e) { * */ static int handle_unmap_notify_event(xcb_unmap_notify_event_t *event) { - - /* FIXME: we cannot ignore this sequence because more UnmapNotifys with the same sequence - * numbers but different window IDs may follow */ /* we need to ignore EnterNotify events which will be generated because a * different window is visible now */ - //add_ignore_event(event->sequence); + add_ignore_event(event->sequence, XCB_ENTER_NOTIFY); DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence); Con *con = con_by_window_id(event->window); diff --git a/src/x.c b/src/x.c index 22660d12..ab60c51d 100644 --- a/src/x.c +++ b/src/x.c @@ -564,14 +564,14 @@ void x_push_node(Con *con, bool skip_decoration) { cookie = xcb_map_window(conn, con->window->id); DLOG("mapping child window (serial %d)\n", cookie.sequence); /* Ignore enter_notifies which are generated when mapping */ - add_ignore_event(cookie.sequence); + add_ignore_event(cookie.sequence, 0); state->child_mapped = true; } cookie = xcb_map_window(conn, con->frame); DLOG("mapping container (serial %d)\n", cookie.sequence); /* Ignore enter_notifies which are generated when mapping */ - add_ignore_event(cookie.sequence); + add_ignore_event(cookie.sequence, 0); state->mapped = con->mapped; } @@ -631,7 +631,7 @@ static void x_push_node_unmaps(Con *con) { DLOG("ignore_unmap for con %p (frame 0x%08x) now %d\n", con, con->frame, con->ignore_unmap); } /* Ignore enter_notifies which are generated when unmapping */ - add_ignore_event(cookie.sequence); + add_ignore_event(cookie.sequence, 0); state->mapped = con->mapped; } diff --git a/src/xcb.c b/src/xcb.c index a7758ad3..3fd0bfcd 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -328,7 +328,7 @@ void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) { XCB_CONFIG_WINDOW_HEIGHT, &(r.x)); /* ignore events which are generated because we configured a window */ - add_ignore_event(cookie.sequence); + add_ignore_event(cookie.sequence, 0); } /*