aboutsummaryrefslogtreecommitdiff
path: root/sway/commands
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands')
-rw-r--r--sway/commands/assign.c27
-rw-r--r--sway/commands/exec_always.c11
-rw-r--r--sway/commands/floating.c5
-rw-r--r--sway/commands/focus.c13
-rw-r--r--sway/commands/fullscreen.c3
-rw-r--r--sway/commands/hide_edge_borders.c2
-rw-r--r--sway/commands/move.c18
-rw-r--r--sway/commands/nop.c5
-rw-r--r--sway/commands/rename.c11
-rw-r--r--sway/commands/resize.c9
-rw-r--r--sway/commands/scratchpad.c9
-rw-r--r--sway/commands/set.c12
-rw-r--r--sway/commands/show_marks.c3
-rw-r--r--sway/commands/sticky.c16
-rw-r--r--sway/commands/swap.c8
-rw-r--r--sway/commands/unmark.c3
-rw-r--r--sway/commands/workspace.c7
17 files changed, 106 insertions, 56 deletions
diff --git a/sway/commands/assign.c b/sway/commands/assign.c
index 0bc0929a..04582e88 100644
--- a/sway/commands/assign.c
+++ b/sway/commands/assign.c
@@ -22,27 +22,38 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
return error;
}
- ++argv;
- int target_len = argc - 1;
+ --argc; ++argv;
if (strncmp(*argv, "→", strlen("→")) == 0) {
- if (argc < 3) {
+ if (argc < 2) {
free(criteria);
return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
}
+ --argc;
++argv;
- --target_len;
}
if (strcmp(*argv, "output") == 0) {
criteria->type = CT_ASSIGN_OUTPUT;
- ++argv;
- --target_len;
+ --argc; ++argv;
} else {
- criteria->type = CT_ASSIGN_WORKSPACE;
+ if (strcmp(*argv, "workspace") == 0) {
+ --argc; ++argv;
+ }
+ if (strcmp(*argv, "number") == 0) {
+ --argc; ++argv;
+ if (argv[0][0] < '0' || argv[0][0] > '9') {
+ free(criteria);
+ return cmd_results_new(CMD_INVALID, "assign",
+ "Invalid workspace number '%s'", argv[0]);
+ }
+ criteria->type = CT_ASSIGN_WORKSPACE_NUMBER;
+ } else {
+ criteria->type = CT_ASSIGN_WORKSPACE;
+ }
}
- criteria->target = join_args(argv, target_len);
+ criteria->target = join_args(argv, argc);
list_add(config->criteria, criteria);
wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index 00e39ae7..5ce7919b 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -26,7 +26,16 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
return error;
}
- tmp = join_args(argv + 1, argc - 1);
+ --argc; ++argv;
+ }
+
+ if (argv[0][0] == '\'' || argv[0][0] == '"') {
+ if (argc > 0) {
+ return cmd_results_new(CMD_INVALID, "exec_always",
+ "command cannot be partially quoted");
+ }
+ tmp = strdup(argv[0]);
+ strip_quotes(tmp);
} else {
tmp = join_args(argv, argc);
}
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index 31de5ec3..beafd9fb 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -8,6 +8,7 @@
#include "sway/tree/container.h"
#include "sway/tree/layout.h"
#include "sway/tree/view.h"
+#include "sway/tree/workspace.h"
#include "list.h"
struct cmd_results *cmd_floating(int argc, char **argv) {
@@ -24,7 +25,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
if (container->type == C_WORKSPACE) {
// Wrap the workspace's children in a container so we can float it
struct sway_container *workspace = container;
- container = container_wrap_children(container);
+ container = workspace_wrap_children(container);
workspace->layout = L_HORIZ;
seat_set_focus(config->handler_context.seat, container);
}
@@ -32,7 +33,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
// If the container is in a floating split container,
// operate on the split container instead of the child.
if (container_is_floating_or_child(container)) {
- while (container->parent->layout != L_FLOATING) {
+ while (container->parent->type != C_WORKSPACE) {
container = container->parent;
}
}
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 76d3f1dc..6659a683 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -39,21 +39,24 @@ static struct cmd_results *focus_mode(struct sway_container *con,
// If the container is in a floating split container,
// operate on the split container instead of the child.
if (container_is_floating_or_child(con)) {
- while (con->parent->layout != L_FLOATING) {
+ while (con->parent->type != C_WORKSPACE) {
con = con->parent;
}
}
struct sway_container *new_focus = NULL;
if (floating) {
- new_focus = seat_get_focus_inactive(seat, ws->sway_workspace->floating);
+ new_focus = seat_get_focus_inactive_floating(seat, ws);
} else {
new_focus = seat_get_focus_inactive_tiling(seat, ws);
}
- if (!new_focus) {
- new_focus = ws;
+ if (new_focus) {
+ seat_set_focus(seat, new_focus);
+ } else {
+ return cmd_results_new(CMD_FAILURE, "focus",
+ "Failed to find a %s container in workspace",
+ floating ? "floating" : "tiling");
}
- seat_set_focus(seat, new_focus);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index 5ad06e40..a0661200 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -4,6 +4,7 @@
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
+#include "sway/tree/workspace.h"
#include "sway/tree/layout.h"
#include "util.h"
@@ -21,7 +22,7 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
if (container->type == C_WORKSPACE) {
// Wrap the workspace's children in a container so we can fullscreen it
struct sway_container *workspace = container;
- container = container_wrap_children(container);
+ container = workspace_wrap_children(container);
workspace->layout = L_HORIZ;
seat_set_focus(config->handler_context.seat, container);
}
diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c
index bb390f5f..d59c9fdb 100644
--- a/sway/commands/hide_edge_borders.c
+++ b/sway/commands/hide_edge_borders.c
@@ -31,7 +31,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
"<none|vertical|horizontal|both|smart>'");
}
- container_for_each_descendant(&root_container, _configure_view, NULL);
+ root_for_each_container(_configure_view, NULL);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/commands/move.c b/sway/commands/move.c
index de6b1b0a..c6dc0775 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500
+#include <ctype.h>
#include <stdbool.h>
#include <string.h>
#include <strings.h>
@@ -22,7 +23,7 @@
static const char *expected_syntax =
"Expected 'move <left|right|up|down> <[px] px>' or "
"'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or "
- "'move [--no-auto-back-and-forth] <container|window|workspace> [to] output <name|direction>' or "
+ "'move <container|window|workspace> [to] output <name|direction>' or "
"'move <container|window> [to] mark <mark>'";
static struct sway_container *output_in_direction(const char *direction,
@@ -64,7 +65,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
return cmd_results_new(CMD_FAILURE, "move",
"Can't move an empty workspace");
}
- current = container_wrap_children(current);
+ current = workspace_wrap_children(current);
} else if (current->type != C_CONTAINER && current->type != C_VIEW) {
return cmd_results_new(CMD_FAILURE, "move",
"Can only move containers and views.");
@@ -124,7 +125,11 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
return cmd_results_new(CMD_INVALID, "move",
expected_syntax);
}
- ws_name = strdup(argv[3]);
+ if (!isdigit(argv[3][0])) {
+ return cmd_results_new(CMD_INVALID, "move",
+ "Invalid workspace number '%s'", argv[3]);
+ }
+ ws_name = join_args(argv + 3, argc - 3);
ws = workspace_by_number(ws_name);
} else {
ws_name = join_args(argv + 2, argc - 2);
@@ -231,7 +236,6 @@ static void workspace_move_to_output(struct sway_container *workspace,
seat_get_focus_inactive(seat, output);
container_add_child(output, workspace);
- wl_signal_emit(&workspace->events.reparent, old_output);
// If moving the last workspace from the old output, create a new workspace
// on the old output
@@ -245,7 +249,7 @@ static void workspace_move_to_output(struct sway_container *workspace,
// Try to remove an empty workspace from the destination output.
container_reap_empty_recursive(new_output_focus);
- container_sort_workspaces(output);
+ output_sort_workspaces(output);
seat_set_focus(seat, output);
workspace_output_raise_priority(workspace, old_output, output);
ipc_event_workspace(NULL, workspace, "move");
@@ -437,14 +441,14 @@ static struct cmd_results *move_to_scratchpad(struct sway_container *con) {
if (con->type == C_WORKSPACE) {
// Wrap the workspace's children in a container
struct sway_container *workspace = con;
- con = container_wrap_children(con);
+ con = workspace_wrap_children(con);
workspace->layout = L_HORIZ;
}
// If the container is in a floating split container,
// operate on the split container instead of the child.
if (container_is_floating_or_child(con)) {
- while (con->parent->layout != L_FLOATING) {
+ while (con->parent->type != C_WORKSPACE) {
con = con->parent;
}
}
diff --git a/sway/commands/nop.c b/sway/commands/nop.c
new file mode 100644
index 00000000..c12fe15a
--- /dev/null
+++ b/sway/commands/nop.c
@@ -0,0 +1,5 @@
+#include "sway/commands.h"
+
+struct cmd_results *cmd_nop(int argc, char **argv) {
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/rename.c b/sway/commands/rename.c
index c6952bbb..21d2aa64 100644
--- a/sway/commands/rename.c
+++ b/sway/commands/rename.c
@@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500
+#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "log.h"
@@ -6,6 +7,7 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
+#include "sway/output.h"
#include "sway/tree/container.h"
#include "sway/tree/workspace.h"
@@ -33,6 +35,10 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
}
} else if (strcasecmp(argv[1], "number") == 0) {
// 'rename workspace number x to new_name'
+ if (!isdigit(argv[2][0])) {
+ return cmd_results_new(CMD_INVALID, "rename",
+ "Invalid workspace number '%s'", argv[2]);
+ }
workspace = workspace_by_number(argv[2]);
while (argn < argc && strcasecmp(argv[argn], "to") != 0) {
++argn;
@@ -66,7 +72,8 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
strcasecmp(new_name, "next_on_output") == 0 ||
strcasecmp(new_name, "prev_on_output") == 0 ||
strcasecmp(new_name, "back_and_forth") == 0 ||
- strcasecmp(new_name, "current") == 0) {
+ strcasecmp(new_name, "current") == 0 ||
+ strcasecmp(new_name, "number") == 0) {
free(new_name);
return cmd_results_new(CMD_INVALID, "rename",
"Cannot use special workspace name '%s'", argv[argn]);
@@ -82,7 +89,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
free(workspace->name);
workspace->name = new_name;
- container_sort_workspaces(workspace->parent);
+ output_sort_workspaces(workspace->parent);
ipc_event_workspace(NULL, workspace, "rename");
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index 0f3005f4..ea1e36ff 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include <wlr/util/edges.h>
#include <wlr/util/log.h>
#include "sway/commands.h"
#include "sway/tree/arrange.h"
@@ -250,10 +251,10 @@ static void resize_tiled(struct sway_container *parent, int amount,
}
}
- enum resize_edge minor_edge = axis == RESIZE_AXIS_HORIZONTAL ?
- RESIZE_EDGE_LEFT : RESIZE_EDGE_TOP;
- enum resize_edge major_edge = axis == RESIZE_AXIS_HORIZONTAL ?
- RESIZE_EDGE_RIGHT : RESIZE_EDGE_BOTTOM;
+ enum wlr_edges minor_edge = axis == RESIZE_AXIS_HORIZONTAL ?
+ WLR_EDGE_LEFT : WLR_EDGE_TOP;
+ enum wlr_edges major_edge = axis == RESIZE_AXIS_HORIZONTAL ?
+ WLR_EDGE_RIGHT : WLR_EDGE_BOTTOM;
for (int i = 0; i < parent->parent->children->length; i++) {
struct sway_container *sibling = parent->parent->children->items[i];
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c
index 0e573aeb..7da20015 100644
--- a/sway/commands/scratchpad.c
+++ b/sway/commands/scratchpad.c
@@ -16,7 +16,7 @@ static void scratchpad_toggle_auto(void) {
// If the focus is in a floating split container,
// operate on the split container instead of the child.
if (container_is_floating_or_child(focus)) {
- while (focus->parent->layout != L_FLOATING) {
+ while (focus->parent->type != C_WORKSPACE) {
focus = focus->parent;
}
}
@@ -33,9 +33,8 @@ static void scratchpad_toggle_auto(void) {
// Check if there is an unfocused scratchpad window on the current workspace
// and focus it.
- for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) {
- struct sway_container *floater =
- ws->sway_workspace->floating->children->items[i];
+ for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
+ struct sway_container *floater = ws->sway_workspace->floating->items[i];
if (floater->scratchpad && focus != floater) {
wlr_log(WLR_DEBUG,
"Focusing other scratchpad window (%s) in this workspace",
@@ -103,7 +102,7 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
// If the container is in a floating split container,
// operate on the split container instead of the child.
if (container_is_floating_or_child(con)) {
- while (con->parent->layout != L_FLOATING) {
+ while (con->parent->type != C_WORKSPACE) {
con = con->parent;
}
}
diff --git a/sway/commands/set.c b/sway/commands/set.c
index ea388d3b..be51230b 100644
--- a/sway/commands/set.c
+++ b/sway/commands/set.c
@@ -25,23 +25,13 @@ void free_sway_variable(struct sway_variable *var) {
}
struct cmd_results *cmd_set(int argc, char **argv) {
- char *tmp;
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "set", EXPECTED_AT_LEAST, 2))) {
return error;
}
if (argv[0][0] != '$') {
- wlr_log(WLR_INFO, "Warning: variable '%s' doesn't start with $", argv[0]);
-
- size_t size = snprintf(NULL, 0, "$%s", argv[0]);
- tmp = malloc(size + 1);
- if (!tmp) {
- return cmd_results_new(CMD_FAILURE, "set", "Not possible to create variable $'%s'", argv[0]);
- }
- snprintf(tmp, size+1, "$%s", argv[0]);
-
- argv[0] = tmp;
+ return cmd_results_new(CMD_INVALID, "set", "variable '%s' must start with $", argv[0]);
}
struct sway_variable *var = NULL;
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c
index cf153a0a..dd7d170c 100644
--- a/sway/commands/show_marks.c
+++ b/sway/commands/show_marks.c
@@ -24,8 +24,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) {
config->show_marks = parse_boolean(argv[0], config->show_marks);
if (config->show_marks) {
- container_for_each_descendant(&root_container,
- rebuild_marks_iterator, NULL);
+ root_for_each_container(rebuild_marks_iterator, NULL);
}
for (int i = 0; i < root_container.children->length; ++i) {
diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c
index 732ccb98..a0dd7215 100644
--- a/sway/commands/sticky.c
+++ b/sway/commands/sticky.c
@@ -36,5 +36,21 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
container->is_sticky = wants_sticky;
+ if (wants_sticky) {
+ // move container to focused workspace
+ struct sway_container *output = container_parent(container, C_OUTPUT);
+ struct sway_seat *seat = input_manager_current_seat(input_manager);
+ struct sway_container *focus = seat_get_focus_inactive(seat, output);
+ struct sway_container *focused_workspace = container_parent(focus, C_WORKSPACE);
+ struct sway_container *current_workspace = container_parent(container, C_WORKSPACE);
+ if (current_workspace != focused_workspace) {
+ container_move_to(container, focused_workspace);
+ arrange_windows(focused_workspace);
+ if (!container_reap_empty(current_workspace)) {
+ arrange_windows(current_workspace);
+ }
+ }
+ }
+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index 4e3a9cce..f881a002 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -50,13 +50,13 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
if (strcasecmp(argv[2], "id") == 0) {
#ifdef HAVE_XWAYLAND
xcb_window_t id = strtol(value, NULL, 0);
- other = container_find(&root_container, test_id, (void *)&id);
+ other = root_find_container(test_id, (void *)&id);
#endif
} else if (strcasecmp(argv[2], "con_id") == 0) {
size_t con_id = atoi(value);
- other = container_find(&root_container, test_con_id, (void *)con_id);
+ other = root_find_container(test_con_id, (void *)con_id);
} else if (strcasecmp(argv[2], "mark") == 0) {
- other = container_find(&root_container, test_mark, (void *)value);
+ other = root_find_container(test_mark, (void *)value);
} else {
free(value);
return cmd_results_new(CMD_INVALID, "swap", EXPECTED_SYNTAX);
@@ -72,7 +72,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|| container_has_ancestor(other, current)) {
error = cmd_results_new(CMD_FAILURE, "swap",
"Cannot swap ancestor and descendant");
- } else if (current->layout == L_FLOATING || other->layout == L_FLOATING) {
+ } else if (container_is_floating(current) || container_is_floating(other)) {
error = cmd_results_new(CMD_FAILURE, "swap",
"Swapping with floating containers is not supported");
}
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c
index 44ceccee..c183785b 100644
--- a/sway/commands/unmark.c
+++ b/sway/commands/unmark.c
@@ -52,8 +52,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
view_find_and_unmark(mark);
} else {
// Remove all marks from all views
- container_for_each_descendant(&root_container,
- remove_all_marks_iterator, NULL);
+ root_for_each_container(remove_all_marks_iterator, NULL);
}
free(mark);
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index f5558bb4..ceb4cd6e 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500
+#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
@@ -60,9 +61,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
struct sway_container *ws = NULL;
if (strcasecmp(argv[0], "number") == 0) {
if (argc < 2) {
- cmd_results_new(CMD_INVALID, "workspace",
+ return cmd_results_new(CMD_INVALID, "workspace",
"Expected workspace number");
}
+ if (!isdigit(argv[1][0])) {
+ return cmd_results_new(CMD_INVALID, "workspace",
+ "Invalid workspace number '%s'", argv[1]);
+ }
if (!(ws = workspace_by_number(argv[1]))) {
char *name = join_args(argv + 1, argc - 1);
ws = workspace_create(NULL, name);