Bugfix: Ignore EnterNotifies generated by UnmapNotifies
Actually, commit1c5adc6c35
commented out code without ever fixing it. I think this was responsible for the 'workspace switching sometimes does not work' bug. My observations: Had it again today and analyzed a log of it. Looks like after unmapping the windows on one workspace (in my case: chromium, eclipse, urxvt, focus on eclipse) we get UnmapNotify events for chromium and eclipse, but then we get an EnterNotify for the terminal (due to unmapping the other windows and therefore mapping the terminal under the cursor), only afterwards the UnmapNotify follows. So, there are two things wrong with that: • We handle EnterNotifys for unmapped windows • Unmapping windows sometimes works in a sequence, sometimes the sequence gets split. Not sure why (if unmapping can take longer for some windows or if our syncing is wrong -- but i checked the latter briefly and it looks correct). Maybe GrabServer helps? • We don’t ignore EnterNotify events caused by UnmapNotifies. We used to, but then there was a different problem and we decided to solve the EnterNotify problem in another way, which actually never happened (commit1c5adc6c35
).
This commit is contained in:
parent
cd6f93be3f
commit
3721bcb868
|
@ -115,6 +115,7 @@ struct deco_render_params {
|
||||||
|
|
||||||
struct Ignore_Event {
|
struct Ignore_Event {
|
||||||
int sequence;
|
int sequence;
|
||||||
|
int response_type;
|
||||||
time_t added;
|
time_t added;
|
||||||
|
|
||||||
SLIST_ENTRY(Ignore_Event) ignore_events;
|
SLIST_ENTRY(Ignore_Event) ignore_events;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
extern int randr_base;
|
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
|
* Takes an xcb_generic_event_t and calls the appropriate handler, based on the
|
||||||
|
|
|
@ -21,10 +21,11 @@ int randr_base = -1;
|
||||||
changing workspaces */
|
changing workspaces */
|
||||||
static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
|
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));
|
struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
|
||||||
|
|
||||||
event->sequence = sequence;
|
event->sequence = sequence;
|
||||||
|
event->response_type = response_type;
|
||||||
event->added = time(NULL);
|
event->added = time(NULL);
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
|
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.
|
* 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;
|
struct Ignore_Event *event;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
|
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)
|
if (event->sequence != sequence)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (event->response_type != 0 &&
|
||||||
|
event->response_type != response_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* instead of removing a sequence number we better wait until it gets
|
/* instead of removing a sequence number we better wait until it gets
|
||||||
* garbage collected. it may generate multiple events (there are multiple
|
* garbage collected. it may generate multiple events (there are multiple
|
||||||
* enter_notifies for one configure_request, for example). */
|
* 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
|
/* Some events are not interesting, because they were not generated
|
||||||
* actively by the user, but by reconfiguration of windows */
|
* 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;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool enter_child = false;
|
bool enter_child = false;
|
||||||
/* Get container by frame or by child window */
|
/* 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);
|
cookie = xcb_get_window_attributes_unchecked(conn, event->window);
|
||||||
|
|
||||||
DLOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence);
|
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);
|
manage_window(event->window, cookie, false);
|
||||||
x_push_changes(croot);
|
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) {
|
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
|
/* we need to ignore EnterNotify events which will be generated because a
|
||||||
* different window is visible now */
|
* 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);
|
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);
|
Con *con = con_by_window_id(event->window);
|
||||||
|
|
6
src/x.c
6
src/x.c
|
@ -564,14 +564,14 @@ void x_push_node(Con *con, bool skip_decoration) {
|
||||||
cookie = xcb_map_window(conn, con->window->id);
|
cookie = xcb_map_window(conn, con->window->id);
|
||||||
DLOG("mapping child window (serial %d)\n", cookie.sequence);
|
DLOG("mapping child window (serial %d)\n", cookie.sequence);
|
||||||
/* Ignore enter_notifies which are generated when mapping */
|
/* Ignore enter_notifies which are generated when mapping */
|
||||||
add_ignore_event(cookie.sequence);
|
add_ignore_event(cookie.sequence, 0);
|
||||||
state->child_mapped = true;
|
state->child_mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = xcb_map_window(conn, con->frame);
|
cookie = xcb_map_window(conn, con->frame);
|
||||||
DLOG("mapping container (serial %d)\n", cookie.sequence);
|
DLOG("mapping container (serial %d)\n", cookie.sequence);
|
||||||
/* Ignore enter_notifies which are generated when mapping */
|
/* Ignore enter_notifies which are generated when mapping */
|
||||||
add_ignore_event(cookie.sequence);
|
add_ignore_event(cookie.sequence, 0);
|
||||||
state->mapped = con->mapped;
|
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);
|
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 */
|
/* Ignore enter_notifies which are generated when unmapping */
|
||||||
add_ignore_event(cookie.sequence);
|
add_ignore_event(cookie.sequence, 0);
|
||||||
state->mapped = con->mapped;
|
state->mapped = con->mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) {
|
||||||
XCB_CONFIG_WINDOW_HEIGHT,
|
XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
&(r.x));
|
&(r.x));
|
||||||
/* ignore events which are generated because we configured a window */
|
/* ignore events which are generated because we configured a window */
|
||||||
add_ignore_event(cookie.sequence);
|
add_ignore_event(cookie.sequence, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue