From 07bebdf84169621732456c23f07f40421b12e781 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 24 Jun 2009 17:12:12 +0200 Subject: [PATCH] Correctly re-assign floating clients to the destination workspace when moving --- include/floating.h | 10 +++++++++- src/commands.c | 14 +------------- src/floating.c | 22 ++++++++++++++++++++++ src/layout.c | 15 +++++++++++++++ 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/floating.h b/include/floating.h index edc11a95..a4f8619a 100644 --- a/include/floating.h +++ b/include/floating.h @@ -3,7 +3,7 @@ * * i3 - an improved dynamic tiling window manager * - * (c) 2009 Michael Stapelberg and contributors + * © 2009 Michael Stapelberg and contributors * * See file LICENSE for license information. * @@ -22,6 +22,14 @@ */ void toggle_floating_mode(xcb_connection_t *conn, Client *client, bool automatic); +/** + * Removes the floating client from its workspace and attaches it to the new workspace. + * This is centralized here because it may happen if you move it via keyboard and + * if you move it using your mouse. + * + */ +void floating_assign_to_workspace(Client *client, Workspace *new_workspace); + /** * Called whenever the user clicks on a border (not the titlebar!) of a floating window. * Determines on which border the user clicked and launches the drag_pointer function diff --git a/src/commands.c b/src/commands.c index ff682bd5..2b4b163e 100644 --- a/src/commands.c +++ b/src/commands.c @@ -453,19 +453,7 @@ static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *cl } } - /* Remove from focus stack and list of floating clients */ - SLIST_REMOVE(&(client->workspace->focus_stack), client, Client, focus_clients); - TAILQ_REMOVE(&(client->workspace->floating_clients), client, floating_clients); - - if (client->workspace->fullscreen_client == client) - client->workspace->fullscreen_client = NULL; - - /* Insert into destination focus stack and list of floating clients */ - client->workspace = t_ws; - SLIST_INSERT_HEAD(&(t_ws->focus_stack), client, focus_clients); - TAILQ_INSERT_TAIL(&(t_ws->floating_clients), client, floating_clients); - if (client->fullscreen) - t_ws->fullscreen_client = client; + floating_assign_to_workspace(client, t_ws); /* If we’re moving it to an invisible screen, we need to unmap it */ if (t_ws->screen->current_workspace != t_ws->num) { diff --git a/src/floating.c b/src/floating.c index fb280dc9..6e5bec52 100644 --- a/src/floating.c +++ b/src/floating.c @@ -140,6 +140,28 @@ void toggle_floating_mode(xcb_connection_t *conn, Client *client, bool automatic xcb_flush(conn); } +/* + * Removes the floating client from its workspace and attaches it to the new workspace. + * This is centralized here because it may happen if you move it via keyboard and + * if you move it using your mouse. + * + */ +void floating_assign_to_workspace(Client *client, Workspace *new_workspace) { + /* Remove from focus stack and list of floating clients */ + SLIST_REMOVE(&(client->workspace->focus_stack), client, Client, focus_clients); + TAILQ_REMOVE(&(client->workspace->floating_clients), client, floating_clients); + + if (client->workspace->fullscreen_client == client) + client->workspace->fullscreen_client = NULL; + + /* Insert into destination focus stack and list of floating clients */ + client->workspace = new_workspace; + SLIST_INSERT_HEAD(&(client->workspace->focus_stack), client, focus_clients); + TAILQ_INSERT_TAIL(&(client->workspace->floating_clients), client, floating_clients); + if (client->fullscreen) + client->workspace->fullscreen_client = client; + +} /* * Called whenever the user clicks on a border (not the titlebar!) of a floating window. diff --git a/src/layout.c b/src/layout.c index 2b01f90c..e70d0f49 100644 --- a/src/layout.c +++ b/src/layout.c @@ -25,6 +25,7 @@ #include "xinerama.h" #include "layout.h" #include "client.h" +#include "floating.h" /* * Updates *destination with new_value and returns true if it was changed or false @@ -173,10 +174,24 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw * */ void reposition_client(xcb_connection_t *conn, Client *client) { + i3Screen *screen; + LOG("frame 0x%08x needs to be pushed to %dx%d\n", client->frame, client->rect.x, client->rect.y); /* Note: We can use a pointer to client->x like an array of uint32_ts because it is followed by client->y by definition */ xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, &(client->rect.x)); + + if (!client_is_floating(client)) + return; + + /* If the client is floating, we need to check if we moved it to a different workspace */ + if (client->workspace->screen == (screen = get_screen_containing(client->rect.x, client->rect.y))) + return; + + LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen); + LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen); + floating_assign_to_workspace(client, &workspaces[screen->current_workspace]); + LOG("fixed that\n"); } /* -- 2.39.5