-#line 2 "commands.c"
+#undef I3__FILE__
+#define I3__FILE__ "commands.c"
/*
* vim:ts=4:sw=4:expandtab
*
Output *output;
if (strcasecmp(output_str, "left") == 0) {
- output = get_output_next(D_LEFT, current_output);
+ output = get_output_next(D_LEFT, current_output, CLOSEST_OUTPUT);
if (!output)
output = get_output_most(D_RIGHT, current_output);
} else if (strcasecmp(output_str, "right") == 0) {
- output = get_output_next(D_RIGHT, current_output);
+ output = get_output_next(D_RIGHT, current_output, CLOSEST_OUTPUT);
if (!output)
output = get_output_most(D_LEFT, current_output);
} else if (strcasecmp(output_str, "up") == 0) {
- output = get_output_next(D_UP, current_output);
+ output = get_output_next(D_UP, current_output, CLOSEST_OUTPUT);
if (!output)
output = get_output_most(D_DOWN, current_output);
} else if (strcasecmp(output_str, "down") == 0) {
- output = get_output_next(D_DOWN, current_output);
+ output = get_output_next(D_DOWN, current_output, CLOSEST_OUTPUT);
if (!output)
output = get_output_most(D_UP, current_output);
} else output = get_output_by_name(output_str);
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
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>'.
*
/* 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;
}
/* 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) {
}
/*
- * Implementation of 'move [window|container] [to] workspace number <number>'.
+ * Implementation of 'move [window|container] [to] workspace number <name>'.
*
*/
void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
if (parsed_num == LONG_MIN ||
parsed_num == LONG_MAX ||
parsed_num < 0 ||
- *endptr != '\0') {
- LOG("Could not parse \"%s\" as a number.\n", which);
+ endptr == which) {
+ LOG("Could not parse initial part of \"%s\" as a number.\n", which);
y(map_open);
ystr("success");
y(bool, false);
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) {
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;
}
/*
- * Implementation of 'workspace number <number>'
+ * Implementation of 'workspace number <name>'
*
*/
void cmd_workspace_number(I3_CMD, char *which) {
if (parsed_num == LONG_MIN ||
parsed_num == LONG_MAX ||
parsed_num < 0 ||
- *endptr != '\0') {
- LOG("Could not parse \"%s\" as a number.\n", which);
+ endptr == which) {
+ LOG("Could not parse initial part of \"%s\" as a number.\n", which);
y(map_open);
ystr("success");
y(bool, false);
if (!workspace) {
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);
// TODO: clean this up with commands.spec as soon as we switched away from the lex/yacc command parser
if (strcasecmp(name, "up") == 0)
- output = get_output_next(D_UP, current_output);
+ output = get_output_next(D_UP, current_output, CLOSEST_OUTPUT);
else if (strcasecmp(name, "down") == 0)
- output = get_output_next(D_DOWN, current_output);
+ output = get_output_next(D_DOWN, current_output, CLOSEST_OUTPUT);
else if (strcasecmp(name, "left") == 0)
- output = get_output_next(D_LEFT, current_output);
+ output = get_output_next(D_LEFT, current_output, CLOSEST_OUTPUT);
else if (strcasecmp(name, "right") == 0)
- output = get_output_next(D_RIGHT, current_output);
+ output = get_output_next(D_RIGHT, current_output, CLOSEST_OUTPUT);
else
output = get_output_by_name(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
/* 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);
/* 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);