Bugfix: Re-assign dock windows to different workspaces when a workspace is deleted

Killing a dock client and having destroyed workspace 1 before (or the workspace
on which the dock client was started when it was not auto-started) crashed i3 before
this bugfix.
This commit is contained in:
Michael Stapelberg 2009-05-16 18:12:35 +02:00
parent e79cca8f72
commit d5d44e66a2
3 changed files with 25 additions and 6 deletions

View File

@ -547,11 +547,12 @@ void show_workspace(xcb_connection_t *conn, int workspace) {
}
t_ws->screen->current_workspace = workspace-1;
/* Unmap all clients of the current workspace */
unmap_workspace(conn, c_ws);
Workspace *old_workspace = c_ws;
c_ws = &workspaces[workspace-1];
/* Unmap all clients of the old workspace */
unmap_workspace(conn, old_workspace);
current_row = c_ws->current_row;
current_col = c_ws->current_col;
LOG("new current row = %d, current col = %d\n", current_row, current_col);

View File

@ -145,7 +145,7 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
return 1;
}
/* Some events are not interesting, because they were not generated actively by the
user, but be reconfiguration of windows */
user, but by reconfiguration of windows */
if (event_is_ignored(event->sequence))
return 1;
@ -192,6 +192,14 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
return 1;
}
if (client->container->workspace != c_ws) {
/* This can happen when a client gets assigned to a different workspace than
* the current one (see src/mainx.c:reparent_window). Shortly after it was created,
* an enter_notify will follow. */
LOG("enter_notify for a client on a different workspace, ignoring\n");
return 1;
}
set_focus(conn, client, false);
return 1;

View File

@ -263,8 +263,18 @@ void unmap_workspace(xcb_connection_t *conn, Workspace *u_ws) {
}
/* If we did not unmap any clients, the workspace is empty and we can destroy it */
if (unmapped_clients == 0)
if (unmapped_clients == 0) {
/* Re-assign the workspace of all dock clients which use this workspace */
Client *dock;
SLIST_FOREACH(dock, &(u_ws->screen->dock_clients), dock_clients) {
if (dock->workspace != u_ws)
continue;
LOG("Re-assigning dock client to c_ws (%p)\n", c_ws);
dock->workspace = c_ws;
}
u_ws->screen = NULL;
}
/* Unmap the stack windows on the current workspace, if any */
SLIST_FOREACH(stack_win, &stack_wins, stack_windows)