]> git.sur5r.net Git - i3/i3/blobdiff - src/commands.c
fixes #776
[i3/i3] / src / commands.c
index 44e6a23d4533f275b6ddffd15c96dd905c3899ea..34f0f9db97f5da72a4e042da4addc7bf383f8fe9 100644 (file)
@@ -1,3 +1,5 @@
+#undef I3__FILE__
+#define I3__FILE__ "commands.c"
 /*
  * vim:ts=4:sw=4:expandtab
  *
@@ -97,6 +99,29 @@ static bool maybe_back_and_forth(struct CommandResult *cmd_output, char *name) {
     return true;
 }
 
+/*
+ * Return the passed workspace unless it is the current one and auto back and
+ * forth is enabled, in which case the back_and_forth workspace is returned.
+ */
+static Con *maybe_auto_back_and_forth_workspace(Con *workspace) {
+    Con *current, *baf;
+
+    if (!config.workspace_auto_back_and_forth)
+        return workspace;
+
+    current = con_get_workspace(focused);
+
+    if (current == workspace) {
+        baf = workspace_back_and_forth_get();
+        if (baf != NULL) {
+            DLOG("Substituting workspace with back_and_forth, as it is focused.\n");
+            return baf;
+        }
+    }
+
+    return workspace;
+}
+
 // This code is commented out because we might recycle it for popping up error
 // messages on parser errors.
 #if 0
@@ -398,6 +423,38 @@ void cmd_move_con_to_workspace(I3_CMD, char *which) {
     ysuccess(true);
 }
 
+/**
+ * Implementation of 'move [window|container] [to] workspace back_and_forth'.
+ *
+ */
+void cmd_move_con_to_workspace_back_and_forth(I3_CMD) {
+    owindow *current;
+    Con *ws;
+
+    ws = workspace_back_and_forth_get();
+
+    if (ws == NULL) {
+        y(map_open);
+        ystr("success");
+        y(bool, false);
+        ystr("error");
+        ystr("No workspace was previously active.");
+        y(map_close);
+        return;
+    }
+
+    HANDLE_EMPTY_MATCH;
+
+    TAILQ_FOREACH(current, &owindows, owindows) {
+        DLOG("matching: %p / %s\n", current->con, current->con->name);
+        con_move_to_workspace(current->con, ws, true, false);
+    }
+
+    cmd_output->needs_tree_render = true;
+    // XXX: default reply for now, make this a better reply
+    ysuccess(true);
+}
+
 /*
  * Implementation of 'move [window|container] [to] workspace <name>'.
  *
@@ -414,8 +471,14 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
     /* We have nothing to move:
      *  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)) {
+    if (!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) {
+        ELOG("No windows match your criteria, cannot move.\n");
+        ysuccess(false);
+        return;
+    }
+
+    if (match_is_empty(current_match) && focused->type == CT_WORKSPACE) {
+        ELOG("No window to move, you have focused a workspace.\n");
         ysuccess(false);
         return;
     }
@@ -424,6 +487,8 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
     /* get the workspace */
     Con *ws = workspace_get(name, NULL);
 
+    ws = maybe_auto_back_and_forth_workspace(ws);
+
     HANDLE_EMPTY_MATCH;
 
     TAILQ_FOREACH(current, &owindows, owindows) {
@@ -452,7 +517,7 @@ void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
         return;
     }
 
-    LOG("should move window to workspace with number %d\n", which);
+    LOG("should move window to workspace %s\n", which);
     /* get the workspace */
     Con *output, *workspace = NULL;
 
@@ -478,16 +543,11 @@ void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
             child->num == parsed_num);
 
     if (!workspace) {
-        y(map_open);
-        ystr("success");
-        y(bool, false);
-        ystr("error");
-        // TODO: better error message
-        ystr("No such workspace");
-        y(map_close);
-        return;
+        workspace = workspace_get(which, NULL);
     }
 
