From d5d44e66a217f7c41a2968ff435c09261ca4b6d4 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 16 May 2009 18:12:35 +0200 Subject: [PATCH] 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. --- src/commands.c | 7 ++++--- src/handlers.c | 10 +++++++++- src/util.c | 12 +++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/commands.c b/src/commands.c index b84cb858..e289e018 100644 --- a/src/commands.c +++ b/src/commands.c @@ -547,11 +547,12 @@ void show_workspace(xcb_connection_t *conn, int workspace) { } t_ws->screen->current_workspace = workspace-1; + Workspace *old_workspace = c_ws; + c_ws = &workspaces[workspace-1]; - /* Unmap all clients of the current workspace */ - unmap_workspace(conn, c_ws); + /* Unmap all clients of the old workspace */ + unmap_workspace(conn, old_workspace); - c_ws = &workspaces[workspace-1]; 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); diff --git a/src/handlers.c b/src/handlers.c index c7c11246..7dae1149 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -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; diff --git a/src/util.c b/src/util.c index 5b51bd5b..a1146251 100644 --- a/src/util.c +++ b/src/util.c @@ -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) -- 2.39.5