Bugfix: Eliminate race condition, fix dock windows
There was a race condition when mapping a window and not setting the event mask before. Therefore, the ReparentNotify and (more important) the UnmapNotify generated by reparenting were not received, thus leaving the awaiting_useless_unmap variable of the client "true". To just make it work, in previous commits the DestroyNotify handler was introduced. Fortunately, with fixing this race condition by first setting the event mask and mapping the window afterwards, we can remove this handler. As for the dock windows, there were quite some occurences were client->container was used without checking if the client is inside a container at all. Furthermore, the client’s strut containing the space to reserve at the screen edge is now checked and the desired height is set to the window’s height if the strut contains 0 or if no strut was specified at all.
This commit is contained in:
@ -158,7 +158,9 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
|
||||
|
||||
/* Do plausibility checks: This event may be useless for us if it occurs on a window
|
||||
which is in a stacked container but not the focused one */
|
||||
if (client->container->mode == MODE_STACK && client->container->currently_focused != client) {
|
||||
if (client->container != NULL &&
|
||||
client->container->mode == MODE_STACK &&
|
||||
client->container->currently_focused != client) {
|
||||
LOG("Plausibility check says: no\n");
|
||||
return 1;
|
||||
}
|
||||
@ -410,6 +412,7 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
|
||||
wa.u.override_redirect = reply->override_redirect;
|
||||
LOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence);
|
||||
add_ignore_event(event->sequence);
|
||||
|
||||
manage_window(prophs, conn, event->window, wa);
|
||||
return 1;
|
||||
}
|
||||
@ -536,13 +539,19 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti
|
||||
}
|
||||
}
|
||||
|
||||
if (client->dock) {
|
||||
LOG("Removing from dock clients\n");
|
||||
SLIST_REMOVE(&(client->workspace->dock_clients), client, Client, dock_clients);
|
||||
}
|
||||
|
||||
LOG("child of 0x%08x.\n", client->frame);
|
||||
xcb_reparent_window(conn, client->child, root, 0, 0);
|
||||
xcb_destroy_window(conn, client->frame);
|
||||
xcb_flush(conn);
|
||||
table_remove(byParent, client->frame);
|
||||
|
||||
cleanup_table(conn, client->container->workspace);
|
||||
if (client->container != NULL)
|
||||
cleanup_table(conn, client->container->workspace);
|
||||
|
||||
free(client);
|
||||
|
||||
@ -551,20 +560,6 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This handler makes sure that windows are closed correctly as we drop the first unmap event we
|
||||
* get because they are sometimes generated by remapping.
|
||||
*
|
||||
* FIXME: Rather than providing this event, I’d rather know why some applications need to have
|
||||
* unmap events ignored (like VLC’s open dialog, just open it two times) while others don’t (GIMP).
|
||||
* For now, just make it work.
|
||||
*
|
||||
*/
|
||||
int handle_destroy_notify_event(void *data, xcb_connection_t *conn, xcb_destroy_notify_event_t *event) {
|
||||
LOG("Destroynotify, faking unmapnotify\n");
|
||||
return handle_unmap_notify_event(data, conn, (xcb_unmap_notify_event_t*)event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a window changes its title
|
||||
*
|
||||
@ -608,6 +603,10 @@ int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state,
|
||||
if (old_name != NULL)
|
||||
free(old_name);
|
||||
|
||||
/* If the client is a dock window, we don’t need to render anything */
|
||||
if (client->dock)
|
||||
return 1;
|
||||
|
||||
if (client->container->mode == MODE_STACK)
|
||||
render_container(conn, client->container);
|
||||
else decorate_window(conn, client, client->frame, client->titlegc, 0);
|
||||
@ -649,6 +648,11 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *
|
||||
}
|
||||
|
||||
LOG("got client %s\n", client->name);
|
||||
if (client->dock) {
|
||||
LOG("this is a dock\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (client->container->mode != MODE_STACK)
|
||||
decorate_window(conn, client, client->frame, client->titlegc, 0);
|
||||
else {
|
||||
|
Reference in New Issue
Block a user