+    workspace = maybe_auto_back_and_forth_workspace(workspace);
+
     HANDLE_EMPTY_MATCH;
 
     TAILQ_FOREACH(current, &owindows, owindows) {
@@ -505,7 +565,7 @@ static void cmd_resize_floating(I3_CMD, char *way, char *direction, Con *floatin
     if (strcmp(direction, "up") == 0) {
         floating_con->rect.y -= px;
         floating_con->rect.height += px;
-    } else if (strcmp(direction, "down") == 0) {
+    } else if (strcmp(direction, "down") == 0 || strcmp(direction, "height") == 0) {
         floating_con->rect.height += px;
     } else if (strcmp(direction, "left") == 0) {
         floating_con->rect.x -= px;
@@ -835,17 +895,15 @@ void cmd_workspace_number(I3_CMD, char *which) {
             child->num == parsed_num);
 
     if (!workspace) {
-        LOG("There is no workspace with number %d, creating a new one.\n", parsed_num);
+        LOG("There is no workspace with number %ld, creating a new one.\n", parsed_num);
         ysuccess(true);
         /* terminate the which string after the endposition of the number */
         *endptr = '\0';
-        if (maybe_back_and_forth(cmd_output, which))
-            return;
         workspace_show_by_name(which);
         cmd_output->needs_tree_render = true;
         return;
     }
-    if (maybe_back_and_forth(cmd_output, which))
+    if (maybe_back_and_forth(cmd_output, workspace->name))
         return;
     workspace_show(workspace);
 
@@ -1115,9 +1173,17 @@ void cmd_move_workspace_to_output(I3_CMD, char *name) {
  *
  */
 void cmd_split(I3_CMD, char *direction) {
+    owindow *current;
     /* TODO: use matches */
     LOG("splitting in direction %c\n", direction[0]);
-    tree_split(focused, (direction[0] == 'v' ? VERT : HORIZ));
+    if (match_is_empty(current_match))
+        tree_split(focused, (direction[0] == 'v' ? VERT : HORIZ));
+    else {
+        TAILQ_FOREACH(current, &owindows, owindows) {
+            DLOG("matching: %p / %s\n", current->con, current->con->name);
+            tree_split(current->con, (direction[0] == 'v' ? VERT : HORIZ));
+        }
+    }
 
     cmd_output->needs_tree_render = true;
     // XXX: default reply for now, make this a better reply
@@ -1263,7 +1329,7 @@ void cmd_focus_level(I3_CMD, char *level) {
             if (con_fullscreen_permits_focusing(focused->parent))
                 success = level_up();
             else
-                LOG("Currently in fullscreen, not going up\n");
+                ELOG("'focus parent': Currently in fullscreen, not going up\n");
         }
     }
 
@@ -1421,12 +1487,16 @@ void cmd_layout(I3_CMD, char *layout_str) {
         layout = L_SPLITV;
     else if (strcmp(layout_str, "splith") == 0)
         layout = L_SPLITH;
+    else {
+        ELOG("Unknown layout \"%s\", this is a mismatch between code and parser spec.\n", layout_str);
+        return;
+    }
 
     DLOG("changing layout to %s (%d)\n", layout_str, layout);
 
     /* check if the match is empty, not if the result is empty */
     if (match_is_empty(current_match))
-        con_set_layout(focused->parent, layout);
+        con_set_layout(focused, layout);
     else {
         TAILQ_FOREACH(current, &owindows, owindows) {
             DLOG("matching: %p / %s\n", current->con, current->con->name);
@@ -1453,7 +1523,7 @@ void cmd_layout_toggle(I3_CMD, char *toggle_mode) {
 
     /* check if the match is empty, not if the result is empty */
     if (match_is_empty(current_match))
-        con_toggle_layout(focused->parent, toggle_mode);
+        con_toggle_layout(focused, toggle_mode);
     else {
         TAILQ_FOREACH(current, &owindows, owindows) {
             DLOG("matching: %p / %s\n", current->con, current->con->name);