Implement moving workspaces as if they're regular containers

This commit is contained in:
Deiz
2012-09-28 13:54:24 -04:00
committed by Michael Stapelberg
parent 72c66a2091
commit e89a25f81f
5 changed files with 179 additions and 10 deletions

View File

@ -388,7 +388,8 @@ void cmd_move_con_to_workspace(I3_CMD, char *which) {
* when criteria was specified but didn't match any window or
* when criteria wasn't specified and we don't have any window focused. */
if ((!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) ||
(match_is_empty(current_match) && focused->type == CT_WORKSPACE)) {
(match_is_empty(current_match) && focused->type == CT_WORKSPACE &&
con_is_leaf(focused))) {
ysuccess(false);
return;
}
@ -476,9 +477,8 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
ysuccess(false);
return;
}
if (match_is_empty(current_match) && focused->type == CT_WORKSPACE) {
ELOG("No window to move, you have focused a workspace.\n");
else if (match_is_empty(current_match) && focused->type == CT_WORKSPACE &&
con_is_leaf(focused)) {
ysuccess(false);
return;
}
@ -512,7 +512,8 @@ void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
* when criteria was specified but didn't match any window or
* when criteria wasn't specified and we don't have any window focused. */
if ((!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) ||
(match_is_empty(current_match) && focused->type == CT_WORKSPACE)) {
(match_is_empty(current_match) && focused->type == CT_WORKSPACE &&
con_is_leaf(focused))) {
ysuccess(false);
return;
}

View File

@ -607,11 +607,6 @@ void con_toggle_fullscreen(Con *con, int fullscreen_mode) {
*
*/
void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool dont_warp) {
if (con->type == CT_WORKSPACE) {
DLOG("Moving workspaces is not yet implemented.\n");
return;
}
/* Prevent moving if this would violate the fullscreen focus restrictions. */
if (!con_fullscreen_permits_focusing(workspace)) {
LOG("Cannot move out of a fullscreen container");
@ -629,6 +624,21 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool
return;
}
if (con->type == CT_WORKSPACE) {
con = workspace_encapsulate(con);
if (con == NULL) {
ELOG("Workspace failed to move its contents into a container!\n");
return;
}
/* Re-parent all of the old workspace's floating windows. */
Con *child;
while (!TAILQ_EMPTY(&(source_ws->floating_head))) {
child = TAILQ_FIRST(&(source_ws->floating_head));
con_move_to_workspace(child, workspace, true, true);
}
}
/* Save the current workspace. So we can call workspace_show() by the end
* of this function. */
Con *current_ws = con_get_workspace(focused);

View File

@ -830,3 +830,34 @@ Con *workspace_attach_to(Con *ws) {
return new;
}
/**
* Creates a new container and re-parents all of children from the given
* workspace into it.
*
* The container inherits the layout from the workspace.
*/
Con *workspace_encapsulate(Con *ws) {
if (TAILQ_EMPTY(&(ws->nodes_head))) {
ELOG("Workspace %p / %s has no children to encapsulate\n", ws, ws->name);
return NULL;
}
Con *new = con_new(NULL, NULL);
new->parent = ws;
new->layout = ws->layout;
DLOG("Moving children of workspace %p / %s into container %p\n",
ws, ws->name, new);
Con *child;
while (!TAILQ_EMPTY(&(ws->nodes_head))) {
child = TAILQ_FIRST(&(ws->nodes_head));
con_detach(child);
con_attach(child, new, true);
}
con_attach(new, ws, true);
return new;
}