diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-05-26 11:02:21 -0400 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-05-26 11:05:02 -0400 |
commit | 569f4e0e4c75562c38848ea0bbaeb3b2f230b1a9 (patch) | |
tree | 02716bf706478cc5ca73d892dfc34c8a327897b3 /sway/commands/swap.c | |
parent | Replace oft-failing abort with if statement (diff) | |
download | sway-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.c | 80 |
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 | |||
8 | static const char* EXPECTED_SYNTAX = | ||
9 | "Expected 'swap container with id|con_id|mark <arg>'"; | ||
10 | |||
11 | static bool test_con_id(struct sway_container *container, void *con_id) { | ||
12 | return container->id == (size_t)con_id; | ||
13 | } | ||
14 | |||
15 | static 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 | |||
22 | static 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 | |||
30 | struct 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 | } | ||