aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/swap.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-05-26 11:02:21 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-05-26 11:05:02 -0400
commit569f4e0e4c75562c38848ea0bbaeb3b2f230b1a9 (patch)
tree02716bf706478cc5ca73d892dfc34c8a327897b3 /sway/commands/swap.c
parentReplace oft-failing abort with if statement (diff)
downloadsway-569f4e0e4c75562c38848ea0bbaeb3b2f230b1a9.tar.gz
sway-569f4e0e4c75562c38848ea0bbaeb3b2f230b1a9.tar.zst
sway-569f4e0e4c75562c38848ea0bbaeb3b2f230b1a9.zip
Implement swap command
Diffstat (limited to 'sway/commands/swap.c')
-rw-r--r--sway/commands/swap.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
new file mode 100644
index 00000000..e925ad33
--- /dev/null
+++ b/sway/commands/swap.c
@@ -0,0 +1,80 @@
1#include <strings.h>
2#include <wlr/util/log.h>
3#include "sway/commands.h"
4#include "sway/tree/layout.h"
5#include "sway/tree/view.h"
6#include "stringop.h"
7
8static const char* EXPECTED_SYNTAX =
9 "Expected 'swap container with id|con_id|mark <arg>'";
10
11static bool test_con_id(struct sway_container *container, void *con_id) {
12 return container->id == (size_t)con_id;
13}
14
15static bool test_id(struct sway_container *container, void *id) {
16 xcb_window_t *wid = id;
17 return (container->type == C_VIEW
18 && container->sway_view->type == SWAY_VIEW_XWAYLAND
19 && container->sway_view->wlr_xwayland_surface->window_id == *wid);
20}
21
22static bool test_mark(struct sway_container *container, void *mark) {
23 if (container->type == C_VIEW && container->sway_view->marks->length) {
24 return !list_seq_find(container->sway_view->marks,
25 (int (*)(const void *, const void *))strcmp, mark);
26 }
27 return false;
28}
29
30struct cmd_results *cmd_swap(int argc, char **argv) {
31 struct cmd_results *error = NULL;
32 if ((error = checkarg(argc, "swap", EXPECTED_AT_LEAST, 4))) {
33 return error;
34 }
35
36 if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) {
37 return cmd_results_new(CMD_INVALID, "swap", EXPECTED_SYNTAX);
38 }
39
40 struct sway_container *current = config->handler_context.current_container;
41 struct sway_container *other;
42
43 char *value = join_args(argv + 3, argc - 3);
44 if (strcasecmp(argv[2], "id") == 0) {
45 xcb_window_t id = strtol(value, NULL, 0);
46 other = container_find(&root_container, test_id, (void *)&id);
47 } else if (strcasecmp(argv[2], "con_id") == 0) {
48 size_t con_id = atoi(value);
49 other = container_find(&root_container, test_con_id, (void *)con_id);
50 } else if (strcasecmp(argv[2], "mark") == 0) {
51 other = container_find(&root_container, test_mark, (void *)value);
52 } else {
53 free(value);
54 return cmd_results_new(CMD_INVALID, "swap", EXPECTED_SYNTAX);
55 }
56
57 if (!other) {
58 error = cmd_results_new(CMD_FAILURE, "swap",
59 "Failed to find %s '%s'", argv[2], value);
60 } else if (current->type < C_CONTAINER || other->type < C_CONTAINER) {
61 error = cmd_results_new(CMD_FAILURE, "swap",
62 "Can only swap with containers and views");
63 } else if (container_has_anscestor(current, other)
64 || container_has_anscestor(other, current)) {
65 error = cmd_results_new(CMD_FAILURE, "swap",
66 "Cannot swap ancestor and descendant");
67 } else if (current->layout == L_FLOATING || other->layout == L_FLOATING) {
68 error = cmd_results_new(CMD_FAILURE, "swap",
69 "Swapping with floating containers is not supported");
70 }
71
72 free(value);
73
74 if (error) {
75 return error;
76 }
77
78 container_swap(current, other);
79 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
80}