diff options
Diffstat (limited to 'sway/commands')
85 files changed, 1065 insertions, 634 deletions
diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 976bc3cc..bf95cf00 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
@@ -17,7 +16,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) { | |||
17 | char *err_str = NULL; | 16 | char *err_str = NULL; |
18 | struct criteria *criteria = criteria_parse(argv[0], &err_str); | 17 | struct criteria *criteria = criteria_parse(argv[0], &err_str); |
19 | if (!criteria) { | 18 | if (!criteria) { |
20 | error = cmd_results_new(CMD_INVALID, err_str); | 19 | error = cmd_results_new(CMD_INVALID, "%s", err_str); |
21 | free(err_str); | 20 | free(err_str); |
22 | return error; | 21 | return error; |
23 | } | 22 | } |
diff --git a/sway/commands/bar.c b/sway/commands/bar.c index d42b7fc2..635e895b 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -8,7 +7,7 @@ | |||
8 | #include "log.h" | 7 | #include "log.h" |
9 | 8 | ||
10 | // Must be in alphabetical order for bsearch | 9 | // Must be in alphabetical order for bsearch |
11 | static struct cmd_handler bar_handlers[] = { | 10 | static const struct cmd_handler bar_handlers[] = { |
12 | { "bindcode", bar_cmd_bindcode }, | 11 | { "bindcode", bar_cmd_bindcode }, |
13 | { "binding_mode_indicator", bar_cmd_binding_mode_indicator }, | 12 | { "binding_mode_indicator", bar_cmd_binding_mode_indicator }, |
14 | { "bindsym", bar_cmd_bindsym }, | 13 | { "bindsym", bar_cmd_bindsym }, |
@@ -41,7 +40,7 @@ static struct cmd_handler bar_handlers[] = { | |||
41 | }; | 40 | }; |
42 | 41 | ||
43 | // Must be in alphabetical order for bsearch | 42 | // Must be in alphabetical order for bsearch |
44 | static struct cmd_handler bar_config_handlers[] = { | 43 | static const struct cmd_handler bar_config_handlers[] = { |
45 | { "id", bar_cmd_id }, | 44 | { "id", bar_cmd_id }, |
46 | { "swaybar_command", bar_cmd_swaybar_command }, | 45 | { "swaybar_command", bar_cmd_swaybar_command }, |
47 | }; | 46 | }; |
@@ -73,12 +72,10 @@ struct cmd_results *cmd_bar(int argc, char **argv) { | |||
73 | } | 72 | } |
74 | ++argv; --argc; | 73 | ++argv; --argc; |
75 | } else if (config->reading && !config->current_bar) { | 74 | } else if (config->reading && !config->current_bar) { |
76 | int len = snprintf(NULL, 0, "bar-%d", config->bars->length) + 1; | 75 | id = format_str("bar-%d", config->bars->length); |
77 | id = malloc(len * sizeof(char)); | ||
78 | if (!id) { | 76 | if (!id) { |
79 | return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id"); | 77 | return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id"); |
80 | } | 78 | } |
81 | snprintf(id, len, "bar-%d", config->bars->length); | ||
82 | } else if (!config->reading && strcmp(argv[0], "mode") != 0 && | 79 | } else if (!config->reading && strcmp(argv[0], "mode") != 0 && |
83 | strcmp(argv[0], "hidden_state") != 0) { | 80 | strcmp(argv[0], "hidden_state") != 0) { |
84 | if (is_subcommand(argv[0])) { | 81 | if (is_subcommand(argv[0])) { |
@@ -116,6 +113,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) { | |||
116 | if (res && res->status != CMD_SUCCESS) { | 113 | if (res && res->status != CMD_SUCCESS) { |
117 | if (id) { | 114 | if (id) { |
118 | free_bar_config(config->current_bar); | 115 | free_bar_config(config->current_bar); |
116 | config->current_bar = NULL; | ||
119 | id = NULL; | 117 | id = NULL; |
120 | } | 118 | } |
121 | return res; | 119 | return res; |
diff --git a/sway/commands/bar/bind.c b/sway/commands/bar/bind.c index b4b5bc45..8a837e3f 100644 --- a/sway/commands/bar/bind.c +++ b/sway/commands/bar/bind.c | |||
@@ -96,7 +96,7 @@ static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code, | |||
96 | } | 96 | } |
97 | if (message) { | 97 | if (message) { |
98 | free_bar_binding(binding); | 98 | free_bar_binding(binding); |
99 | error = cmd_results_new(CMD_INVALID, message); | 99 | error = cmd_results_new(CMD_INVALID, "%s", message); |
100 | free(message); | 100 | free(message); |
101 | return error; | 101 | return error; |
102 | } else if (!binding->button) { | 102 | } else if (!binding->button) { |
diff --git a/sway/commands/bar/colors.c b/sway/commands/bar/colors.c index 2d5b22bf..275fa3c6 100644 --- a/sway/commands/bar/colors.c +++ b/sway/commands/bar/colors.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "util.h" | 4 | #include "util.h" |
5 | 5 | ||
6 | // Must be in alphabetical order for bsearch | 6 | // Must be in alphabetical order for bsearch |
7 | static struct cmd_handler bar_colors_handlers[] = { | 7 | static const struct cmd_handler bar_colors_handlers[] = { |
8 | { "active_workspace", bar_colors_cmd_active_workspace }, | 8 | { "active_workspace", bar_colors_cmd_active_workspace }, |
9 | { "background", bar_colors_cmd_background }, | 9 | { "background", bar_colors_cmd_background }, |
10 | { "binding_mode", bar_colors_cmd_binding_mode }, | 10 | { "binding_mode", bar_colors_cmd_binding_mode }, |
diff --git a/sway/commands/bar/font.c b/sway/commands/bar/font.c index 62987f3e..0c074679 100644 --- a/sway/commands/bar/font.c +++ b/sway/commands/bar/font.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
@@ -11,7 +10,20 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) { | |||
11 | } | 10 | } |
12 | char *font = join_args(argv, argc); | 11 | char *font = join_args(argv, argc); |
13 | free(config->current_bar->font); | 12 | free(config->current_bar->font); |
14 | config->current_bar->font = font; | 13 | |
14 | if (strncmp(font, "pango:", 6) == 0) { | ||
15 | if (config->current_bar->pango_markup == PANGO_MARKUP_DEFAULT) { | ||
16 | config->current_bar->pango_markup = true; | ||
17 | } | ||
18 | config->current_bar->font = strdup(font + 6); | ||
19 | } else { | ||
20 | if (config->current_bar->pango_markup == PANGO_MARKUP_DEFAULT) { | ||
21 | config->current_bar->pango_markup = false; | ||
22 | } | ||
23 | config->current_bar->font = strdup(font); | ||
24 | } | ||
25 | |||
26 | free(font); | ||
15 | sway_log(SWAY_DEBUG, "Settings font '%s' for bar: %s", | 27 | sway_log(SWAY_DEBUG, "Settings font '%s' for bar: %s", |
16 | config->current_bar->font, config->current_bar->id); | 28 | config->current_bar->font, config->current_bar->id); |
17 | return cmd_results_new(CMD_SUCCESS, NULL); | 29 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c index 1f08a5d2..7b38831e 100644 --- a/sway/commands/bar/hidden_state.c +++ b/sway/commands/bar/hidden_state.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
@@ -54,7 +53,7 @@ struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) { | |||
54 | } | 53 | } |
55 | 54 | ||
56 | const char *state = argv[0]; | 55 | const char *state = argv[0]; |
57 | if (config->reading) { | 56 | if (config->current_bar) { |
58 | error = bar_set_hidden_state(config->current_bar, state); | 57 | error = bar_set_hidden_state(config->current_bar, state); |
59 | } else { | 58 | } else { |
60 | const char *id = argc == 2 ? argv[1] : NULL; | 59 | const char *id = argc == 2 ? argv[1] : NULL; |
diff --git a/sway/commands/bar/icon_theme.c b/sway/commands/bar/icon_theme.c index 6ac07843..fee21709 100644 --- a/sway/commands/bar/icon_theme.c +++ b/sway/commands/bar/icon_theme.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/id.c b/sway/commands/bar/id.c index a9a61743..46cf4ca9 100644 --- a/sway/commands/bar/id.c +++ b/sway/commands/bar/id.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 8b3fb275..d69e910b 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
@@ -58,7 +57,7 @@ struct cmd_results *bar_cmd_mode(int argc, char **argv) { | |||
58 | } | 57 | } |
59 | 58 | ||
60 | const char *mode = argv[0]; | 59 | const char *mode = argv[0]; |
61 | if (config->reading) { | 60 | if (config->current_bar) { |
62 | error = bar_set_mode(config->current_bar, mode); | 61 | error = bar_set_mode(config->current_bar, mode); |
63 | } else { | 62 | } else { |
64 | const char *id = argc == 2 ? argv[1] : NULL; | 63 | const char *id = argc == 2 ? argv[1] : NULL; |
diff --git a/sway/commands/bar/output.c b/sway/commands/bar/output.c index cac1d056..51730176 100644 --- a/sway/commands/bar/output.c +++ b/sway/commands/bar/output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/position.c b/sway/commands/bar/position.c index b207de0b..94f530ec 100644 --- a/sway/commands/bar/position.c +++ b/sway/commands/bar/position.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bar/separator_symbol.c b/sway/commands/bar/separator_symbol.c index 6737d4d2..50e9a873 100644 --- a/sway/commands/bar/separator_symbol.c +++ b/sway/commands/bar/separator_symbol.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/bar/tray_bind.c b/sway/commands/bar/tray_bind.c index 243834ba..3dc9bc4c 100644 --- a/sway/commands/bar/tray_bind.c +++ b/sway/commands/bar/tray_bind.c | |||
@@ -26,7 +26,7 @@ static struct cmd_results *tray_bind(int argc, char **argv, bool code) { | |||
26 | } | 26 | } |
27 | if (message) { | 27 | if (message) { |
28 | free(binding); | 28 | free(binding); |
29 | error = cmd_results_new(CMD_INVALID, message); | 29 | error = cmd_results_new(CMD_INVALID, "%s", message); |
30 | free(message); | 30 | free(message); |
31 | return error; | 31 | return error; |
32 | } else if (!binding->button) { | 32 | } else if (!binding->button) { |
diff --git a/sway/commands/bar/tray_output.c b/sway/commands/bar/tray_output.c index eb3b486e..679facf7 100644 --- a/sway/commands/bar/tray_output.c +++ b/sway/commands/bar/tray_output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index f6e58d99..268f2855 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <libevdev/libevdev.h> | 1 | #include <libevdev/libevdev.h> |
3 | #include <linux/input-event-codes.h> | 2 | #include <linux/input-event-codes.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -8,6 +7,7 @@ | |||
8 | #include <wlr/types/wlr_cursor.h> | 7 | #include <wlr/types/wlr_cursor.h> |
9 | #include "sway/commands.h" | 8 | #include "sway/commands.h" |
10 | #include "sway/config.h" | 9 | #include "sway/config.h" |
10 | #include "sway/desktop/transaction.h" | ||
11 | #include "sway/input/cursor.h" | 11 | #include "sway/input/cursor.h" |
12 | #include "sway/input/keyboard.h" | 12 | #include "sway/input/keyboard.h" |
13 | #include "sway/ipc-server.h" | 13 | #include "sway/ipc-server.h" |
@@ -46,7 +46,7 @@ static bool binding_switch_compare(struct sway_switch_binding *binding_a, | |||
46 | if (binding_a->type != binding_b->type) { | 46 | if (binding_a->type != binding_b->type) { |
47 | return false; | 47 | return false; |
48 | } | 48 | } |
49 | if (binding_a->state != binding_b->state) { | 49 | if (binding_a->trigger != binding_b->trigger) { |
50 | return false; | 50 | return false; |
51 | } | 51 | } |
52 | if ((binding_a->flags & BINDING_LOCKED) != | 52 | if ((binding_a->flags & BINDING_LOCKED) != |
@@ -126,7 +126,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key, | |||
126 | if (!button) { | 126 | if (!button) { |
127 | if (message) { | 127 | if (message) { |
128 | struct cmd_results *error = | 128 | struct cmd_results *error = |
129 | cmd_results_new(CMD_INVALID, message); | 129 | cmd_results_new(CMD_INVALID, "%s", message); |
130 | free(message); | 130 | free(message); |
131 | return error; | 131 | return error; |
132 | } else { | 132 | } else { |
@@ -142,7 +142,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key, | |||
142 | if (!button) { | 142 | if (!button) { |
143 | if (message) { | 143 | if (message) { |
144 | struct cmd_results *error = | 144 | struct cmd_results *error = |
145 | cmd_results_new(CMD_INVALID, message); | 145 | cmd_results_new(CMD_INVALID, "%s", message); |
146 | free(message); | 146 | free(message); |
147 | return error; | 147 | return error; |
148 | } else { | 148 | } else { |
@@ -181,7 +181,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key, | |||
181 | uint32_t button = get_mouse_bindsym(name, &message); | 181 | uint32_t button = get_mouse_bindsym(name, &message); |
182 | if (message) { | 182 | if (message) { |
183 | struct cmd_results *error = | 183 | struct cmd_results *error = |
184 | cmd_results_new(CMD_INVALID, message); | 184 | cmd_results_new(CMD_INVALID, "%s", message); |
185 | free(message); | 185 | free(message); |
186 | return error; | 186 | return error; |
187 | } else if (button) { | 187 | } else if (button) { |
@@ -371,6 +371,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
371 | strlen("--input-device=")) == 0) { | 371 | strlen("--input-device=")) == 0) { |
372 | free(binding->input); | 372 | free(binding->input); |
373 | binding->input = strdup(argv[0] + strlen("--input-device=")); | 373 | binding->input = strdup(argv[0] + strlen("--input-device=")); |
374 | strip_quotes(binding->input); | ||
374 | } else if (strcmp("--no-warn", argv[0]) == 0) { | 375 | } else if (strcmp("--no-warn", argv[0]) == 0) { |
375 | warn = false; | 376 | warn = false; |
376 | } else if (strcmp("--no-repeat", argv[0]) == 0) { | 377 | } else if (strcmp("--no-repeat", argv[0]) == 0) { |
@@ -537,7 +538,7 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv, | |||
537 | free_switch_binding(binding); | 538 | free_switch_binding(binding); |
538 | return cmd_results_new(CMD_FAILURE, | 539 | return cmd_results_new(CMD_FAILURE, |
539 | "Invalid %s command (expected binding with the form " | 540 | "Invalid %s command (expected binding with the form " |
540 | "<switch>:<state>)", bindtype, argc); | 541 | "<switch>:<state>)", bindtype); |
541 | } | 542 | } |
542 | if (strcmp(split->items[0], "tablet") == 0) { | 543 | if (strcmp(split->items[0], "tablet") == 0) { |
543 | binding->type = WLR_SWITCH_TYPE_TABLET_MODE; | 544 | binding->type = WLR_SWITCH_TYPE_TABLET_MODE; |
@@ -547,20 +548,21 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv, | |||
547 | free_switch_binding(binding); | 548 | free_switch_binding(binding); |
548 | return cmd_results_new(CMD_FAILURE, | 549 | return cmd_results_new(CMD_FAILURE, |
549 | "Invalid %s command (expected switch binding: " | 550 | "Invalid %s command (expected switch binding: " |
550 | "unknown switch %s)", bindtype, split->items[0]); | 551 | "unknown switch %s)", bindtype, |
552 | (const char *)split->items[0]); | ||
551 | } | 553 | } |
552 | if (strcmp(split->items[1], "on") == 0) { | 554 | if (strcmp(split->items[1], "on") == 0) { |
553 | binding->state = WLR_SWITCH_STATE_ON; | 555 | binding->trigger = SWAY_SWITCH_TRIGGER_ON; |
554 | } else if (strcmp(split->items[1], "off") == 0) { | 556 | } else if (strcmp(split->items[1], "off") == 0) { |
555 | binding->state = WLR_SWITCH_STATE_OFF; | 557 | binding->trigger = SWAY_SWITCH_TRIGGER_OFF; |
556 | } else if (strcmp(split->items[1], "toggle") == 0) { | 558 | } else if (strcmp(split->items[1], "toggle") == 0) { |
557 | binding->state = WLR_SWITCH_STATE_TOGGLE; | 559 | binding->trigger = SWAY_SWITCH_TRIGGER_TOGGLE; |
558 | } else { | 560 | } else { |
559 | free_switch_binding(binding); | 561 | free_switch_binding(binding); |
560 | return cmd_results_new(CMD_FAILURE, | 562 | return cmd_results_new(CMD_FAILURE, |
561 | "Invalid %s command " | 563 | "Invalid %s command " |
562 | "(expected switch state: unknown state %d)", | 564 | "(expected switch state: unknown state %s)", |
563 | bindtype, split->items[0]); | 565 | bindtype, (const char *)split->items[1]); |
564 | } | 566 | } |
565 | list_free_items_and_destroy(split); | 567 | list_free_items_and_destroy(split); |
566 | 568 | ||
@@ -642,6 +644,8 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) | |||
642 | if (success) { | 644 | if (success) { |
643 | ipc_event_binding(binding); | 645 | ipc_event_binding(binding); |
644 | } | 646 | } |
647 | |||
648 | transaction_commit_dirty(); | ||
645 | } | 649 | } |
646 | 650 | ||
647 | /** | 651 | /** |
diff --git a/sway/commands/border.c b/sway/commands/border.c index 647663ac..7818fc96 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c | |||
@@ -19,11 +19,11 @@ static void set_border(struct sway_container *con, | |||
19 | view_set_csd_from_server(con->view, false); | 19 | view_set_csd_from_server(con->view, false); |
20 | } else if (!con->view->using_csd && new_border == B_CSD) { | 20 | } else if (!con->view->using_csd && new_border == B_CSD) { |
21 | view_set_csd_from_server(con->view, true); | 21 | view_set_csd_from_server(con->view, true); |
22 | con->saved_border = con->border; | 22 | con->saved_border = con->pending.border; |
23 | } | 23 | } |
24 | } | 24 | } |
25 | if (new_border != B_CSD || container_is_floating(con)) { | 25 | if (new_border != B_CSD || container_is_floating(con)) { |
26 | con->border = new_border; | 26 | con->pending.border = new_border; |
27 | } | 27 | } |
28 | if (con->view) { | 28 | if (con->view) { |
29 | con->view->using_csd = new_border == B_CSD; | 29 | con->view->using_csd = new_border == B_CSD; |
@@ -35,7 +35,7 @@ static void border_toggle(struct sway_container *con) { | |||
35 | set_border(con, B_NONE); | 35 | set_border(con, B_NONE); |
36 | return; | 36 | return; |
37 | } | 37 | } |
38 | switch (con->border) { | 38 | switch (con->pending.border) { |
39 | case B_NONE: | 39 | case B_NONE: |
40 | set_border(con, B_PIXEL); | 40 | set_border(con, B_PIXEL); |
41 | break; | 41 | break; |
@@ -88,7 +88,7 @@ struct cmd_results *cmd_border(int argc, char **argv) { | |||
88 | "or 'border pixel <px>'"); | 88 | "or 'border pixel <px>'"); |
89 | } | 89 | } |
90 | if (argc == 2) { | 90 | if (argc == 2) { |
91 | container->border_thickness = atoi(argv[1]); | 91 | container->pending.border_thickness = atoi(argv[1]); |
92 | } | 92 | } |
93 | 93 | ||
94 | if (container_is_floating(container)) { | 94 | if (container_is_floating(container)) { |
diff --git a/sway/commands/client.c b/sway/commands/client.c index dd0694df..fd2ac7a8 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c | |||
@@ -5,9 +5,8 @@ | |||
5 | #include "sway/tree/container.h" | 5 | #include "sway/tree/container.h" |
6 | #include "util.h" | 6 | #include "util.h" |
7 | 7 | ||
8 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 8 | static void container_update_iterator(struct sway_container *con, void *data) { |
9 | container_update_marks_textures(con); | 9 | container_update(con); |
10 | container_update_title_textures(con); | ||
11 | } | 10 | } |
12 | 11 | ||
13 | static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | 12 | static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, |
@@ -18,6 +17,12 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | |||
18 | return error; | 17 | return error; |
19 | } | 18 | } |
20 | 19 | ||
20 | if (argc > 3 && strcmp(cmd_name, "client.focused_tab_title") == 0) { | ||
21 | sway_log(SWAY_ERROR, | ||
22 | "Warning: indicator and child_border colors have no effect for %s", | ||
23 | cmd_name); | ||
24 | } | ||
25 | |||
21 | struct border_colors colors = {0}; | 26 | struct border_colors colors = {0}; |
22 | const char *ind_hex = argc > 3 ? argv[3] : default_indicator; | 27 | const char *ind_hex = argc > 3 ? argv[3] : default_indicator; |
23 | const char *child_hex = argc > 4 ? argv[4] : argv[1]; // def to background | 28 | const char *child_hex = argc > 4 ? argv[4] : argv[1]; // def to background |
@@ -45,12 +50,7 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | |||
45 | memcpy(class, &colors, sizeof(struct border_colors)); | 50 | memcpy(class, &colors, sizeof(struct border_colors)); |
46 | 51 | ||
47 | if (config->active) { | 52 | if (config->active) { |
48 | root_for_each_container(rebuild_textures_iterator, NULL); | 53 | root_for_each_container(container_update_iterator, NULL); |
49 | |||
50 | for (int i = 0; i < root->outputs->length; ++i) { | ||
51 | struct sway_output *output = root->outputs->items[i]; | ||
52 | output_damage_whole(output); | ||
53 | } | ||
54 | } | 54 | } |
55 | 55 | ||
56 | return cmd_results_new(CMD_SUCCESS, NULL); | 56 | return cmd_results_new(CMD_SUCCESS, NULL); |
@@ -80,3 +80,13 @@ struct cmd_results *cmd_client_noop(int argc, char **argv) { | |||
80 | sway_log(SWAY_INFO, "Warning: %s is ignored by sway", argv[-1]); | 80 | sway_log(SWAY_INFO, "Warning: %s is ignored by sway", argv[-1]); |
81 | return cmd_results_new(CMD_SUCCESS, NULL); | 81 | return cmd_results_new(CMD_SUCCESS, NULL); |
82 | } | 82 | } |
83 | |||
84 | struct cmd_results *cmd_client_focused_tab_title(int argc, char **argv) { | ||
85 | struct cmd_results *result = handle_command(argc, argv, | ||
86 | "client.focused_tab_title", | ||
87 | &config->border_colors.focused_tab_title, "#2e9ef4ff"); | ||
88 | if (result && result->status == CMD_SUCCESS) { | ||
89 | config->has_focused_tab_title = true; | ||
90 | } | ||
91 | return result; | ||
92 | } | ||
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index 39e48a44..8bc1048c 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <stdint.h> | 2 | #include <stdint.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -7,6 +6,8 @@ | |||
7 | #include <signal.h> | 6 | #include <signal.h> |
8 | #include "sway/commands.h" | 7 | #include "sway/commands.h" |
9 | #include "sway/config.h" | 8 | #include "sway/config.h" |
9 | #include "sway/server.h" | ||
10 | #include "sway/desktop/launcher.h" | ||
10 | #include "sway/tree/container.h" | 11 | #include "sway/tree/container.h" |
11 | #include "sway/tree/root.h" | 12 | #include "sway/tree/root.h" |
12 | #include "sway/tree/workspace.h" | 13 | #include "sway/tree/workspace.h" |
@@ -24,11 +25,22 @@ struct cmd_results *cmd_exec_validate(int argc, char **argv) { | |||
24 | return error; | 25 | return error; |
25 | } | 26 | } |
26 | 27 | ||
28 | static void export_xdga_token(struct launcher_ctx *ctx) { | ||
29 | const char *token = launcher_ctx_get_token_name(ctx); | ||
30 | setenv("XDG_ACTIVATION_TOKEN", token, 1); | ||
31 | } | ||
32 | |||
33 | static void export_startup_id(struct launcher_ctx *ctx) { | ||
34 | const char *token = launcher_ctx_get_token_name(ctx); | ||
35 | setenv("DESKTOP_STARTUP_ID", token, 1); | ||
36 | } | ||
37 | |||
27 | struct cmd_results *cmd_exec_process(int argc, char **argv) { | 38 | struct cmd_results *cmd_exec_process(int argc, char **argv) { |
28 | struct cmd_results *error = NULL; | 39 | struct cmd_results *error = NULL; |
29 | char *tmp = NULL; | 40 | char *cmd = NULL; |
41 | bool no_startup_id = false; | ||
30 | if (strcmp(argv[0], "--no-startup-id") == 0) { | 42 | if (strcmp(argv[0], "--no-startup-id") == 0) { |
31 | sway_log(SWAY_INFO, "exec switch '--no-startup-id' not supported, ignored."); | 43 | no_startup_id = true; |
32 | --argc; ++argv; | 44 | --argc; ++argv; |
33 | if ((error = checkarg(argc, argv[-1], EXPECTED_AT_LEAST, 1))) { | 45 | if ((error = checkarg(argc, argv[-1], EXPECTED_AT_LEAST, 1))) { |
34 | return error; | 46 | return error; |
@@ -36,17 +48,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { | |||
36 | } | 48 | } |
37 | 49 | ||
38 | if (argc == 1 && (argv[0][0] == '\'' || argv[0][0] == '"')) { | 50 | if (argc == 1 && (argv[0][0] == '\'' || argv[0][0] == '"')) { |
39 | tmp = strdup(argv[0]); | 51 | cmd = strdup(argv[0]); |
40 | strip_quotes(tmp); | 52 | strip_quotes(cmd); |
41 | } else { | 53 | } else { |
42 | tmp = join_args(argv, argc); | 54 | cmd = join_args(argv, argc); |
43 | } | 55 | } |
44 | 56 | ||
45 | // Put argument into cmd array | ||
46 | char cmd[4096]; | ||
47 | strncpy(cmd, tmp, sizeof(cmd) - 1); | ||
48 | cmd[sizeof(cmd) - 1] = 0; | ||
49 | free(tmp); | ||
50 | sway_log(SWAY_DEBUG, "Executing %s", cmd); | 57 | sway_log(SWAY_DEBUG, "Executing %s", cmd); |
51 | 58 | ||
52 | int fd[2]; | 59 | int fd[2]; |
@@ -55,18 +62,28 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { | |||
55 | } | 62 | } |
56 | 63 | ||
57 | pid_t pid, child; | 64 | pid_t pid, child; |
65 | struct launcher_ctx *ctx = launcher_ctx_create_internal(); | ||
58 | // Fork process | 66 | // Fork process |
59 | if ((pid = fork()) == 0) { | 67 | if ((pid = fork()) == 0) { |
60 | // Fork child process again | 68 | // Fork child process again |
69 | restore_nofile_limit(); | ||
61 | setsid(); | 70 | setsid(); |
62 | sigset_t set; | 71 | sigset_t set; |
63 | sigemptyset(&set); | 72 | sigemptyset(&set); |
64 | sigprocmask(SIG_SETMASK, &set, NULL); | 73 | sigprocmask(SIG_SETMASK, &set, NULL); |
74 | signal(SIGPIPE, SIG_DFL); | ||
65 | close(fd[0]); | 75 | close(fd[0]); |
66 | if ((child = fork()) == 0) { | 76 | if ((child = fork()) == 0) { |
67 | close(fd[1]); | 77 | close(fd[1]); |
68 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); | 78 | if (ctx) { |
69 | _exit(0); | 79 | export_xdga_token(ctx); |
80 | } | ||
81 | if (ctx && !no_startup_id) { | ||
82 | export_startup_id(ctx); | ||
83 | } | ||
84 | execlp("sh", "sh", "-c", cmd, (void *)NULL); | ||
85 | sway_log_errno(SWAY_ERROR, "execlp failed"); | ||
86 | _exit(1); | ||
70 | } | 87 | } |
71 | ssize_t s = 0; | 88 | ssize_t s = 0; |
72 | while ((size_t)s < sizeof(pid_t)) { | 89 | while ((size_t)s < sizeof(pid_t)) { |
@@ -75,10 +92,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { | |||
75 | close(fd[1]); | 92 | close(fd[1]); |
76 | _exit(0); // Close child process | 93 | _exit(0); // Close child process |
77 | } else if (pid < 0) { | 94 | } else if (pid < 0) { |
95 | free(cmd); | ||
78 | close(fd[0]); | 96 | close(fd[0]); |
79 | close(fd[1]); | 97 | close(fd[1]); |
80 | return cmd_results_new(CMD_FAILURE, "fork() failed"); | 98 | return cmd_results_new(CMD_FAILURE, "fork() failed"); |
81 | } | 99 | } |
100 | free(cmd); | ||
82 | close(fd[1]); // close write | 101 | close(fd[1]); // close write |
83 | ssize_t s = 0; | 102 | ssize_t s = 0; |
84 | while ((size_t)s < sizeof(pid_t)) { | 103 | while ((size_t)s < sizeof(pid_t)) { |
@@ -89,8 +108,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { | |||
89 | waitpid(pid, NULL, 0); | 108 | waitpid(pid, NULL, 0); |
90 | if (child > 0) { | 109 | if (child > 0) { |
91 | sway_log(SWAY_DEBUG, "Child process created with pid %d", child); | 110 | sway_log(SWAY_DEBUG, "Child process created with pid %d", child); |
92 | root_record_workspace_pid(child); | 111 | if (ctx != NULL) { |
112 | sway_log(SWAY_DEBUG, "Recording workspace for process %d", child); | ||
113 | ctx->pid = child; | ||
114 | } | ||
93 | } else { | 115 | } else { |
116 | launcher_ctx_destroy(ctx); | ||
94 | return cmd_results_new(CMD_FAILURE, "Second fork() failed"); | 117 | return cmd_results_new(CMD_FAILURE, "Second fork() failed"); |
95 | } | 118 | } |
96 | 119 | ||
diff --git a/sway/commands/floating.c b/sway/commands/floating.c index ce123345..74f6522c 100644 --- a/sway/commands/floating.c +++ b/sway/commands/floating.c | |||
@@ -40,8 +40,8 @@ struct cmd_results *cmd_floating(int argc, char **argv) { | |||
40 | // If the container is in a floating split container, | 40 | // If the container is in a floating split container, |
41 | // operate on the split container instead of the child. | 41 | // operate on the split container instead of the child. |
42 | if (container_is_floating_or_child(container)) { | 42 | if (container_is_floating_or_child(container)) { |
43 | while (container->parent) { | 43 | while (container->pending.parent) { |
44 | container = container->parent; | 44 | container = container->pending.parent; |
45 | } | 45 | } |
46 | } | 46 | } |
47 | 47 | ||
@@ -51,8 +51,8 @@ struct cmd_results *cmd_floating(int argc, char **argv) { | |||
51 | container_set_floating(container, wants_floating); | 51 | container_set_floating(container, wants_floating); |
52 | 52 | ||
53 | // Floating containers in the scratchpad should be ignored | 53 | // Floating containers in the scratchpad should be ignored |
54 | if (container->workspace) { | 54 | if (container->pending.workspace) { |
55 | arrange_workspace(container->workspace); | 55 | arrange_workspace(container->pending.workspace); |
56 | } | 56 | } |
57 | 57 | ||
58 | return cmd_results_new(CMD_SUCCESS, NULL); | 58 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/floating_minmax_size.c b/sway/commands/floating_minmax_size.c index 3a1d606a..e8c24ace 100644 --- a/sway/commands/floating_minmax_size.c +++ b/sway/commands/floating_minmax_size.c | |||
@@ -23,16 +23,16 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | |||
23 | char *err; | 23 | char *err; |
24 | int width = (int)strtol(argv[0], &err, 10); | 24 | int width = (int)strtol(argv[0], &err, 10); |
25 | if (*err) { | 25 | if (*err) { |
26 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | 26 | return cmd_results_new(CMD_INVALID, "%s", usage); |
27 | } | 27 | } |
28 | 28 | ||
29 | if (strcmp(argv[1], "x") != 0) { | 29 | if (strcmp(argv[1], "x") != 0) { |
30 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | 30 | return cmd_results_new(CMD_INVALID, "%s", usage); |
31 | } | 31 | } |
32 | 32 | ||
33 | int height = (int)strtol(argv[2], &err, 10); | 33 | int height = (int)strtol(argv[2], &err, 10); |
34 | if (*err) { | 34 | if (*err) { |
35 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | 35 | return cmd_results_new(CMD_INVALID, "%s", usage); |
36 | } | 36 | } |
37 | 37 | ||
38 | *config_width = width; | 38 | *config_width = width; |
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 79b7aed5..facd82de 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -54,7 +54,7 @@ static bool get_direction_from_next_prev(struct sway_container *container, | |||
54 | } else { | 54 | } else { |
55 | return false; | 55 | return false; |
56 | } | 56 | } |
57 | 57 | ||
58 | return true; | 58 | return true; |
59 | } | 59 | } |
60 | 60 | ||
@@ -141,9 +141,9 @@ static struct sway_node *node_get_in_direction_tiling( | |||
141 | struct sway_container *wrap_candidate = NULL; | 141 | struct sway_container *wrap_candidate = NULL; |
142 | struct sway_container *current = container; | 142 | struct sway_container *current = container; |
143 | while (current) { | 143 | while (current) { |
144 | if (current->fullscreen_mode == FULLSCREEN_WORKSPACE) { | 144 | if (current->pending.fullscreen_mode == FULLSCREEN_WORKSPACE) { |
145 | // Fullscreen container with a direction - go straight to outputs | 145 | // Fullscreen container with a direction - go straight to outputs |
146 | struct sway_output *output = current->workspace->output; | 146 | struct sway_output *output = current->pending.workspace->output; |
147 | struct sway_output *new_output = | 147 | struct sway_output *new_output = |
148 | output_get_in_direction(output, dir); | 148 | output_get_in_direction(output, dir); |
149 | if (!new_output) { | 149 | if (!new_output) { |
@@ -151,7 +151,7 @@ static struct sway_node *node_get_in_direction_tiling( | |||
151 | } | 151 | } |
152 | return get_node_in_output_direction(new_output, dir); | 152 | return get_node_in_output_direction(new_output, dir); |
153 | } | 153 | } |
154 | if (current->fullscreen_mode == FULLSCREEN_GLOBAL) { | 154 | if (current->pending.fullscreen_mode == FULLSCREEN_GLOBAL) { |
155 | return NULL; | 155 | return NULL; |
156 | } | 156 | } |
157 | 157 | ||
@@ -202,11 +202,11 @@ static struct sway_node *node_get_in_direction_tiling( | |||
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | current = current->parent; | 205 | current = current->pending.parent; |
206 | } | 206 | } |
207 | 207 | ||
208 | // Check a different output | 208 | // Check a different output |
209 | struct sway_output *output = container->workspace->output; | 209 | struct sway_output *output = container->pending.workspace->output; |
210 | struct sway_output *new_output = output_get_in_direction(output, dir); | 210 | struct sway_output *new_output = output_get_in_direction(output, dir); |
211 | if ((config->focus_wrapping != WRAP_WORKSPACE || | 211 | if ((config->focus_wrapping != WRAP_WORKSPACE || |
212 | container->node.type == N_WORKSPACE) && new_output) { | 212 | container->node.type == N_WORKSPACE) && new_output) { |
@@ -226,23 +226,23 @@ static struct sway_node *node_get_in_direction_tiling( | |||
226 | static struct sway_node *node_get_in_direction_floating( | 226 | static struct sway_node *node_get_in_direction_floating( |
227 | struct sway_container *con, struct sway_seat *seat, | 227 | struct sway_container *con, struct sway_seat *seat, |
228 | enum wlr_direction dir) { | 228 | enum wlr_direction dir) { |
229 | double ref_lx = con->x + con->width / 2; | 229 | double ref_lx = con->pending.x + con->pending.width / 2; |
230 | double ref_ly = con->y + con->height / 2; | 230 | double ref_ly = con->pending.y + con->pending.height / 2; |
231 | double closest_distance = DBL_MAX; | 231 | double closest_distance = DBL_MAX; |
232 | struct sway_container *closest_con = NULL; | 232 | struct sway_container *closest_con = NULL; |
233 | 233 | ||
234 | if (!con->workspace) { | 234 | if (!con->pending.workspace) { |
235 | return NULL; | 235 | return NULL; |
236 | } | 236 | } |
237 | 237 | ||
238 | for (int i = 0; i < con->workspace->floating->length; i++) { | 238 | for (int i = 0; i < con->pending.workspace->floating->length; i++) { |
239 | struct sway_container *floater = con->workspace->floating->items[i]; | 239 | struct sway_container *floater = con->pending.workspace->floating->items[i]; |
240 | if (floater == con) { | 240 | if (floater == con) { |
241 | continue; | 241 | continue; |
242 | } | 242 | } |
243 | float distance = dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_RIGHT | 243 | float distance = dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_RIGHT |
244 | ? (floater->x + floater->width / 2) - ref_lx | 244 | ? (floater->pending.x + floater->pending.width / 2) - ref_lx |
245 | : (floater->y + floater->height / 2) - ref_ly; | 245 | : (floater->pending.y + floater->pending.height / 2) - ref_ly; |
246 | if (dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_UP) { | 246 | if (dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_UP) { |
247 | distance = -distance; | 247 | distance = -distance; |
248 | } | 248 | } |
@@ -267,6 +267,11 @@ static struct cmd_results *focus_mode(struct sway_workspace *ws, | |||
267 | new_focus = seat_get_focus_inactive_tiling(seat, ws); | 267 | new_focus = seat_get_focus_inactive_tiling(seat, ws); |
268 | } | 268 | } |
269 | if (new_focus) { | 269 | if (new_focus) { |
270 | struct sway_container *new_focus_view = | ||
271 | seat_get_focus_inactive_view(seat, &new_focus->node); | ||
272 | if (new_focus_view) { | ||
273 | new_focus = new_focus_view; | ||
274 | } | ||
270 | seat_set_focus_container(seat, new_focus); | 275 | seat_set_focus_container(seat, new_focus); |
271 | 276 | ||
272 | // If we're on the floating layer and the floating container area | 277 | // If we're on the floating layer and the floating container area |
@@ -280,7 +285,7 @@ static struct cmd_results *focus_mode(struct sway_workspace *ws, | |||
280 | } | 285 | } |
281 | } else { | 286 | } else { |
282 | return cmd_results_new(CMD_FAILURE, | 287 | return cmd_results_new(CMD_FAILURE, |
283 | "Failed to find a %s container in workspace", | 288 | "Failed to find a %s container in workspace.", |
284 | floating ? "floating" : "tiling"); | 289 | floating ? "floating" : "tiling"); |
285 | } | 290 | } |
286 | return cmd_results_new(CMD_SUCCESS, NULL); | 291 | return cmd_results_new(CMD_SUCCESS, NULL); |
@@ -290,7 +295,7 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
290 | int argc, char **argv) { | 295 | int argc, char **argv) { |
291 | if (!argc) { | 296 | if (!argc) { |
292 | return cmd_results_new(CMD_INVALID, | 297 | return cmd_results_new(CMD_INVALID, |
293 | "Expected 'focus output <direction|name>'"); | 298 | "Expected 'focus output <direction|name>'."); |
294 | } | 299 | } |
295 | char *identifier = join_args(argv, argc); | 300 | char *identifier = join_args(argv, argc); |
296 | struct sway_output *output = output_by_name_or_id(identifier); | 301 | struct sway_output *output = output_by_name_or_id(identifier); |
@@ -300,13 +305,13 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
300 | if (!parse_direction(identifier, &direction)) { | 305 | if (!parse_direction(identifier, &direction)) { |
301 | free(identifier); | 306 | free(identifier); |
302 | return cmd_results_new(CMD_INVALID, | 307 | return cmd_results_new(CMD_INVALID, |
303 | "There is no output with that name"); | 308 | "There is no output with that name."); |
304 | } | 309 | } |
305 | struct sway_workspace *ws = seat_get_focused_workspace(seat); | 310 | struct sway_workspace *ws = seat_get_focused_workspace(seat); |
306 | if (!ws) { | 311 | if (!ws) { |
307 | free(identifier); | 312 | free(identifier); |
308 | return cmd_results_new(CMD_FAILURE, | 313 | return cmd_results_new(CMD_FAILURE, |
309 | "No focused workspace to base directions off of"); | 314 | "No focused workspace to base directions off of."); |
310 | } | 315 | } |
311 | output = output_get_in_direction(ws->output, direction); | 316 | output = output_get_in_direction(ws->output, direction); |
312 | 317 | ||
@@ -334,7 +339,7 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
334 | static struct cmd_results *focus_parent(void) { | 339 | static struct cmd_results *focus_parent(void) { |
335 | struct sway_seat *seat = config->handler_context.seat; | 340 | struct sway_seat *seat = config->handler_context.seat; |
336 | struct sway_container *con = config->handler_context.container; | 341 | struct sway_container *con = config->handler_context.container; |
337 | if (!con || con->fullscreen_mode) { | 342 | if (!con || con->pending.fullscreen_mode) { |
338 | return cmd_results_new(CMD_SUCCESS, NULL); | 343 | return cmd_results_new(CMD_SUCCESS, NULL); |
339 | } | 344 | } |
340 | struct sway_node *parent = node_get_parent(&con->node); | 345 | struct sway_node *parent = node_get_parent(&con->node); |
@@ -370,13 +375,24 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
370 | struct sway_seat *seat = config->handler_context.seat; | 375 | struct sway_seat *seat = config->handler_context.seat; |
371 | if (node->type < N_WORKSPACE) { | 376 | if (node->type < N_WORKSPACE) { |
372 | return cmd_results_new(CMD_FAILURE, | 377 | return cmd_results_new(CMD_FAILURE, |
373 | "Command 'focus' cannot be used above the workspace level"); | 378 | "Command 'focus' cannot be used above the workspace level."); |
374 | } | 379 | } |
375 | 380 | ||
376 | if (argc == 0 && container) { | 381 | if (argc == 0) { |
382 | if (!container) { | ||
383 | return cmd_results_new(CMD_FAILURE, "No container to focus was specified."); | ||
384 | } | ||
385 | |||
377 | if (container_is_scratchpad_hidden_or_child(container)) { | 386 | if (container_is_scratchpad_hidden_or_child(container)) { |
378 | root_scratchpad_show(container); | 387 | root_scratchpad_show(container); |
379 | } | 388 | } |
389 | // if we are switching to a container under a fullscreen window, we first | ||
390 | // need to exit fullscreen so that the newly focused container becomes visible | ||
391 | struct sway_container *obstructing = container_obstructing_fullscreen_container(container); | ||
392 | if (obstructing) { | ||
393 | container_fullscreen_disable(obstructing); | ||
394 | arrange_root(); | ||
395 | } | ||
380 | seat_set_focus_container(seat, container); | 396 | seat_set_focus_container(seat, container); |
381 | seat_consider_warp_to_focus(seat); | 397 | seat_consider_warp_to_focus(seat); |
382 | container_raise_floating(container); | 398 | container_raise_floating(container); |
@@ -439,7 +455,8 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
439 | return cmd_results_new(CMD_FAILURE, ""); | 455 | return cmd_results_new(CMD_FAILURE, ""); |
440 | } | 456 | } |
441 | struct sway_node *next_focus = NULL; | 457 | struct sway_node *next_focus = NULL; |
442 | if (container_is_floating(container)) { | 458 | if (container_is_floating(container) && |
459 | container->pending.fullscreen_mode == FULLSCREEN_NONE) { | ||
443 | next_focus = node_get_in_direction_floating(container, seat, direction); | 460 | next_focus = node_get_in_direction_floating(container, seat, direction); |
444 | } else { | 461 | } else { |
445 | next_focus = node_get_in_direction_tiling(container, seat, direction, descend); | 462 | next_focus = node_get_in_direction_tiling(container, seat, direction, descend); |
diff --git a/sway/commands/font.c b/sway/commands/font.c index c54365b5..9920d03e 100644 --- a/sway/commands/font.c +++ b/sway/commands/font.c | |||
@@ -1,9 +1,9 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
5 | #include "log.h" | 4 | #include "log.h" |
6 | #include "stringop.h" | 5 | #include "stringop.h" |
6 | #include <pango/pangocairo.h> | ||
7 | 7 | ||
8 | struct cmd_results *cmd_font(int argc, char **argv) { | 8 | struct cmd_results *cmd_font(int argc, char **argv) { |
9 | struct cmd_results *error = NULL; | 9 | struct cmd_results *error = NULL; |
@@ -16,12 +16,34 @@ struct cmd_results *cmd_font(int argc, char **argv) { | |||
16 | if (strncmp(font, "pango:", 6) == 0) { | 16 | if (strncmp(font, "pango:", 6) == 0) { |
17 | config->pango_markup = true; | 17 | config->pango_markup = true; |
18 | config->font = strdup(font + 6); | 18 | config->font = strdup(font + 6); |
19 | free(font); | ||
19 | } else { | 20 | } else { |
20 | config->pango_markup = false; | 21 | config->pango_markup = false; |
21 | config->font = strdup(font); | 22 | config->font = font; |
22 | } | 23 | } |
23 | 24 | ||
24 | free(font); | 25 | // Parse the font early so we can reject it if it's not valid for pango. |
25 | config_update_font_height(true); | 26 | // Also avoids re-parsing each time we render text. |
27 | PangoFontDescription *font_description = pango_font_description_from_string(config->font); | ||
28 | |||
29 | const char *family = pango_font_description_get_family(font_description); | ||
30 | if (family == NULL) { | ||
31 | pango_font_description_free(font_description); | ||
32 | return cmd_results_new(CMD_FAILURE, "Invalid font family."); | ||
33 | } | ||
34 | |||
35 | const gint size = pango_font_description_get_size(font_description); | ||
36 | if (size == 0) { | ||
37 | pango_font_description_free(font_description); | ||
38 | return cmd_results_new(CMD_FAILURE, "Invalid font size."); | ||
39 | } | ||
40 | |||
41 | if (config->font_description != NULL) { | ||
42 | pango_font_description_free(config->font_description); | ||
43 | } | ||
44 | |||
45 | config->font_description = font_description; | ||
46 | config_update_font_height(); | ||
47 | |||
26 | return cmd_results_new(CMD_SUCCESS, NULL); | 48 | return cmd_results_new(CMD_SUCCESS, NULL); |
27 | } | 49 | } |
diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index ee9f4647..905e6776 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { | |||
14 | char *err_str = NULL; | 14 | char *err_str = NULL; |
15 | struct criteria *criteria = criteria_parse(argv[0], &err_str); | 15 | struct criteria *criteria = criteria_parse(argv[0], &err_str); |
16 | if (!criteria) { | 16 | if (!criteria) { |
17 | error = cmd_results_new(CMD_INVALID, err_str); | 17 | error = cmd_results_new(CMD_INVALID, "%s", err_str); |
18 | free(err_str); | 18 | free(err_str); |
19 | return error; | 19 | return error; |
20 | } | 20 | } |
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index 3392a7f7..21c1e9a0 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c | |||
@@ -18,30 +18,19 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
18 | return cmd_results_new(CMD_FAILURE, | 18 | return cmd_results_new(CMD_FAILURE, |
19 | "Can't run this command while there's no outputs connected."); | 19 | "Can't run this command while there's no outputs connected."); |
20 | } | 20 | } |
21 | struct sway_node *node = config->handler_context.node; | ||
22 | struct sway_container *container = config->handler_context.container; | 21 | struct sway_container *container = config->handler_context.container; |
23 | struct sway_workspace *workspace = config->handler_context.workspace; | ||
24 | if (node->type == N_WORKSPACE && workspace->tiling->length == 0) { | ||
25 | return cmd_results_new(CMD_FAILURE, | ||
26 | "Can't fullscreen an empty workspace"); | ||
27 | } | ||
28 | 22 | ||
29 | // If in the scratchpad, operate on the highest container | 23 | if (!container) { |
30 | if (container && !container->workspace) { | 24 | // If the focus is not a container, do nothing successfully |
31 | while (container->parent) { | 25 | return cmd_results_new(CMD_SUCCESS, NULL); |
32 | container = container->parent; | 26 | } else if (!container->pending.workspace) { |
33 | } | 27 | // If in the scratchpad, operate on the highest container |
34 | } | 28 | while (container->pending.parent) { |
35 | 29 | container = container->pending.parent; | |
36 | bool is_fullscreen = false; | ||
37 | for (struct sway_container *curr = container; curr; curr = curr->parent) { | ||
38 | if (curr->fullscreen_mode != FULLSCREEN_NONE) { | ||
39 | container = curr; | ||
40 | is_fullscreen = true; | ||
41 | break; | ||
42 | } | 30 | } |
43 | } | 31 | } |
44 | 32 | ||
33 | bool is_fullscreen = container->pending.fullscreen_mode != FULLSCREEN_NONE; | ||
45 | bool global = false; | 34 | bool global = false; |
46 | bool enable = !is_fullscreen; | 35 | bool enable = !is_fullscreen; |
47 | 36 | ||
@@ -57,13 +46,6 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
57 | global = strcasecmp(argv[1], "global") == 0; | 46 | global = strcasecmp(argv[1], "global") == 0; |
58 | } | 47 | } |
59 | 48 | ||
60 | if (enable && node->type == N_WORKSPACE) { | ||
61 | // Wrap the workspace's children in a container so we can fullscreen it | ||
62 | container = workspace_wrap_children(workspace); | ||
63 | workspace->layout = L_HORIZ; | ||
64 | seat_set_focus_container(config->handler_context.seat, container); | ||
65 | } | ||
66 | |||
67 | enum sway_fullscreen_mode mode = FULLSCREEN_NONE; | 49 | enum sway_fullscreen_mode mode = FULLSCREEN_NONE; |
68 | if (enable) { | 50 | if (enable) { |
69 | mode = global ? FULLSCREEN_GLOBAL : FULLSCREEN_WORKSPACE; | 51 | mode = global ? FULLSCREEN_GLOBAL : FULLSCREEN_WORKSPACE; |
diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c index 021df843..1deeb56e 100644 --- a/sway/commands/gaps.c +++ b/sway/commands/gaps.c | |||
@@ -11,7 +11,8 @@ | |||
11 | enum gaps_op { | 11 | enum gaps_op { |
12 | GAPS_OP_SET, | 12 | GAPS_OP_SET, |
13 | GAPS_OP_ADD, | 13 | GAPS_OP_ADD, |
14 | GAPS_OP_SUBTRACT | 14 | GAPS_OP_SUBTRACT, |
15 | GAPS_OP_TOGGLE | ||
15 | }; | 16 | }; |
16 | 17 | ||
17 | struct gaps_data { | 18 | struct gaps_data { |
@@ -102,6 +103,9 @@ static void apply_gaps_op(int *prop, enum gaps_op op, int amount) { | |||
102 | case GAPS_OP_SUBTRACT: | 103 | case GAPS_OP_SUBTRACT: |
103 | *prop -= amount; | 104 | *prop -= amount; |
104 | break; | 105 | break; |
106 | case GAPS_OP_TOGGLE: | ||
107 | *prop = *prop ? 0 : amount; | ||
108 | break; | ||
105 | } | 109 | } |
106 | } | 110 | } |
107 | 111 | ||
@@ -133,9 +137,9 @@ static void configure_gaps(struct sway_workspace *ws, void *_data) { | |||
133 | } | 137 | } |
134 | 138 | ||
135 | // gaps inner|outer|horizontal|vertical|top|right|bottom|left current|all | 139 | // gaps inner|outer|horizontal|vertical|top|right|bottom|left current|all |
136 | // set|plus|minus <px> | 140 | // set|plus|minus|toggle <px> |
137 | static const char expected_runtime[] = "'gaps inner|outer|horizontal|vertical|" | 141 | static const char expected_runtime[] = "'gaps inner|outer|horizontal|vertical|" |
138 | "top|right|bottom|left current|all set|plus|minus <px>'"; | 142 | "top|right|bottom|left current|all set|plus|minus|toggle <px>'"; |
139 | static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | 143 | static struct cmd_results *gaps_set_runtime(int argc, char **argv) { |
140 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); | 144 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); |
141 | if (error) { | 145 | if (error) { |
@@ -180,6 +184,8 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
180 | data.operation = GAPS_OP_ADD; | 184 | data.operation = GAPS_OP_ADD; |
181 | } else if (strcasecmp(argv[2], "minus") == 0) { | 185 | } else if (strcasecmp(argv[2], "minus") == 0) { |
182 | data.operation = GAPS_OP_SUBTRACT; | 186 | data.operation = GAPS_OP_SUBTRACT; |
187 | } else if (strcasecmp(argv[2], "toggle") == 0) { | ||
188 | data.operation = GAPS_OP_TOGGLE; | ||
183 | } else { | 189 | } else { |
184 | return cmd_results_new(CMD_INVALID, "Expected %s", expected_runtime); | 190 | return cmd_results_new(CMD_INVALID, "Expected %s", expected_runtime); |
185 | } | 191 | } |
@@ -200,7 +206,7 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
200 | } | 206 | } |
201 | 207 | ||
202 | // gaps inner|outer|<dir>|<side> <px> - sets defaults for workspaces | 208 | // gaps inner|outer|<dir>|<side> <px> - sets defaults for workspaces |
203 | // gaps inner|outer|<dir>|<side> current|all set|plus|minus <px> - runtime only | 209 | // gaps inner|outer|<dir>|<side> current|all set|plus|minus|toggle <px> - runtime only |
204 | // <dir> = horizontal|vertical | 210 | // <dir> = horizontal|vertical |
205 | // <side> = top|right|bottom|left | 211 | // <side> = top|right|bottom|left |
206 | struct cmd_results *cmd_gaps(int argc, char **argv) { | 212 | struct cmd_results *cmd_gaps(int argc, char **argv) { |
diff --git a/sway/commands/gesture.c b/sway/commands/gesture.c new file mode 100644 index 00000000..90a20716 --- /dev/null +++ b/sway/commands/gesture.c | |||
@@ -0,0 +1,165 @@ | |||
1 | #include "sway/config.h" | ||
2 | |||
3 | #include "gesture.h" | ||
4 | #include "log.h" | ||
5 | #include "stringop.h" | ||
6 | #include "sway/commands.h" | ||
7 | |||
8 | void free_gesture_binding(struct sway_gesture_binding *binding) { | ||
9 | if (!binding) { | ||
10 | return; | ||
11 | } | ||
12 | free(binding->input); | ||
13 | free(binding->command); | ||
14 | free(binding); | ||
15 | } | ||
16 | |||
17 | /** | ||
18 | * Returns true if the bindings have the same gesture type, direction, etc | ||
19 | */ | ||
20 | static bool binding_gesture_equal(struct sway_gesture_binding *binding_a, | ||
21 | struct sway_gesture_binding *binding_b) { | ||
22 | if (strcmp(binding_a->input, binding_b->input) != 0) { | ||
23 | return false; | ||
24 | } | ||
25 | |||
26 | if (!gesture_equal(&binding_a->gesture, &binding_b->gesture)) { | ||
27 | return false; | ||
28 | } | ||
29 | |||
30 | if ((binding_a->flags & BINDING_EXACT) != | ||
31 | (binding_b->flags & BINDING_EXACT)) { | ||
32 | return false; | ||
33 | } | ||
34 | return true; | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Add gesture binding to config | ||
39 | */ | ||
40 | static struct cmd_results *gesture_binding_add( | ||
41 | struct sway_gesture_binding *binding, | ||
42 | const char *gesturecombo, bool warn) { | ||
43 | list_t *mode_bindings = config->current_mode->gesture_bindings; | ||
44 | // overwrite the binding if it already exists | ||
45 | bool overwritten = false; | ||
46 | for (int i = 0; i < mode_bindings->length; ++i) { | ||
47 | struct sway_gesture_binding *config_binding = mode_bindings->items[i]; | ||
48 | if (binding_gesture_equal(binding, config_binding)) { | ||
49 | sway_log(SWAY_INFO, "Overwriting binding '%s' to `%s` from `%s`", | ||
50 | gesturecombo, binding->command, config_binding->command); | ||
51 | if (warn) { | ||
52 | config_add_swaynag_warning("Overwriting binding" | ||
53 | "'%s' to `%s` from `%s`", | ||
54 | gesturecombo, binding->command, | ||
55 | config_binding->command); | ||
56 | } | ||
57 | free_gesture_binding(config_binding); | ||
58 | mode_bindings->items[i] = binding; | ||
59 | overwritten = true; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | if (!overwritten) { | ||
64 | list_add(mode_bindings, binding); | ||
65 | sway_log(SWAY_DEBUG, "bindgesture - Bound %s to command `%s`", | ||
66 | gesturecombo, binding->command); | ||
67 | } | ||
68 | |||
69 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Remove gesture binding from config | ||
74 | */ | ||
75 | static struct cmd_results *gesture_binding_remove( | ||
76 | struct sway_gesture_binding *binding, const char *gesturecombo) { | ||
77 | list_t *mode_bindings = config->current_mode->gesture_bindings; | ||
78 | for (int i = 0; i < mode_bindings->length; ++i) { | ||
79 | struct sway_gesture_binding *config_binding = mode_bindings->items[i]; | ||
80 | if (binding_gesture_equal(binding, config_binding)) { | ||
81 | free_gesture_binding(config_binding); | ||
82 | free_gesture_binding(binding); | ||
83 | list_del(mode_bindings, i); | ||
84 | sway_log(SWAY_DEBUG, "unbindgesture - Unbound %s gesture", | ||
85 | gesturecombo); | ||
86 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | free_gesture_binding(binding); | ||
91 | return cmd_results_new(CMD_FAILURE, "Could not find gesture binding `%s`", | ||
92 | gesturecombo); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Parse and execute bindgesture or unbindgesture command. | ||
97 | */ | ||
98 | static struct cmd_results *cmd_bind_or_unbind_gesture(int argc, char **argv, bool unbind) { | ||
99 | int minargs = 2; | ||
100 | char *bindtype = "bindgesture"; | ||
101 | if (unbind) { | ||
102 | minargs--; | ||
103 | bindtype = "unbindgesture"; | ||
104 | } | ||
105 | |||
106 | struct cmd_results *error = NULL; | ||
107 | if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) { | ||
108 | return error; | ||
109 | } | ||
110 | struct sway_gesture_binding *binding = calloc(1, sizeof(struct sway_gesture_binding)); | ||
111 | if (!binding) { | ||
112 | return cmd_results_new(CMD_FAILURE, "Unable to allocate binding"); | ||
113 | } | ||
114 | binding->input = strdup("*"); | ||
115 | |||
116 | bool warn = true; | ||
117 | |||
118 | // Handle flags | ||
119 | while (argc > 0) { | ||
120 | if (strcmp("--exact", argv[0]) == 0) { | ||
121 | binding->flags |= BINDING_EXACT; | ||
122 | } else if (strcmp("--no-warn", argv[0]) == 0) { | ||
123 | warn = false; | ||
124 | } else if (strncmp("--input-device=", argv[0], | ||
125 | strlen("--input-device=")) == 0) { | ||
126 | free(binding->input); | ||
127 | binding->input = strdup(argv[0] + strlen("--input-device=")); | ||
128 | } else { | ||
129 | break; | ||
130 | } | ||
131 | argv++; | ||
132 | argc--; | ||
133 | } | ||
134 | |||
135 | if (argc < minargs) { | ||
136 | free(binding); | ||
137 | return cmd_results_new(CMD_FAILURE, | ||
138 | "Invalid %s command (expected at least %d " | ||
139 | "non-option arguments, got %d)", bindtype, minargs, argc); | ||
140 | } | ||
141 | |||
142 | char* errmsg = NULL; | ||
143 | if ((errmsg = gesture_parse(argv[0], &binding->gesture))) { | ||
144 | free(binding); | ||
145 | struct cmd_results *final = cmd_results_new(CMD_FAILURE, | ||
146 | "Invalid %s command (%s)", | ||
147 | bindtype, errmsg); | ||
148 | free(errmsg); | ||
149 | return final; | ||
150 | } | ||
151 | |||
152 | if (unbind) { | ||
153 | return gesture_binding_remove(binding, argv[0]); | ||
154 | } | ||
155 | binding->command = join_args(argv + 1, argc - 1); | ||
156 | return gesture_binding_add(binding, argv[0], warn); | ||
157 | } | ||
158 | |||
159 | struct cmd_results *cmd_bindgesture(int argc, char **argv) { | ||
160 | return cmd_bind_or_unbind_gesture(argc, argv, false); | ||
161 | } | ||
162 | |||
163 | struct cmd_results *cmd_unbindgesture(int argc, char **argv) { | ||
164 | return cmd_bind_or_unbind_gesture(argc, argv, true); | ||
165 | } | ||
diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c index 9a1d8445..43bd6dc8 100644 --- a/sway/commands/hide_edge_borders.c +++ b/sway/commands/hide_edge_borders.c | |||
@@ -20,7 +20,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { | |||
20 | } | 20 | } |
21 | 21 | ||
22 | if (!argc) { | 22 | if (!argc) { |
23 | return cmd_results_new(CMD_INVALID, expected_syntax); | 23 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
24 | } | 24 | } |
25 | 25 | ||
26 | if (strcmp(argv[0], "none") == 0) { | 26 | if (strcmp(argv[0], "none") == 0) { |
@@ -38,7 +38,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { | |||
38 | config->hide_edge_borders = E_NONE; | 38 | config->hide_edge_borders = E_NONE; |
39 | config->hide_edge_borders_smart = ESMART_NO_GAPS; | 39 | config->hide_edge_borders_smart = ESMART_NO_GAPS; |
40 | } else { | 40 | } else { |
41 | return cmd_results_new(CMD_INVALID, expected_syntax); | 41 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
42 | } | 42 | } |
43 | config->hide_lone_tab = hide_lone_tab; | 43 | config->hide_lone_tab = hide_lone_tab; |
44 | 44 | ||
diff --git a/sway/commands/inhibit_idle.c b/sway/commands/inhibit_idle.c index aebc2bf9..6125736a 100644 --- a/sway/commands/inhibit_idle.c +++ b/sway/commands/inhibit_idle.c | |||
@@ -41,7 +41,7 @@ struct cmd_results *cmd_inhibit_idle(int argc, char **argv) { | |||
41 | sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor); | 41 | sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor); |
42 | } else { | 42 | } else { |
43 | inhibitor->mode = mode; | 43 | inhibitor->mode = mode; |
44 | sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1); | 44 | sway_idle_inhibit_v1_check_active(); |
45 | } | 45 | } |
46 | } else if (!clear) { | 46 | } else if (!clear) { |
47 | sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode); | 47 | sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode); |
diff --git a/sway/commands/input.c b/sway/commands/input.c index c9bb8e06..306c40f7 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c | |||
@@ -7,13 +7,14 @@ | |||
7 | #include "stringop.h" | 7 | #include "stringop.h" |
8 | 8 | ||
9 | // must be in order for the bsearch | 9 | // must be in order for the bsearch |
10 | static struct cmd_handler input_handlers[] = { | 10 | static const struct cmd_handler input_handlers[] = { |
11 | { "accel_profile", input_cmd_accel_profile }, | 11 | { "accel_profile", input_cmd_accel_profile }, |
12 | { "calibration_matrix", input_cmd_calibration_matrix }, | 12 | { "calibration_matrix", input_cmd_calibration_matrix }, |
13 | { "click_method", input_cmd_click_method }, | 13 | { "click_method", input_cmd_click_method }, |
14 | { "drag", input_cmd_drag }, | 14 | { "drag", input_cmd_drag }, |
15 | { "drag_lock", input_cmd_drag_lock }, | 15 | { "drag_lock", input_cmd_drag_lock }, |
16 | { "dwt", input_cmd_dwt }, | 16 | { "dwt", input_cmd_dwt }, |
17 | { "dwtp", input_cmd_dwtp }, | ||
17 | { "events", input_cmd_events }, | 18 | { "events", input_cmd_events }, |
18 | { "left_handed", input_cmd_left_handed }, | 19 | { "left_handed", input_cmd_left_handed }, |
19 | { "map_from_region", input_cmd_map_from_region }, | 20 | { "map_from_region", input_cmd_map_from_region }, |
@@ -24,7 +25,9 @@ static struct cmd_handler input_handlers[] = { | |||
24 | { "pointer_accel", input_cmd_pointer_accel }, | 25 | { "pointer_accel", input_cmd_pointer_accel }, |
25 | { "repeat_delay", input_cmd_repeat_delay }, | 26 | { "repeat_delay", input_cmd_repeat_delay }, |
26 | { "repeat_rate", input_cmd_repeat_rate }, | 27 | { "repeat_rate", input_cmd_repeat_rate }, |
28 | { "rotation_angle", input_cmd_rotation_angle }, | ||
27 | { "scroll_button", input_cmd_scroll_button }, | 29 | { "scroll_button", input_cmd_scroll_button }, |
30 | { "scroll_button_lock", input_cmd_scroll_button_lock }, | ||
28 | { "scroll_factor", input_cmd_scroll_factor }, | 31 | { "scroll_factor", input_cmd_scroll_factor }, |
29 | { "scroll_method", input_cmd_scroll_method }, | 32 | { "scroll_method", input_cmd_scroll_method }, |
30 | { "tap", input_cmd_tap }, | 33 | { "tap", input_cmd_tap }, |
@@ -40,7 +43,7 @@ static struct cmd_handler input_handlers[] = { | |||
40 | }; | 43 | }; |
41 | 44 | ||
42 | // must be in order for the bsearch | 45 | // must be in order for the bsearch |
43 | static struct cmd_handler input_config_handlers[] = { | 46 | static const struct cmd_handler input_config_handlers[] = { |
44 | { "xkb_capslock", input_cmd_xkb_capslock }, | 47 | { "xkb_capslock", input_cmd_xkb_capslock }, |
45 | { "xkb_numlock", input_cmd_xkb_numlock }, | 48 | { "xkb_numlock", input_cmd_xkb_numlock }, |
46 | }; | 49 | }; |
diff --git a/sway/commands/input/calibration_matrix.c b/sway/commands/input/calibration_matrix.c index 38749fbb..53fe2c35 100644 --- a/sway/commands/input/calibration_matrix.c +++ b/sway/commands/input/calibration_matrix.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/dwtp.c b/sway/commands/input/dwtp.c new file mode 100644 index 00000000..232e2b26 --- /dev/null +++ b/sway/commands/input/dwtp.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <string.h> | ||
2 | #include <strings.h> | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/commands.h" | ||
5 | #include "sway/input/input-manager.h" | ||
6 | #include "util.h" | ||
7 | |||
8 | struct cmd_results *input_cmd_dwtp(int argc, char **argv) { | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "dwtp", EXPECTED_AT_LEAST, 1))) { | ||
11 | return error; | ||
12 | } | ||
13 | struct input_config *ic = config->handler_context.input_config; | ||
14 | if (!ic) { | ||
15 | return cmd_results_new(CMD_FAILURE, "No input device defined."); | ||
16 | } | ||
17 | |||
18 | if (parse_boolean(argv[0], true)) { | ||
19 | ic->dwtp = LIBINPUT_CONFIG_DWTP_ENABLED; | ||
20 | } else { | ||
21 | ic->dwtp = LIBINPUT_CONFIG_DWTP_DISABLED; | ||
22 | } | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
25 | } | ||
diff --git a/sway/commands/input/events.c b/sway/commands/input/events.c index 9405181a..08d99bf0 100644 --- a/sway/commands/input/events.c +++ b/sway/commands/input/events.c | |||
@@ -1,14 +1,19 @@ | |||
1 | #include <limits.h> | 1 | #include <limits.h> |
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <strings.h> | 3 | #include <strings.h> |
4 | #include <wlr/backend/libinput.h> | 4 | #include <wlr/config.h> |
5 | #include "sway/config.h" | 5 | #include "sway/config.h" |
6 | #include "sway/commands.h" | 6 | #include "sway/commands.h" |
7 | #include "sway/input/input-manager.h" | 7 | #include "sway/input/input-manager.h" |
8 | #include "log.h" | 8 | #include "log.h" |
9 | 9 | ||
10 | #if WLR_HAS_LIBINPUT_BACKEND | ||
11 | #include <wlr/backend/libinput.h> | ||
12 | #endif | ||
13 | |||
10 | static void toggle_supported_send_events_for_device(struct input_config *ic, | 14 | static void toggle_supported_send_events_for_device(struct input_config *ic, |
11 | struct sway_input_device *input_device) { | 15 | struct sway_input_device *input_device) { |
16 | #if WLR_HAS_LIBINPUT_BACKEND | ||
12 | struct wlr_input_device *wlr_device = input_device->wlr_device; | 17 | struct wlr_input_device *wlr_device = input_device->wlr_device; |
13 | if (!wlr_input_device_is_libinput(wlr_device)) { | 18 | if (!wlr_input_device_is_libinput(wlr_device)) { |
14 | return; | 19 | return; |
@@ -41,6 +46,7 @@ static void toggle_supported_send_events_for_device(struct input_config *ic, | |||
41 | } | 46 | } |
42 | 47 | ||
43 | ic->send_events = mode; | 48 | ic->send_events = mode; |
49 | #endif | ||
44 | } | 50 | } |
45 | 51 | ||
46 | static int mode_for_name(const char *name) { | 52 | static int mode_for_name(const char *name) { |
@@ -56,6 +62,7 @@ static int mode_for_name(const char *name) { | |||
56 | 62 | ||
57 | static void toggle_select_send_events_for_device(struct input_config *ic, | 63 | static void toggle_select_send_events_for_device(struct input_config *ic, |
58 | struct sway_input_device *input_device, int argc, char **argv) { | 64 | struct sway_input_device *input_device, int argc, char **argv) { |
65 | #if WLR_HAS_LIBINPUT_BACKEND | ||
59 | if (!wlr_input_device_is_libinput(input_device->wlr_device)) { | 66 | if (!wlr_input_device_is_libinput(input_device->wlr_device)) { |
60 | return; | 67 | return; |
61 | } | 68 | } |
@@ -72,6 +79,7 @@ static void toggle_select_send_events_for_device(struct input_config *ic, | |||
72 | } | 79 | } |
73 | } | 80 | } |
74 | ic->send_events = mode_for_name(argv[index % argc]); | 81 | ic->send_events = mode_for_name(argv[index % argc]); |
82 | #endif | ||
75 | } | 83 | } |
76 | 84 | ||
77 | static void toggle_send_events(int argc, char **argv) { | 85 | static void toggle_send_events(int argc, char **argv) { |
diff --git a/sway/commands/input/map_from_region.c b/sway/commands/input/map_from_region.c index de00b714..2f8f753d 100644 --- a/sway/commands/input/map_from_region.c +++ b/sway/commands/input/map_from_region.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -11,11 +10,21 @@ static bool parse_coords(const char *str, double *x, double *y, bool *mm) { | |||
11 | *mm = false; | 10 | *mm = false; |
12 | 11 | ||
13 | char *end; | 12 | char *end; |
14 | *x = strtod(str, &end); | 13 | |
15 | if (end[0] != 'x') { | 14 | // Check for "0x" prefix to avoid strtod treating the string as hex |
16 | return false; | 15 | if (str[0] == '0' && str[1] == 'x') { |
16 | if (strlen(str) < 3) { | ||
17 | return false; | ||
18 | } | ||
19 | *x = 0; | ||
20 | end = (char *)str + 2; | ||
21 | } else { | ||
22 | *x = strtod(str, &end); | ||
23 | if (end[0] != 'x') { | ||
24 | return false; | ||
25 | } | ||
26 | ++end; | ||
17 | } | 27 | } |
18 | ++end; | ||
19 | 28 | ||
20 | *y = strtod(end, &end); | 29 | *y = strtod(end, &end); |
21 | if (end[0] == 'm') { | 30 | if (end[0] == 'm') { |
diff --git a/sway/commands/input/map_to_output.c b/sway/commands/input/map_to_output.c index f60fb7d5..a7266baa 100644 --- a/sway/commands/input/map_to_output.c +++ b/sway/commands/input/map_to_output.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/map_to_region.c b/sway/commands/input/map_to_region.c index e85495e5..9087c589 100644 --- a/sway/commands/input/map_to_region.c +++ b/sway/commands/input/map_to_region.c | |||
@@ -1,7 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | 1 | #include <stdlib.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <wlr/types/wlr_box.h> | ||
5 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
6 | #include "sway/config.h" | 4 | #include "sway/config.h" |
7 | 5 | ||
@@ -50,5 +48,5 @@ struct cmd_results *input_cmd_map_to_region(int argc, char **argv) { | |||
50 | error: | 48 | error: |
51 | free(ic->mapped_to_region); | 49 | free(ic->mapped_to_region); |
52 | ic->mapped_to_region = NULL; | 50 | ic->mapped_to_region = NULL; |
53 | return cmd_results_new(CMD_FAILURE, errstr); | 51 | return cmd_results_new(CMD_FAILURE, "%s", errstr); |
54 | } | 52 | } |
diff --git a/sway/commands/input/rotation_angle.c b/sway/commands/input/rotation_angle.c new file mode 100644 index 00000000..5e278fff --- /dev/null +++ b/sway/commands/input/rotation_angle.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <math.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/commands.h" | ||
6 | #include "sway/input/input-manager.h" | ||
7 | #include "util.h" | ||
8 | |||
9 | struct cmd_results *input_cmd_rotation_angle(int argc, char **argv) { | ||
10 | struct cmd_results *error = NULL; | ||
11 | if ((error = checkarg(argc, "rotation_angle", EXPECTED_AT_LEAST, 1))) { | ||
12 | return error; | ||
13 | } | ||
14 | struct input_config *ic = config->handler_context.input_config; | ||
15 | if (!ic) { | ||
16 | return cmd_results_new(CMD_FAILURE, "No input device defined."); | ||
17 | } | ||
18 | |||
19 | float rotation_angle = parse_float(argv[0]); | ||
20 | if (isnan(rotation_angle)) { | ||
21 | return cmd_results_new(CMD_INVALID, | ||
22 | "Invalid rotation_angle; expected float."); | ||
23 | } if (rotation_angle < 0 || rotation_angle > 360) { | ||
24 | return cmd_results_new(CMD_INVALID, "Input out of range [0, 360)"); | ||
25 | } | ||
26 | ic->rotation_angle = rotation_angle; | ||
27 | |||
28 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
29 | } | ||
diff --git a/sway/commands/input/scroll_button.c b/sway/commands/input/scroll_button.c index 6b331419..81f69a6d 100644 --- a/sway/commands/input/scroll_button.c +++ b/sway/commands/input/scroll_button.c | |||
@@ -21,7 +21,7 @@ struct cmd_results *input_cmd_scroll_button(int argc, char **argv) { | |||
21 | char *message = NULL; | 21 | char *message = NULL; |
22 | uint32_t button = get_mouse_button(*argv, &message); | 22 | uint32_t button = get_mouse_button(*argv, &message); |
23 | if (message) { | 23 | if (message) { |
24 | error = cmd_results_new(CMD_INVALID, message); | 24 | error = cmd_results_new(CMD_INVALID, "%s", message); |
25 | free(message); | 25 | free(message); |
26 | return error; | 26 | return error; |
27 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN | 27 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN |
diff --git a/sway/commands/input/scroll_button_lock.c b/sway/commands/input/scroll_button_lock.c new file mode 100644 index 00000000..f96b6514 --- /dev/null +++ b/sway/commands/input/scroll_button_lock.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <libinput.h> | ||
2 | #include <string.h> | ||
3 | #include <strings.h> | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/commands.h" | ||
6 | #include "sway/input/input-manager.h" | ||
7 | #include "util.h" | ||
8 | |||
9 | struct cmd_results *input_cmd_scroll_button_lock(int argc, char **argv) { | ||
10 | struct cmd_results *error = NULL; | ||
11 | if ((error = checkarg(argc, "scroll_button_lock", EXPECTED_AT_LEAST, 1))) { | ||
12 | return error; | ||
13 | } | ||
14 | struct input_config *ic = config->handler_context.input_config; | ||
15 | if (!ic) { | ||
16 | return cmd_results_new(CMD_FAILURE, "No input device defined."); | ||
17 | } | ||
18 | |||
19 | if (parse_boolean(argv[0], true)) { | ||
20 | ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED; | ||
21 | } else { | ||
22 | ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED; | ||
23 | } | ||
24 | |||
25 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
26 | } | ||
diff --git a/sway/commands/input/xkb_file.c b/sway/commands/input/xkb_file.c index 493f94fb..056f00e5 100644 --- a/sway/commands/input/xkb_file.c +++ b/sway/commands/input/xkb_file.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <unistd.h> | 1 | #include <unistd.h> |
3 | #include <errno.h> | 2 | #include <errno.h> |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c index 22626517..1d01886c 100644 --- a/sway/commands/input/xkb_layout.c +++ b/sway/commands/input/xkb_layout.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c index f4a33de3..a9144a8a 100644 --- a/sway/commands/input/xkb_model.c +++ b/sway/commands/input/xkb_model.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_numlock.c b/sway/commands/input/xkb_numlock.c index 87d3e60c..bbe848fe 100644 --- a/sway/commands/input/xkb_numlock.c +++ b/sway/commands/input/xkb_numlock.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "util.h" | 3 | #include "util.h" |
diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c index d609293f..7ca20777 100644 --- a/sway/commands/input/xkb_options.c +++ b/sway/commands/input/xkb_options.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c index 3b59622c..8fbd26fb 100644 --- a/sway/commands/input/xkb_rules.c +++ b/sway/commands/input/xkb_rules.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index d6548a68..ecac8e6c 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c | |||
@@ -1,10 +1,15 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
2 | #include <wlr/interfaces/wlr_keyboard.h> | ||
3 | #include "sway/config.h" | 3 | #include "sway/config.h" |
4 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
5 | #include "sway/input/input-manager.h" | 5 | #include "sway/input/input-manager.h" |
6 | #include "log.h" | 6 | #include "log.h" |
7 | 7 | ||
8 | struct xkb_switch_layout_action { | ||
9 | struct wlr_keyboard *keyboard; | ||
10 | xkb_layout_index_t layout; | ||
11 | }; | ||
12 | |||
8 | static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { | 13 | static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { |
9 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | 14 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); |
10 | if (idx >= num_layouts) { | 15 | if (idx >= num_layouts) { |
@@ -28,10 +33,10 @@ static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { | |||
28 | return layout_idx; | 33 | return layout_idx; |
29 | } | 34 | } |
30 | 35 | ||
31 | static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { | 36 | static xkb_layout_index_t get_layout_relative(struct wlr_keyboard *kbd, int dir) { |
32 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | 37 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); |
33 | xkb_layout_index_t idx = get_current_layout_index(kbd); | 38 | xkb_layout_index_t idx = get_current_layout_index(kbd); |
34 | switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); | 39 | return (idx + num_layouts + dir) % num_layouts; |
35 | } | 40 | } |
36 | 41 | ||
37 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | 42 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { |
@@ -66,6 +71,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
66 | relative = 0; | 71 | relative = 0; |
67 | } | 72 | } |
68 | 73 | ||
74 | struct xkb_switch_layout_action *actions = calloc( | ||
75 | wl_list_length(&server.input->devices), | ||
76 | sizeof(struct xkb_switch_layout_action)); | ||
77 | size_t actions_len = 0; | ||
78 | |||
79 | if (!actions) { | ||
80 | return cmd_results_new(CMD_FAILURE, "Unable to allocate actions"); | ||
81 | } | ||
82 | |||
83 | /* Calculate new indexes first because switching a layout in one | ||
84 | keyboard may result in a change on other keyboards as well because | ||
85 | of keyboard groups. */ | ||
69 | struct sway_input_device *dev; | 86 | struct sway_input_device *dev; |
70 | wl_list_for_each(dev, &server.input->devices, link) { | 87 | wl_list_for_each(dev, &server.input->devices, link) { |
71 | if (strcmp(ic->identifier, "*") != 0 && | 88 | if (strcmp(ic->identifier, "*") != 0 && |
@@ -76,12 +93,22 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
76 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 93 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
77 | continue; | 94 | continue; |
78 | } | 95 | } |
96 | |||
97 | struct xkb_switch_layout_action *action = | ||
98 | &actions[actions_len++]; | ||
99 | |||
100 | action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device); | ||
79 | if (relative) { | 101 | if (relative) { |
80 | switch_layout_relative(dev->wlr_device->keyboard, relative); | 102 | action->layout = get_layout_relative(action->keyboard, relative); |
81 | } else { | 103 | } else { |
82 | switch_layout(dev->wlr_device->keyboard, layout); | 104 | action->layout = layout; |
83 | } | 105 | } |
84 | } | 106 | } |
85 | 107 | ||
108 | for (size_t i = 0; i < actions_len; i++) { | ||
109 | switch_layout(actions[i].keyboard, actions[i].layout); | ||
110 | } | ||
111 | free(actions); | ||
112 | |||
86 | return cmd_results_new(CMD_SUCCESS, NULL); | 113 | return cmd_results_new(CMD_SUCCESS, NULL); |
87 | } | 114 | } |
diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c index d0e21d77..2d14ea9c 100644 --- a/sway/commands/input/xkb_variant.c +++ b/sway/commands/input/xkb_variant.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include "sway/config.h" | 1 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "log.h" | 3 | #include "log.h" |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index f2af183b..12ce4839 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -133,7 +133,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
133 | 133 | ||
134 | // Operate on parent container, like i3. | 134 | // Operate on parent container, like i3. |
135 | if (container) { | 135 | if (container) { |
136 | container = container->parent; | 136 | container = container->pending.parent; |
137 | } | 137 | } |
138 | 138 | ||
139 | // We could be working with a container OR a workspace. These are different | 139 | // We could be working with a container OR a workspace. These are different |
@@ -142,10 +142,10 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
142 | enum sway_container_layout new_layout = L_NONE; | 142 | enum sway_container_layout new_layout = L_NONE; |
143 | enum sway_container_layout old_layout = L_NONE; | 143 | enum sway_container_layout old_layout = L_NONE; |
144 | if (container) { | 144 | if (container) { |
145 | old_layout = container->layout; | 145 | old_layout = container->pending.layout; |
146 | new_layout = get_layout(argc, argv, | 146 | new_layout = get_layout(argc, argv, |
147 | container->layout, container->prev_split_layout, | 147 | container->pending.layout, container->prev_split_layout, |
148 | container->workspace->output); | 148 | container->pending.workspace->output); |
149 | } else { | 149 | } else { |
150 | old_layout = workspace->layout; | 150 | old_layout = workspace->layout; |
151 | new_layout = get_layout(argc, argv, | 151 | new_layout = get_layout(argc, argv, |
@@ -153,20 +153,20 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
153 | workspace->output); | 153 | workspace->output); |
154 | } | 154 | } |
155 | if (new_layout == L_NONE) { | 155 | if (new_layout == L_NONE) { |
156 | return cmd_results_new(CMD_INVALID, expected_syntax); | 156 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
157 | } | 157 | } |
158 | if (new_layout != old_layout) { | 158 | if (new_layout != old_layout) { |
159 | if (container) { | 159 | if (container) { |
160 | if (old_layout != L_TABBED && old_layout != L_STACKED) { | 160 | if (old_layout != L_TABBED && old_layout != L_STACKED) { |
161 | container->prev_split_layout = old_layout; | 161 | container->prev_split_layout = old_layout; |
162 | } | 162 | } |
163 | container->layout = new_layout; | 163 | container->pending.layout = new_layout; |
164 | container_update_representation(container); | 164 | container_update_representation(container); |
165 | } else if (config->handler_context.container) { | 165 | } else if (config->handler_context.container) { |
166 | // i3 avoids changing workspace layouts with a new container | 166 | // i3 avoids changing workspace layouts with a new container |
167 | // https://github.com/i3/i3/blob/3cd1c45eba6de073bc4300eebb4e1cc1a0c4479a/src/con.c#L1817 | 167 | // https://github.com/i3/i3/blob/3cd1c45eba6de073bc4300eebb4e1cc1a0c4479a/src/con.c#L1817 |
168 | container = workspace_wrap_children(workspace); | 168 | container = workspace_wrap_children(workspace); |
169 | container->layout = new_layout; | 169 | container->pending.layout = new_layout; |
170 | container_update_representation(container); | 170 | container_update_representation(container); |
171 | } else { | 171 | } else { |
172 | if (old_layout != L_TABBED && old_layout != L_STACKED) { | 172 | if (old_layout != L_TABBED && old_layout != L_STACKED) { |
diff --git a/sway/commands/mark.c b/sway/commands/mark.c index aa5f185c..2bfc86b3 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -59,7 +58,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { | |||
59 | } | 58 | } |
60 | 59 | ||
61 | free(mark); | 60 | free(mark); |
62 | container_update_marks_textures(container); | 61 | container_update_marks(container); |
63 | if (container->view) { | 62 | if (container->view) { |
64 | view_execute_criteria(container->view); | 63 | view_execute_criteria(container->view); |
65 | } | 64 | } |
diff --git a/sway/commands/mode.c b/sway/commands/mode.c index a5871dab..b3216967 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | 1 | #include <stdbool.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
@@ -9,12 +8,14 @@ | |||
9 | #include "stringop.h" | 8 | #include "stringop.h" |
10 | 9 | ||
11 | // Must be in order for the bsearch | 10 | // Must be in order for the bsearch |
12 | static struct cmd_handler mode_handlers[] = { | 11 | static const struct cmd_handler mode_handlers[] = { |
13 | { "bindcode", cmd_bindcode }, | 12 | { "bindcode", cmd_bindcode }, |
13 | { "bindgesture", cmd_bindgesture }, | ||
14 | { "bindswitch", cmd_bindswitch }, | 14 | { "bindswitch", cmd_bindswitch }, |
15 | { "bindsym", cmd_bindsym }, | 15 | { "bindsym", cmd_bindsym }, |
16 | { "set", cmd_set }, | 16 | { "set", cmd_set }, |
17 | { "unbindcode", cmd_unbindcode }, | 17 | { "unbindcode", cmd_unbindcode }, |
18 | { "unbindgesture", cmd_unbindgesture }, | ||
18 | { "unbindswitch", cmd_unbindswitch }, | 19 | { "unbindswitch", cmd_unbindswitch }, |
19 | { "unbindsym", cmd_unbindsym }, | 20 | { "unbindsym", cmd_unbindsym }, |
20 | }; | 21 | }; |
@@ -59,6 +60,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) { | |||
59 | mode->keycode_bindings = create_list(); | 60 | mode->keycode_bindings = create_list(); |
60 | mode->mouse_bindings = create_list(); | 61 | mode->mouse_bindings = create_list(); |
61 | mode->switch_bindings = create_list(); | 62 | mode->switch_bindings = create_list(); |
63 | mode->gesture_bindings = create_list(); | ||
62 | mode->pango = pango; | 64 | mode->pango = pango; |
63 | list_add(config->modes, mode); | 65 | list_add(config->modes, mode); |
64 | } | 66 | } |
diff --git a/sway/commands/move.c b/sway/commands/move.c index f8f89f18..8addf26e 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <math.h> | 2 | #include <math.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
@@ -113,8 +112,8 @@ static void container_move_to_container_from_direction( | |||
113 | struct sway_container *container, struct sway_container *destination, | 112 | struct sway_container *container, struct sway_container *destination, |
114 | enum wlr_direction move_dir) { | 113 | enum wlr_direction move_dir) { |
115 | if (destination->view) { | 114 | if (destination->view) { |
116 | if (destination->parent == container->parent && | 115 | if (destination->pending.parent == container->pending.parent && |
117 | destination->workspace == container->workspace) { | 116 | destination->pending.workspace == container->pending.workspace) { |
118 | sway_log(SWAY_DEBUG, "Swapping siblings"); | 117 | sway_log(SWAY_DEBUG, "Swapping siblings"); |
119 | list_t *siblings = container_get_siblings(container); | 118 | list_t *siblings = container_get_siblings(container); |
120 | int container_index = list_find(siblings, container); | 119 | int container_index = list_find(siblings, container); |
@@ -126,28 +125,28 @@ static void container_move_to_container_from_direction( | |||
126 | int offset = | 125 | int offset = |
127 | move_dir == WLR_DIRECTION_LEFT || move_dir == WLR_DIRECTION_UP; | 126 | move_dir == WLR_DIRECTION_LEFT || move_dir == WLR_DIRECTION_UP; |
128 | int index = container_sibling_index(destination) + offset; | 127 | int index = container_sibling_index(destination) + offset; |
129 | if (destination->parent) { | 128 | if (destination->pending.parent) { |
130 | container_insert_child(destination->parent, container, index); | 129 | container_insert_child(destination->pending.parent, container, index); |
131 | } else { | 130 | } else { |
132 | workspace_insert_tiling(destination->workspace, | 131 | workspace_insert_tiling(destination->pending.workspace, |
133 | container, index); | 132 | container, index); |
134 | } | 133 | } |
135 | container->width = container->height = 0; | 134 | container->pending.width = container->pending.height = 0; |
136 | container->width_fraction = container->height_fraction = 0; | 135 | container->width_fraction = container->height_fraction = 0; |
137 | workspace_squash(destination->workspace); | 136 | workspace_squash(destination->pending.workspace); |
138 | } | 137 | } |
139 | return; | 138 | return; |
140 | } | 139 | } |
141 | 140 | ||
142 | if (is_parallel(destination->layout, move_dir)) { | 141 | if (is_parallel(destination->pending.layout, move_dir)) { |
143 | sway_log(SWAY_DEBUG, "Reparenting container (parallel)"); | 142 | sway_log(SWAY_DEBUG, "Reparenting container (parallel)"); |
144 | int index = | 143 | int index = |
145 | move_dir == WLR_DIRECTION_RIGHT || move_dir == WLR_DIRECTION_DOWN ? | 144 | move_dir == WLR_DIRECTION_RIGHT || move_dir == WLR_DIRECTION_DOWN ? |
146 | 0 : destination->children->length; | 145 | 0 : destination->pending.children->length; |
147 | container_insert_child(destination, container, index); | 146 | container_insert_child(destination, container, index); |
148 | container->width = container->height = 0; | 147 | container->pending.width = container->pending.height = 0; |
149 | container->width_fraction = container->height_fraction = 0; | 148 | container->width_fraction = container->height_fraction = 0; |
150 | workspace_squash(destination->workspace); | 149 | workspace_squash(destination->pending.workspace); |
151 | return; | 150 | return; |
152 | } | 151 | } |
153 | 152 | ||
@@ -168,7 +167,7 @@ static void container_move_to_container_from_direction( | |||
168 | static void container_move_to_workspace_from_direction( | 167 | static void container_move_to_workspace_from_direction( |
169 | struct sway_container *container, struct sway_workspace *workspace, | 168 | struct sway_container *container, struct sway_workspace *workspace, |
170 | enum wlr_direction move_dir) { | 169 | enum wlr_direction move_dir) { |
171 | container->width = container->height = 0; | 170 | container->pending.width = container->pending.height = 0; |
172 | container->width_fraction = container->height_fraction = 0; | 171 | container->width_fraction = container->height_fraction = 0; |
173 | 172 | ||
174 | if (is_parallel(workspace->layout, move_dir)) { | 173 | if (is_parallel(workspace->layout, move_dir)) { |
@@ -188,8 +187,8 @@ static void container_move_to_workspace_from_direction( | |||
188 | workspace_add_tiling(workspace, container); | 187 | workspace_add_tiling(workspace, container); |
189 | return; | 188 | return; |
190 | } | 189 | } |
191 | while (focus_inactive->parent) { | 190 | while (focus_inactive->pending.parent) { |
192 | focus_inactive = focus_inactive->parent; | 191 | focus_inactive = focus_inactive->pending.parent; |
193 | } | 192 | } |
194 | container_move_to_container_from_direction(container, focus_inactive, | 193 | container_move_to_container_from_direction(container, focus_inactive, |
195 | move_dir); | 194 | move_dir); |
@@ -197,25 +196,33 @@ static void container_move_to_workspace_from_direction( | |||
197 | 196 | ||
198 | static void container_move_to_workspace(struct sway_container *container, | 197 | static void container_move_to_workspace(struct sway_container *container, |
199 | struct sway_workspace *workspace) { | 198 | struct sway_workspace *workspace) { |
200 | if (container->workspace == workspace) { | 199 | if (container->pending.workspace == workspace) { |
201 | return; | 200 | return; |
202 | } | 201 | } |
203 | struct sway_workspace *old_workspace = container->workspace; | 202 | struct sway_workspace *old_workspace = container->pending.workspace; |
204 | if (container_is_floating(container)) { | 203 | if (container_is_floating(container)) { |
205 | struct sway_output *old_output = container->workspace->output; | 204 | struct sway_output *old_output = container->pending.workspace->output; |
206 | container_detach(container); | 205 | container_detach(container); |
207 | workspace_add_floating(workspace, container); | 206 | workspace_add_floating(workspace, container); |
208 | container_handle_fullscreen_reparent(container); | 207 | container_handle_fullscreen_reparent(container); |
209 | // If changing output, center it within the workspace | 208 | // If changing output, adjust the coordinates of the window. |
210 | if (old_output != workspace->output && !container->fullscreen_mode) { | 209 | if (old_output != workspace->output && !container->pending.fullscreen_mode) { |
211 | container_floating_move_to_center(container); | 210 | struct wlr_box workspace_box, old_workspace_box; |
211 | workspace_get_box(workspace, &workspace_box); | ||
212 | workspace_get_box(old_workspace, &old_workspace_box); | ||
213 | floating_fix_coordinates(container, &old_workspace_box, &workspace_box); | ||
214 | if (container->scratchpad && workspace->output) { | ||
215 | struct wlr_box output_box; | ||
216 | output_get_box(workspace->output, &output_box); | ||
217 | container->transform = workspace_box; | ||
218 | } | ||
212 | } | 219 | } |
213 | } else { | 220 | } else { |
214 | container_detach(container); | 221 | container_detach(container); |
215 | if (workspace_is_empty(workspace) && container->children) { | 222 | if (workspace_is_empty(workspace) && container->pending.children) { |
216 | workspace_unwrap_children(workspace, container); | 223 | workspace_unwrap_children(workspace, container); |
217 | } else { | 224 | } else { |
218 | container->width = container->height = 0; | 225 | container->pending.width = container->pending.height = 0; |
219 | container->width_fraction = container->height_fraction = 0; | 226 | container->width_fraction = container->height_fraction = 0; |
220 | workspace_add_tiling(workspace, container); | 227 | workspace_add_tiling(workspace, container); |
221 | } | 228 | } |
@@ -237,13 +244,13 @@ static void container_move_to_container(struct sway_container *container, | |||
237 | return; | 244 | return; |
238 | } | 245 | } |
239 | if (container_is_floating(container)) { | 246 | if (container_is_floating(container)) { |
240 | container_move_to_workspace(container, destination->workspace); | 247 | container_move_to_workspace(container, destination->pending.workspace); |
241 | return; | 248 | return; |
242 | } | 249 | } |
243 | struct sway_workspace *old_workspace = container->workspace; | 250 | struct sway_workspace *old_workspace = container->pending.workspace; |
244 | 251 | ||
245 | container_detach(container); | 252 | container_detach(container); |
246 | container->width = container->height = 0; | 253 | container->pending.width = container->pending.height = 0; |
247 | container->width_fraction = container->height_fraction = 0; | 254 | container->width_fraction = container->height_fraction = 0; |
248 | 255 | ||
249 | if (destination->view) { | 256 | if (destination->view) { |
@@ -256,12 +263,12 @@ static void container_move_to_container(struct sway_container *container, | |||
256 | ipc_event_window(container, "move"); | 263 | ipc_event_window(container, "move"); |
257 | } | 264 | } |
258 | 265 | ||
259 | if (destination->workspace) { | 266 | if (destination->pending.workspace) { |
260 | workspace_focus_fullscreen(destination->workspace); | 267 | workspace_focus_fullscreen(destination->pending.workspace); |
261 | workspace_detect_urgent(destination->workspace); | 268 | workspace_detect_urgent(destination->pending.workspace); |
262 | } | 269 | } |
263 | 270 | ||
264 | if (old_workspace && old_workspace != destination->workspace) { | 271 | if (old_workspace && old_workspace != destination->pending.workspace) { |
265 | workspace_detect_urgent(old_workspace); | 272 | workspace_detect_urgent(old_workspace); |
266 | } | 273 | } |
267 | } | 274 | } |
@@ -275,7 +282,7 @@ static bool container_move_to_next_output(struct sway_container *container, | |||
275 | if (!sway_assert(ws, "Expected output to have a workspace")) { | 282 | if (!sway_assert(ws, "Expected output to have a workspace")) { |
276 | return false; | 283 | return false; |
277 | } | 284 | } |
278 | switch (container->fullscreen_mode) { | 285 | switch (container->pending.fullscreen_mode) { |
279 | case FULLSCREEN_NONE: | 286 | case FULLSCREEN_NONE: |
280 | container_move_to_workspace_from_direction(container, ws, move_dir); | 287 | container_move_to_workspace_from_direction(container, ws, move_dir); |
281 | return true; | 288 | return true; |
@@ -293,12 +300,12 @@ static bool container_move_to_next_output(struct sway_container *container, | |||
293 | static bool container_move_in_direction(struct sway_container *container, | 300 | static bool container_move_in_direction(struct sway_container *container, |
294 | enum wlr_direction move_dir) { | 301 | enum wlr_direction move_dir) { |
295 | // If moving a fullscreen view, only consider outputs | 302 | // If moving a fullscreen view, only consider outputs |
296 | switch (container->fullscreen_mode) { | 303 | switch (container->pending.fullscreen_mode) { |
297 | case FULLSCREEN_NONE: | 304 | case FULLSCREEN_NONE: |
298 | break; | 305 | break; |
299 | case FULLSCREEN_WORKSPACE: | 306 | case FULLSCREEN_WORKSPACE: |
300 | return container_move_to_next_output(container, | 307 | return container_move_to_next_output(container, |
301 | container->workspace->output, move_dir); | 308 | container->pending.workspace->output, move_dir); |
302 | case FULLSCREEN_GLOBAL: | 309 | case FULLSCREEN_GLOBAL: |
303 | return false; | 310 | return false; |
304 | } | 311 | } |
@@ -317,26 +324,26 @@ static bool container_move_in_direction(struct sway_container *container, | |||
317 | while (!ancestor) { | 324 | while (!ancestor) { |
318 | // Don't allow containers to move out of their | 325 | // Don't allow containers to move out of their |
319 | // fullscreen or floating parent | 326 | // fullscreen or floating parent |
320 | if (current->fullscreen_mode || container_is_floating(current)) { | 327 | if (current->pending.fullscreen_mode || container_is_floating(current)) { |
321 | return false; | 328 | return false; |
322 | } | 329 | } |
323 | 330 | ||
324 | enum sway_container_layout parent_layout = container_parent_layout(current); | 331 | enum sway_container_layout parent_layout = container_parent_layout(current); |
325 | if (!is_parallel(parent_layout, move_dir)) { | 332 | if (!is_parallel(parent_layout, move_dir)) { |
326 | if (!current->parent) { | 333 | if (!current->pending.parent) { |
327 | // No parallel parent, so we reorient the workspace | 334 | // No parallel parent, so we reorient the workspace |
328 | current = workspace_wrap_children(current->workspace); | 335 | current = workspace_wrap_children(current->pending.workspace); |
329 | current->workspace->layout = | 336 | current->pending.workspace->layout = |
330 | move_dir == WLR_DIRECTION_LEFT || | 337 | move_dir == WLR_DIRECTION_LEFT || |
331 | move_dir == WLR_DIRECTION_RIGHT ? | 338 | move_dir == WLR_DIRECTION_RIGHT ? |
332 | L_HORIZ : L_VERT; | 339 | L_HORIZ : L_VERT; |
333 | container->height = container->width = 0; | 340 | container->pending.height = container->pending.width = 0; |
334 | container->height_fraction = container->width_fraction = 0; | 341 | container->height_fraction = container->width_fraction = 0; |
335 | workspace_update_representation(current->workspace); | 342 | workspace_update_representation(current->pending.workspace); |
336 | wrapped = true; | 343 | wrapped = true; |
337 | } else { | 344 | } else { |
338 | // Keep looking for a parallel parent | 345 | // Keep looking for a parallel parent |
339 | current = current->parent; | 346 | current = current->pending.parent; |
340 | } | 347 | } |
341 | continue; | 348 | continue; |
342 | } | 349 | } |
@@ -356,14 +363,14 @@ static bool container_move_in_direction(struct sway_container *container, | |||
356 | container_move_to_container_from_direction(container, | 363 | container_move_to_container_from_direction(container, |
357 | target, move_dir); | 364 | target, move_dir); |
358 | return true; | 365 | return true; |
359 | } else if (!container->parent) { | 366 | } else if (!container->pending.parent) { |
360 | // Container is at workspace level so we move it to the | 367 | // Container is at workspace level so we move it to the |
361 | // next workspace if possible | 368 | // next workspace if possible |
362 | return container_move_to_next_output(container, | 369 | return container_move_to_next_output(container, |
363 | current->workspace->output, move_dir); | 370 | current->pending.workspace->output, move_dir); |
364 | } else { | 371 | } else { |
365 | // Container has escaped its immediate parallel parent | 372 | // Container has escaped its immediate parallel parent |
366 | current = current->parent; | 373 | current = current->pending.parent; |
367 | continue; | 374 | continue; |
368 | } | 375 | } |
369 | } | 376 | } |
@@ -377,31 +384,31 @@ static bool container_move_in_direction(struct sway_container *container, | |||
377 | container_move_to_container_from_direction(container, | 384 | container_move_to_container_from_direction(container, |
378 | target, move_dir); | 385 | target, move_dir); |
379 | return true; | 386 | return true; |
380 | } else if (!wrapped && !container->parent->parent && | 387 | } else if (!wrapped && !container->pending.parent->pending.parent && |
381 | container->parent->children->length == 1) { | 388 | container->pending.parent->pending.children->length == 1) { |
382 | // Treat singleton children as if they are at workspace level like i3 | 389 | // Treat singleton children as if they are at workspace level like i3 |
383 | // https://github.com/i3/i3/blob/1d9160f2d247dbaa83fb62f02fd7041dec767fc2/src/move.c#L367 | 390 | // https://github.com/i3/i3/blob/1d9160f2d247dbaa83fb62f02fd7041dec767fc2/src/move.c#L367 |
384 | return container_move_to_next_output(container, | 391 | return container_move_to_next_output(container, |
385 | ancestor->workspace->output, move_dir); | 392 | ancestor->pending.workspace->output, move_dir); |
386 | } else { | 393 | } else { |
387 | // Container will be promoted | 394 | // Container will be promoted |
388 | struct sway_container *old_parent = container->parent; | 395 | struct sway_container *old_parent = container->pending.parent; |
389 | if (ancestor->parent) { | 396 | if (ancestor->pending.parent) { |
390 | // Container will move in with its parent | 397 | // Container will move in with its parent |
391 | container_insert_child(ancestor->parent, container, | 398 | container_insert_child(ancestor->pending.parent, container, |
392 | index + (offs < 0 ? 0 : 1)); | 399 | index + (offs < 0 ? 0 : 1)); |
393 | } else { | 400 | } else { |
394 | // Container will move to workspace level, | 401 | // Container will move to workspace level, |
395 | // may be re-split by workspace_layout | 402 | // may be re-split by workspace_layout |
396 | workspace_insert_tiling(ancestor->workspace, container, | 403 | workspace_insert_tiling(ancestor->pending.workspace, container, |
397 | index + (offs < 0 ? 0 : 1)); | 404 | index + (offs < 0 ? 0 : 1)); |
398 | } | 405 | } |
399 | ancestor->height = ancestor->width = 0; | 406 | ancestor->pending.height = ancestor->pending.width = 0; |
400 | ancestor->height_fraction = ancestor->width_fraction = 0; | 407 | ancestor->height_fraction = ancestor->width_fraction = 0; |
401 | if (old_parent) { | 408 | if (old_parent) { |
402 | container_reap_empty(old_parent); | 409 | container_reap_empty(old_parent); |
403 | } | 410 | } |
404 | workspace_squash(container->workspace); | 411 | workspace_squash(container->pending.workspace); |
405 | return true; | 412 | return true; |
406 | } | 413 | } |
407 | } | 414 | } |
@@ -427,14 +434,14 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, | |||
427 | container = workspace_wrap_children(workspace); | 434 | container = workspace_wrap_children(workspace); |
428 | } | 435 | } |
429 | 436 | ||
430 | if (container->fullscreen_mode == FULLSCREEN_GLOBAL) { | 437 | if (container->pending.fullscreen_mode == FULLSCREEN_GLOBAL) { |
431 | return cmd_results_new(CMD_FAILURE, | 438 | return cmd_results_new(CMD_FAILURE, |
432 | "Can't move fullscreen global container"); | 439 | "Can't move fullscreen global container"); |
433 | } | 440 | } |
434 | 441 | ||
435 | struct sway_seat *seat = config->handler_context.seat; | 442 | struct sway_seat *seat = config->handler_context.seat; |
436 | struct sway_container *old_parent = container->parent; | 443 | struct sway_container *old_parent = container->pending.parent; |
437 | struct sway_workspace *old_ws = container->workspace; | 444 | struct sway_workspace *old_ws = container->pending.workspace; |
438 | struct sway_output *old_output = old_ws ? old_ws->output : NULL; | 445 | struct sway_output *old_output = old_ws ? old_ws->output : NULL; |
439 | struct sway_node *destination = NULL; | 446 | struct sway_node *destination = NULL; |
440 | 447 | ||
@@ -462,7 +469,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, | |||
462 | if (strcasecmp(argv[1], "number") == 0) { | 469 | if (strcasecmp(argv[1], "number") == 0) { |
463 | // move [window|container] [to] "workspace number x" | 470 | // move [window|container] [to] "workspace number x" |
464 | if (argc < 3) { | 471 | if (argc < 3) { |
465 | return cmd_results_new(CMD_INVALID, expected_syntax); | 472 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
466 | } | 473 | } |
467 | if (!isdigit(argv[2][0])) { | 474 | if (!isdigit(argv[2][0])) { |
468 | return cmd_results_new(CMD_INVALID, | 475 | return cmd_results_new(CMD_INVALID, |
@@ -508,7 +515,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, | |||
508 | destination = dst ? &dst->node : &ws->node; | 515 | destination = dst ? &dst->node : &ws->node; |
509 | } else if (strcasecmp(argv[0], "output") == 0) { | 516 | } else if (strcasecmp(argv[0], "output") == 0) { |
510 | struct sway_output *new_output = output_in_direction(argv[1], | 517 | struct sway_output *new_output = output_in_direction(argv[1], |
511 | old_output, container->x, container->y); | 518 | old_output, container->pending.x, container->pending.y); |
512 | if (!new_output) { | 519 | if (!new_output) { |
513 | return cmd_results_new(CMD_FAILURE, | 520 | return cmd_results_new(CMD_FAILURE, |
514 | "Can't find output with name/direction '%s'", argv[1]); | 521 | "Can't find output with name/direction '%s'", argv[1]); |
@@ -522,7 +529,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, | |||
522 | } | 529 | } |
523 | destination = &dest_con->node; | 530 | destination = &dest_con->node; |
524 | } else { | 531 | } else { |
525 | return cmd_results_new(CMD_INVALID, expected_syntax); | 532 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
526 | } | 533 | } |
527 | 534 | ||
528 | if (destination->type == N_CONTAINER && | 535 | if (destination->type == N_CONTAINER && |
@@ -686,6 +693,9 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) { | |||
686 | arrange_output(old_output); | 693 | arrange_output(old_output); |
687 | arrange_output(new_output); | 694 | arrange_output(new_output); |
688 | 695 | ||
696 | struct sway_seat *seat = config->handler_context.seat; | ||
697 | seat_consider_warp_to_focus(seat); | ||
698 | |||
689 | return cmd_results_new(CMD_SUCCESS, NULL); | 699 | return cmd_results_new(CMD_SUCCESS, NULL); |
690 | } | 700 | } |
691 | 701 | ||
@@ -706,12 +716,12 @@ static struct cmd_results *cmd_move_in_direction( | |||
706 | "Cannot move workspaces in a direction"); | 716 | "Cannot move workspaces in a direction"); |
707 | } | 717 | } |
708 | if (container_is_floating(container)) { | 718 | if (container_is_floating(container)) { |
709 | if (container->fullscreen_mode) { | 719 | if (container->pending.fullscreen_mode) { |
710 | return cmd_results_new(CMD_FAILURE, | 720 | return cmd_results_new(CMD_FAILURE, |
711 | "Cannot move fullscreen floating container"); | 721 | "Cannot move fullscreen floating container"); |
712 | } | 722 | } |
713 | double lx = container->x; | 723 | double lx = container->pending.x; |
714 | double ly = container->y; | 724 | double ly = container->pending.y; |
715 | switch (direction) { | 725 | switch (direction) { |
716 | case WLR_DIRECTION_LEFT: | 726 | case WLR_DIRECTION_LEFT: |
717 | lx -= move_amt; | 727 | lx -= move_amt; |
@@ -729,8 +739,8 @@ static struct cmd_results *cmd_move_in_direction( | |||
729 | container_floating_move_to(container, lx, ly); | 739 | container_floating_move_to(container, lx, ly); |
730 | return cmd_results_new(CMD_SUCCESS, NULL); | 740 | return cmd_results_new(CMD_SUCCESS, NULL); |
731 | } | 741 | } |
732 | struct sway_workspace *old_ws = container->workspace; | 742 | struct sway_workspace *old_ws = container->pending.workspace; |
733 | struct sway_container *old_parent = container->parent; | 743 | struct sway_container *old_parent = container->pending.parent; |
734 | 744 | ||
735 | if (!container_move_in_direction(container, direction)) { | 745 | if (!container_move_in_direction(container, direction)) { |
736 | // Container didn't move | 746 | // Container didn't move |
@@ -744,7 +754,7 @@ static struct cmd_results *cmd_move_in_direction( | |||
744 | workspace_consider_destroy(old_ws); | 754 | workspace_consider_destroy(old_ws); |
745 | } | 755 | } |
746 | 756 | ||
747 | struct sway_workspace *new_ws = container->workspace; | 757 | struct sway_workspace *new_ws = container->pending.workspace; |
748 | 758 | ||
749 | if (root->fullscreen_global) { | 759 | if (root->fullscreen_global) { |
750 | arrange_root(); | 760 | arrange_root(); |
@@ -759,15 +769,6 @@ static struct cmd_results *cmd_move_in_direction( | |||
759 | ipc_event_window(container, "move"); | 769 | ipc_event_window(container, "move"); |
760 | } | 770 | } |
761 | 771 | ||
762 | // Hack to re-focus container | ||
763 | seat_set_raw_focus(config->handler_context.seat, &new_ws->node); | ||
764 | seat_set_focus_container(config->handler_context.seat, container); | ||
765 | |||
766 | if (old_ws != new_ws) { | ||
767 | ipc_event_workspace(old_ws, new_ws, "focus"); | ||
768 | workspace_detect_urgent(old_ws); | ||
769 | workspace_detect_urgent(new_ws); | ||
770 | } | ||
771 | container_end_mouse_operation(container); | 772 | container_end_mouse_operation(container); |
772 | 773 | ||
773 | return cmd_results_new(CMD_SUCCESS, NULL); | 774 | return cmd_results_new(CMD_SUCCESS, NULL); |
@@ -781,22 +782,22 @@ static struct cmd_results *cmd_move_to_position_pointer( | |||
781 | } | 782 | } |
782 | struct wlr_cursor *cursor = seat->cursor->cursor; | 783 | struct wlr_cursor *cursor = seat->cursor->cursor; |
783 | /* Determine where to put the window. */ | 784 | /* Determine where to put the window. */ |
784 | double lx = cursor->x - container->width / 2; | 785 | double lx = cursor->x - container->pending.width / 2; |
785 | double ly = cursor->y - container->height / 2; | 786 | double ly = cursor->y - container->pending.height / 2; |
786 | 787 | ||
787 | /* Correct target coordinates to be in bounds (on screen). */ | 788 | /* Correct target coordinates to be in bounds (on screen). */ |
788 | struct wlr_output *output = wlr_output_layout_output_at( | 789 | struct wlr_output *output = wlr_output_layout_output_at( |
789 | root->output_layout, cursor->x, cursor->y); | 790 | root->output_layout, cursor->x, cursor->y); |
790 | if (output) { | 791 | if (output) { |
791 | struct wlr_box *box = | 792 | struct wlr_box box; |
792 | wlr_output_layout_get_box(root->output_layout, output); | 793 | wlr_output_layout_get_box(root->output_layout, output, &box); |
793 | lx = fmax(lx, box->x); | 794 | lx = fmax(lx, box.x); |
794 | ly = fmax(ly, box->y); | 795 | ly = fmax(ly, box.y); |
795 | if (lx + container->width > box->x + box->width) { | 796 | if (lx + container->pending.width > box.x + box.width) { |
796 | lx = box->x + box->width - container->width; | 797 | lx = box.x + box.width - container->pending.width; |
797 | } | 798 | } |
798 | if (ly + container->height > box->y + box->height) { | 799 | if (ly + container->pending.height > box.y + box.height) { |
799 | ly = box->y + box->height - container->height; | 800 | ly = box.y + box.height - container->pending.height; |
800 | } | 801 | } |
801 | } | 802 | } |
802 | 803 | ||
@@ -818,7 +819,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) { | |||
818 | } | 819 | } |
819 | 820 | ||
820 | if (!argc) { | 821 | if (!argc) { |
821 | return cmd_results_new(CMD_INVALID, expected_position_syntax); | 822 | return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax); |
822 | } | 823 | } |
823 | 824 | ||
824 | bool absolute = false; | 825 | bool absolute = false; |
@@ -828,41 +829,41 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) { | |||
828 | ++argv; | 829 | ++argv; |
829 | } | 830 | } |
830 | if (!argc) { | 831 | if (!argc) { |
831 | return cmd_results_new(CMD_INVALID, expected_position_syntax); | 832 | return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax); |
832 | } | 833 | } |
833 | if (strcmp(argv[0], "position") == 0) { | 834 | if (strcmp(argv[0], "position") == 0) { |
834 | --argc; | 835 | --argc; |
835 | ++argv; | 836 | ++argv; |
836 | } | 837 | } |
837 | if (!argc) { | 838 | if (!argc) { |
838 | return cmd_results_new(CMD_INVALID, expected_position_syntax); | 839 | return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax); |
839 | } | 840 | } |
840 | if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 || | 841 | if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 || |
841 | strcmp(argv[0], "pointer") == 0) { | 842 | strcmp(argv[0], "pointer") == 0) { |
842 | if (absolute) { | 843 | if (absolute) { |
843 | return cmd_results_new(CMD_INVALID, expected_position_syntax); | 844 | return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax); |
844 | } | 845 | } |
845 | return cmd_move_to_position_pointer(container); | 846 | return cmd_move_to_position_pointer(container); |
846 | } else if (strcmp(argv[0], "center") == 0) { | 847 | } else if (strcmp(argv[0], "center") == 0) { |
847 | double lx, ly; | 848 | double lx, ly; |
848 | if (absolute) { | 849 | if (absolute) { |
849 | lx = root->x + (root->width - container->width) / 2; | 850 | lx = root->x + (root->width - container->pending.width) / 2; |
850 | ly = root->y + (root->height - container->height) / 2; | 851 | ly = root->y + (root->height - container->pending.height) / 2; |
851 | } else { | 852 | } else { |
852 | struct sway_workspace *ws = container->workspace; | 853 | struct sway_workspace *ws = container->pending.workspace; |
853 | if (!ws) { | 854 | if (!ws) { |
854 | struct sway_seat *seat = config->handler_context.seat; | 855 | struct sway_seat *seat = config->handler_context.seat; |
855 | ws = seat_get_focused_workspace(seat); | 856 | ws = seat_get_focused_workspace(seat); |
856 | } | 857 | } |
857 | lx = ws->x + (ws->width - container->width) / 2; | 858 | lx = ws->x + (ws->width - container->pending.width) / 2; |
858 | ly = ws->y + (ws->height - container->height) / 2; | 859 | ly = ws->y + (ws->height - container->pending.height) / 2; |
859 | } | 860 | } |
860 | container_floating_move_to(container, lx, ly); | 861 | container_floating_move_to(container, lx, ly); |
861 | return cmd_results_new(CMD_SUCCESS, NULL); | 862 | return cmd_results_new(CMD_SUCCESS, NULL); |
862 | } | 863 | } |
863 | 864 | ||
864 | if (argc < 2) { | 865 | if (argc < 2) { |
865 | return cmd_results_new(CMD_FAILURE, expected_position_syntax); | 866 | return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax); |
866 | } | 867 | } |
867 | 868 | ||
868 | struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID }; | 869 | struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID }; |
@@ -874,19 +875,23 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) { | |||
874 | return cmd_results_new(CMD_INVALID, "Invalid x position specified"); | 875 | return cmd_results_new(CMD_INVALID, "Invalid x position specified"); |
875 | } | 876 | } |
876 | 877 | ||
878 | if (argc < 1) { | ||
879 | return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax); | ||
880 | } | ||
881 | |||
877 | struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID }; | 882 | struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID }; |
878 | // Y direction | 883 | // Y direction |
879 | num_consumed_args = parse_movement_amount(argc, argv, &ly); | 884 | num_consumed_args = parse_movement_amount(argc, argv, &ly); |
880 | argc -= num_consumed_args; | 885 | argc -= num_consumed_args; |
881 | argv += num_consumed_args; | 886 | argv += num_consumed_args; |
882 | if (argc > 0) { | 887 | if (argc > 0) { |
883 | return cmd_results_new(CMD_INVALID, expected_position_syntax); | 888 | return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax); |
884 | } | 889 | } |
885 | if (ly.unit == MOVEMENT_UNIT_INVALID) { | 890 | if (ly.unit == MOVEMENT_UNIT_INVALID) { |
886 | return cmd_results_new(CMD_INVALID, "Invalid y position specified"); | 891 | return cmd_results_new(CMD_INVALID, "Invalid y position specified"); |
887 | } | 892 | } |
888 | 893 | ||
889 | struct sway_workspace *ws = container->workspace; | 894 | struct sway_workspace *ws = container->pending.workspace; |
890 | if (!ws) { | 895 | if (!ws) { |
891 | struct sway_seat *seat = config->handler_context.seat; | 896 | struct sway_seat *seat = config->handler_context.seat; |
892 | ws = seat_get_focused_workspace(seat); | 897 | ws = seat_get_focused_workspace(seat); |
@@ -960,14 +965,14 @@ static struct cmd_results *cmd_move_to_scratchpad(void) { | |||
960 | // If the container is in a floating split container, | 965 | // If the container is in a floating split container, |
961 | // operate on the split container instead of the child. | 966 | // operate on the split container instead of the child. |
962 | if (container_is_floating_or_child(con)) { | 967 | if (container_is_floating_or_child(con)) { |
963 | while (con->parent) { | 968 | while (con->pending.parent) { |
964 | con = con->parent; | 969 | con = con->pending.parent; |
965 | } | 970 | } |
966 | } | 971 | } |
967 | 972 | ||
968 | if (!con->scratchpad) { | 973 | if (!con->scratchpad) { |
969 | root_scratchpad_add_container(con, NULL); | 974 | root_scratchpad_add_container(con, NULL); |
970 | } else if (con->workspace) { | 975 | } else if (con->pending.workspace) { |
971 | root_scratchpad_hide(con); | 976 | root_scratchpad_hide(con); |
972 | } | 977 | } |
973 | return cmd_results_new(CMD_SUCCESS, NULL); | 978 | return cmd_results_new(CMD_SUCCESS, NULL); |
@@ -1026,13 +1031,13 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
1026 | } | 1031 | } |
1027 | 1032 | ||
1028 | if (!argc) { | 1033 | if (!argc) { |
1029 | return cmd_results_new(CMD_INVALID, expected_full_syntax); | 1034 | return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax); |
1030 | } | 1035 | } |
1031 | 1036 | ||
1032 | // Only `move [window|container] [to] workspace` supports | 1037 | // Only `move [window|container] [to] workspace` supports |
1033 | // `--no-auto-back-and-forth` so treat others as invalid syntax | 1038 | // `--no-auto-back-and-forth` so treat others as invalid syntax |
1034 | if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) { | 1039 | if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) { |
1035 | return cmd_results_new(CMD_INVALID, expected_full_syntax); | 1040 | return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax); |
1036 | } | 1041 | } |
1037 | 1042 | ||
1038 | if (strcasecmp(argv[0], "workspace") == 0 || | 1043 | if (strcasecmp(argv[0], "workspace") == 0 || |
@@ -1046,5 +1051,5 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
1046 | strcasecmp(argv[1], "position") == 0)) { | 1051 | strcasecmp(argv[1], "position") == 0)) { |
1047 | return cmd_move_to_position(argc, argv); | 1052 | return cmd_move_to_position(argc, argv); |
1048 | } | 1053 | } |
1049 | return cmd_results_new(CMD_INVALID, expected_full_syntax); | 1054 | return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax); |
1050 | } | 1055 | } |
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c index 2001e04f..ccfdec82 100644 --- a/sway/commands/no_focus.c +++ b/sway/commands/no_focus.c | |||
@@ -13,7 +13,7 @@ struct cmd_results *cmd_no_focus(int argc, char **argv) { | |||
13 | char *err_str = NULL; | 13 | char *err_str = NULL; |
14 | struct criteria *criteria = criteria_parse(argv[0], &err_str); | 14 | struct criteria *criteria = criteria_parse(argv[0], &err_str); |
15 | if (!criteria) { | 15 | if (!criteria) { |
16 | error = cmd_results_new(CMD_INVALID, err_str); | 16 | error = cmd_results_new(CMD_INVALID, "%s", err_str); |
17 | free(err_str); | 17 | free(err_str); |
18 | return error; | 18 | return error; |
19 | } | 19 | } |
diff --git a/sway/commands/opacity.c b/sway/commands/opacity.c index 96e6228e..610cecc6 100644 --- a/sway/commands/opacity.c +++ b/sway/commands/opacity.c | |||
@@ -37,6 +37,7 @@ struct cmd_results *cmd_opacity(int argc, char **argv) { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | con->alpha = val; | 39 | con->alpha = val; |
40 | container_damage_whole(con); | 40 | container_update(con); |
41 | |||
41 | return cmd_results_new(CMD_SUCCESS, NULL); | 42 | return cmd_results_new(CMD_SUCCESS, NULL); |
42 | } | 43 | } |
diff --git a/sway/commands/output.c b/sway/commands/output.c index 5186a2ba..5e5d31b3 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -6,7 +6,7 @@ | |||
6 | #include "log.h" | 6 | #include "log.h" |
7 | 7 | ||
8 | // must be in order for the bsearch | 8 | // must be in order for the bsearch |
9 | static struct cmd_handler output_handlers[] = { | 9 | static const struct cmd_handler output_handlers[] = { |
10 | { "adaptive_sync", output_cmd_adaptive_sync }, | 10 | { "adaptive_sync", output_cmd_adaptive_sync }, |
11 | { "background", output_cmd_background }, | 11 | { "background", output_cmd_background }, |
12 | { "bg", output_cmd_background }, | 12 | { "bg", output_cmd_background }, |
@@ -15,8 +15,11 @@ static struct cmd_handler output_handlers[] = { | |||
15 | { "enable", output_cmd_enable }, | 15 | { "enable", output_cmd_enable }, |
16 | { "max_render_time", output_cmd_max_render_time }, | 16 | { "max_render_time", output_cmd_max_render_time }, |
17 | { "mode", output_cmd_mode }, | 17 | { "mode", output_cmd_mode }, |
18 | { "modeline", output_cmd_modeline }, | ||
18 | { "pos", output_cmd_position }, | 19 | { "pos", output_cmd_position }, |
19 | { "position", output_cmd_position }, | 20 | { "position", output_cmd_position }, |
21 | { "power", output_cmd_power }, | ||
22 | { "render_bit_depth", output_cmd_render_bit_depth }, | ||
20 | { "res", output_cmd_mode }, | 23 | { "res", output_cmd_mode }, |
21 | { "resolution", output_cmd_mode }, | 24 | { "resolution", output_cmd_mode }, |
22 | { "scale", output_cmd_scale }, | 25 | { "scale", output_cmd_scale }, |
@@ -24,6 +27,7 @@ static struct cmd_handler output_handlers[] = { | |||
24 | { "subpixel", output_cmd_subpixel }, | 27 | { "subpixel", output_cmd_subpixel }, |
25 | { "toggle", output_cmd_toggle }, | 28 | { "toggle", output_cmd_toggle }, |
26 | { "transform", output_cmd_transform }, | 29 | { "transform", output_cmd_transform }, |
30 | { "unplug", output_cmd_unplug }, | ||
27 | }; | 31 | }; |
28 | 32 | ||
29 | struct cmd_results *cmd_output(int argc, char **argv) { | 33 | struct cmd_results *cmd_output(int argc, char **argv) { |
@@ -32,9 +36,9 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
32 | return error; | 36 | return error; |
33 | } | 37 | } |
34 | 38 | ||
35 | // The NOOP-1 output is a dummy output used when there's no outputs | 39 | // The HEADLESS-1 output is a dummy output used when there's no outputs |
36 | // connected. It should never be configured. | 40 | // connected. It should never be configured. |
37 | if (strcasecmp(argv[0], root->noop_output->wlr_output->name) == 0) { | 41 | if (strcasecmp(argv[0], root->fallback_output->wlr_output->name) == 0) { |
38 | return cmd_results_new(CMD_FAILURE, | 42 | return cmd_results_new(CMD_FAILURE, |
39 | "Refusing to configure the no op output"); | 43 | "Refusing to configure the no op output"); |
40 | } | 44 | } |
@@ -51,7 +55,7 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
51 | if (!sway_output) { | 55 | if (!sway_output) { |
52 | return cmd_results_new(CMD_FAILURE, "Unknown output"); | 56 | return cmd_results_new(CMD_FAILURE, "Unknown output"); |
53 | } | 57 | } |
54 | if (sway_output == root->noop_output) { | 58 | if (sway_output == root->fallback_output) { |
55 | return cmd_results_new(CMD_FAILURE, | 59 | return cmd_results_new(CMD_FAILURE, |
56 | "Refusing to configure the no op output"); | 60 | "Refusing to configure the no op output"); |
57 | } | 61 | } |
@@ -99,15 +103,18 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
99 | 103 | ||
100 | bool background = output->background; | 104 | bool background = output->background; |
101 | 105 | ||
102 | output = store_output_config(output); | 106 | store_output_config(output); |
103 | 107 | ||
104 | // If reloading, the output configs will be applied after reading the | 108 | // If reloading, the output configs will be applied after reading the |
105 | // entire config and before the deferred commands so that an auto generated | 109 | // entire config and before the deferred commands so that an auto generated |
106 | // workspace name is not given to re-enabled outputs. | 110 | // workspace name is not given to re-enabled outputs. |
107 | if (!config->reloading && !config->validating) { | 111 | if (!config->reloading && !config->validating) { |
108 | apply_output_config_to_outputs(output); | 112 | apply_all_output_configs(); |
109 | if (background) { | 113 | if (background) { |
110 | spawn_swaybg(); | 114 | if (!spawn_swaybg()) { |
115 | return cmd_results_new(CMD_FAILURE, | ||
116 | "Failed to apply background configuration"); | ||
117 | } | ||
111 | } | 118 | } |
112 | } | 119 | } |
113 | 120 | ||
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index 68ee9fe1..55bd7671 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <libgen.h> | 1 | #include <libgen.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -102,19 +101,19 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
102 | } | 101 | } |
103 | 102 | ||
104 | char *conf_path = dirname(conf); | 103 | char *conf_path = dirname(conf); |
105 | char *rel_path = src; | 104 | char *real_src = malloc(strlen(conf_path) + strlen(src) + 2); |
106 | src = malloc(strlen(conf_path) + strlen(src) + 2); | 105 | if (!real_src) { |
107 | if (!src) { | 106 | free(src); |
108 | free(rel_path); | ||
109 | free(conf); | 107 | free(conf); |
110 | sway_log(SWAY_ERROR, "Unable to allocate memory"); | 108 | sway_log(SWAY_ERROR, "Unable to allocate memory"); |
111 | return cmd_results_new(CMD_FAILURE, | 109 | return cmd_results_new(CMD_FAILURE, |
112 | "Unable to allocate resources"); | 110 | "Unable to allocate resources"); |
113 | } | 111 | } |
114 | 112 | ||
115 | sprintf(src, "%s/%s", conf_path, rel_path); | 113 | snprintf(real_src, strlen(conf_path) + strlen(src) + 2, "%s/%s", conf_path, src); |
116 | free(rel_path); | 114 | free(src); |
117 | free(conf); | 115 | free(conf); |
116 | src = real_src; | ||
118 | } | 117 | } |
119 | 118 | ||
120 | bool can_access = access(src, F_OK) != -1; | 119 | bool can_access = access(src, F_OK) != -1; |
@@ -123,7 +122,10 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
123 | src); | 122 | src); |
124 | config_add_swaynag_warning("Unable to access background file '%s'", | 123 | config_add_swaynag_warning("Unable to access background file '%s'", |
125 | src); | 124 | src); |
125 | struct cmd_results *result = cmd_results_new(CMD_FAILURE, | ||
126 | "unable to access background file '%s'", src); | ||
126 | free(src); | 127 | free(src); |
128 | return result; | ||
127 | } else { | 129 | } else { |
128 | output->background = src; | 130 | output->background = src; |
129 | output->background_option = strdup(mode); | 131 | output->background_option = strdup(mode); |
diff --git a/sway/commands/output/dpms.c b/sway/commands/output/dpms.c index 9d75a80e..c7adbd58 100644 --- a/sway/commands/output/dpms.c +++ b/sway/commands/output/dpms.c | |||
@@ -1,22 +1,8 @@ | |||
1 | #include "log.h" | ||
1 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
2 | #include "sway/config.h" | ||
3 | #include "util.h" | ||
4 | 3 | ||
5 | struct cmd_results *output_cmd_dpms(int argc, char **argv) { | 4 | struct cmd_results *output_cmd_dpms(int argc, char **argv) { |
6 | if (!config->handler_context.output_config) { | 5 | sway_log(SWAY_INFO, "The \"output dpms\" command is deprecated, " |
7 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | 6 | "use \"output power\" instead"); |
8 | } | 7 | return output_cmd_power(argc, argv); |
9 | if (!argc) { | ||
10 | return cmd_results_new(CMD_INVALID, "Missing dpms argument."); | ||
11 | } | ||
12 | |||
13 | if (parse_boolean(argv[0], true)) { | ||
14 | config->handler_context.output_config->dpms_state = DPMS_ON; | ||
15 | } else { | ||
16 | config->handler_context.output_config->dpms_state = DPMS_OFF; | ||
17 | } | ||
18 | |||
19 | config->handler_context.leftovers.argc = argc - 1; | ||
20 | config->handler_context.leftovers.argv = argv + 1; | ||
21 | return NULL; | ||
22 | } | 8 | } |
diff --git a/sway/commands/output/mode.c b/sway/commands/output/mode.c index 5b710713..019d625a 100644 --- a/sway/commands/output/mode.c +++ b/sway/commands/output/mode.c | |||
@@ -20,6 +20,9 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { | |||
20 | output->custom_mode = 0; | 20 | output->custom_mode = 0; |
21 | } | 21 | } |
22 | 22 | ||
23 | // Reset custom modeline, if any | ||
24 | output->drm_mode.type = 0; | ||
25 | |||
23 | char *end; | 26 | char *end; |
24 | output->width = strtol(*argv, &end, 10); | 27 | output->width = strtol(*argv, &end, 10); |
25 | if (*end) { | 28 | if (*end) { |
@@ -58,3 +61,58 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { | |||
58 | return NULL; | 61 | return NULL; |
59 | } | 62 | } |
60 | 63 | ||
64 | static bool parse_modeline(char **argv, drmModeModeInfo *mode) { | ||
65 | mode->type = DRM_MODE_TYPE_USERDEF; | ||
66 | mode->clock = strtof(argv[0], NULL) * 1000; | ||
67 | mode->hdisplay = strtol(argv[1], NULL, 10); | ||
68 | mode->hsync_start = strtol(argv[2], NULL, 10); | ||
69 | mode->hsync_end = strtol(argv[3], NULL, 10); | ||
70 | mode->htotal = strtol(argv[4], NULL, 10); | ||
71 | mode->vdisplay = strtol(argv[5], NULL, 10); | ||
72 | mode->vsync_start = strtol(argv[6], NULL, 10); | ||
73 | mode->vsync_end = strtol(argv[7], NULL, 10); | ||
74 | mode->vtotal = strtol(argv[8], NULL, 10); | ||
75 | |||
76 | mode->vrefresh = mode->clock * 1000.0 * 1000.0 | ||
77 | / mode->htotal / mode->vtotal; | ||
78 | if (strcasecmp(argv[9], "+hsync") == 0) { | ||
79 | mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
80 | } else if (strcasecmp(argv[9], "-hsync") == 0) { | ||
81 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
82 | } else { | ||
83 | return false; | ||
84 | } | ||
85 | |||
86 | if (strcasecmp(argv[10], "+vsync") == 0) { | ||
87 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
88 | } else if (strcasecmp(argv[10], "-vsync") == 0) { | ||
89 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
90 | } else { | ||
91 | return false; | ||
92 | } | ||
93 | |||
94 | snprintf(mode->name, sizeof(mode->name), "%dx%d@%d", | ||
95 | mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000); | ||
96 | |||
97 | return true; | ||
98 | } | ||
99 | |||
100 | struct cmd_results *output_cmd_modeline(int argc, char **argv) { | ||
101 | if (!config->handler_context.output_config) { | ||
102 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
103 | } | ||
104 | if (!argc) { | ||
105 | return cmd_results_new(CMD_INVALID, "Missing modeline argument."); | ||
106 | } | ||
107 | |||
108 | struct output_config *output = config->handler_context.output_config; | ||
109 | |||
110 | if (argc != 11 || !parse_modeline(argv, &output->drm_mode)) { | ||
111 | return cmd_results_new(CMD_INVALID, "Invalid modeline"); | ||
112 | } | ||
113 | |||
114 | config->handler_context.leftovers.argc = argc - 12; | ||
115 | config->handler_context.leftovers.argv = argv + 12; | ||
116 | return NULL; | ||
117 | } | ||
118 | |||
diff --git a/sway/commands/output/power.c b/sway/commands/output/power.c new file mode 100644 index 00000000..e6ae2852 --- /dev/null +++ b/sway/commands/output/power.c | |||
@@ -0,0 +1,43 @@ | |||
1 | #include <strings.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/output.h" | ||
5 | #include "util.h" | ||
6 | |||
7 | struct cmd_results *output_cmd_power(int argc, char **argv) { | ||
8 | if (!config->handler_context.output_config) { | ||
9 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
10 | } | ||
11 | if (argc == 0) { | ||
12 | return cmd_results_new(CMD_INVALID, "Missing power argument"); | ||
13 | } | ||
14 | |||
15 | bool current = true; | ||
16 | if (strcasecmp(argv[0], "toggle") == 0) { | ||
17 | const char *oc_name = config->handler_context.output_config->name; | ||
18 | if (strcmp(oc_name, "*") == 0) { | ||
19 | return cmd_results_new(CMD_INVALID, | ||
20 | "Cannot apply toggle to all outputs"); | ||
21 | } | ||
22 | |||
23 | struct sway_output *sway_output = all_output_by_name_or_id(oc_name); | ||
24 | if (!sway_output || !sway_output->wlr_output) { | ||
25 | return cmd_results_new(CMD_FAILURE, | ||
26 | "Cannot apply toggle to unknown output %s", oc_name); | ||
27 | } | ||
28 | |||
29 | if (sway_output->enabled && !sway_output->wlr_output->enabled) { | ||
30 | current = false; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | if (parse_boolean(argv[0], current)) { | ||
35 | config->handler_context.output_config->power = 1; | ||
36 | } else { | ||
37 | config->handler_context.output_config->power = 0; | ||
38 | } | ||
39 | |||
40 | config->handler_context.leftovers.argc = argc - 1; | ||
41 | config->handler_context.leftovers.argv = argv + 1; | ||
42 | return NULL; | ||
43 | } | ||
diff --git a/sway/commands/output/render_bit_depth.c b/sway/commands/output/render_bit_depth.c new file mode 100644 index 00000000..c419321e --- /dev/null +++ b/sway/commands/output/render_bit_depth.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <drm_fourcc.h> | ||
2 | #include <strings.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | |||
6 | struct cmd_results *output_cmd_render_bit_depth(int argc, char **argv) { | ||
7 | if (!config->handler_context.output_config) { | ||
8 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
9 | } | ||
10 | if (!argc) { | ||
11 | return cmd_results_new(CMD_INVALID, "Missing bit depth argument."); | ||
12 | } | ||
13 | |||
14 | if (strcmp(*argv, "8") == 0) { | ||
15 | config->handler_context.output_config->render_bit_depth = | ||
16 | RENDER_BIT_DEPTH_8; | ||
17 | } else if (strcmp(*argv, "10") == 0) { | ||
18 | config->handler_context.output_config->render_bit_depth = | ||
19 | RENDER_BIT_DEPTH_10; | ||
20 | } else { | ||
21 | return cmd_results_new(CMD_INVALID, | ||
22 | "Invalid bit depth. Must be a value in (8|10)."); | ||
23 | } | ||
24 | |||
25 | config->handler_context.leftovers.argc = argc - 1; | ||
26 | config->handler_context.leftovers.argv = argv + 1; | ||
27 | return NULL; | ||
28 | } | ||
29 | |||
diff --git a/sway/commands/output/toggle.c b/sway/commands/output/toggle.c index 6342d526..c6b72845 100644 --- a/sway/commands/output/toggle.c +++ b/sway/commands/output/toggle.c | |||
@@ -29,7 +29,7 @@ struct cmd_results *output_cmd_toggle(int argc, char **argv) { | |||
29 | config->handler_context.output_config->enabled = 1; | 29 | config->handler_context.output_config->enabled = 1; |
30 | } | 30 | } |
31 | 31 | ||
32 | free(oc); | 32 | free_output_config(oc); |
33 | config->handler_context.leftovers.argc = argc; | 33 | config->handler_context.leftovers.argc = argc; |
34 | config->handler_context.leftovers.argv = argv; | 34 | config->handler_context.leftovers.argv = argv; |
35 | return NULL; | 35 | return NULL; |
diff --git a/sway/commands/output/transform.c b/sway/commands/output/transform.c index f4fcc8c9..8db71bb3 100644 --- a/sway/commands/output/transform.c +++ b/sway/commands/output/transform.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <string.h> | 1 | #include <string.h> |
2 | #include <wlr/util/transform.h> | ||
2 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
3 | #include "sway/config.h" | 4 | #include "sway/config.h" |
4 | #include "log.h" | 5 | #include "log.h" |
diff --git a/sway/commands/output/unplug.c b/sway/commands/output/unplug.c new file mode 100644 index 00000000..dfef626f --- /dev/null +++ b/sway/commands/output/unplug.c | |||
@@ -0,0 +1,54 @@ | |||
1 | #include <strings.h> | ||
2 | #include <wlr/config.h> | ||
3 | #include <wlr/backend/headless.h> | ||
4 | #include <wlr/backend/wayland.h> | ||
5 | #if WLR_HAS_X11_BACKEND | ||
6 | #include <wlr/backend/x11.h> | ||
7 | #endif | ||
8 | #include "sway/commands.h" | ||
9 | #include "sway/config.h" | ||
10 | #include "sway/output.h" | ||
11 | |||
12 | static bool is_backend_allowed(struct wlr_backend *backend) { | ||
13 | if (wlr_backend_is_headless(backend)) { | ||
14 | return true; | ||
15 | } | ||
16 | if (wlr_backend_is_wl(backend)) { | ||
17 | return true; | ||
18 | } | ||
19 | #if WLR_HAS_X11_BACKEND | ||
20 | if (wlr_backend_is_x11(backend)) { | ||
21 | return true; | ||
22 | } | ||
23 | #endif | ||
24 | return false; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * This command is intended for developer use only. | ||
29 | */ | ||
30 | struct cmd_results *output_cmd_unplug(int argc, char **argv) { | ||
31 | if (!config->handler_context.output_config) { | ||
32 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
33 | } | ||
34 | |||
35 | const char *oc_name = config->handler_context.output_config->name; | ||
36 | if (strcmp(oc_name, "*") == 0) { | ||
37 | return cmd_results_new(CMD_INVALID, "Won't unplug all outputs"); | ||
38 | } | ||
39 | |||
40 | struct sway_output *sway_output = all_output_by_name_or_id(oc_name); | ||
41 | if (!sway_output) { | ||
42 | return cmd_results_new(CMD_INVALID, | ||
43 | "Cannot unplug unknown output %s", oc_name); | ||
44 | } | ||
45 | |||
46 | if (!is_backend_allowed(sway_output->wlr_output->backend)) { | ||
47 | return cmd_results_new(CMD_INVALID, | ||
48 | "Can only unplug outputs with headless, wayland or x11 backend"); | ||
49 | } | ||
50 | |||
51 | wlr_output_destroy(sway_output->wlr_output); | ||
52 | |||
53 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
54 | } | ||
diff --git a/sway/commands/primary_selection.c b/sway/commands/primary_selection.c new file mode 100644 index 00000000..9e2689c2 --- /dev/null +++ b/sway/commands/primary_selection.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <string.h> | ||
2 | #include <strings.h> | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/commands.h" | ||
5 | #include "util.h" | ||
6 | |||
7 | struct cmd_results *cmd_primary_selection(int argc, char **argv) { | ||
8 | struct cmd_results *error = NULL; | ||
9 | if ((error = checkarg(argc, "primary_selection", EXPECTED_EQUAL_TO, 1))) { | ||
10 | return error; | ||
11 | } | ||
12 | |||
13 | bool primary_selection = parse_boolean(argv[0], true); | ||
14 | |||
15 | // config->primary_selection is reset to the previous value on reload in | ||
16 | // load_main_config() | ||
17 | if (config->reloading && config->primary_selection != primary_selection) { | ||
18 | return cmd_results_new(CMD_FAILURE, | ||
19 | "primary_selection can only be enabled/disabled at launch"); | ||
20 | } | ||
21 | |||
22 | config->primary_selection = primary_selection; | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
25 | } | ||
diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 3c994d54..6c0aac26 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -9,9 +8,8 @@ | |||
9 | #include "list.h" | 8 | #include "list.h" |
10 | #include "log.h" | 9 | #include "log.h" |
11 | 10 | ||
12 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 11 | static void title_bar_update_iterator(struct sway_container *con, void *data) { |
13 | container_update_marks_textures(con); | 12 | container_update_title_bar(con); |
14 | container_update_title_textures(con); | ||
15 | } | 13 | } |
16 | 14 | ||
17 | static void do_reload(void *data) { | 15 | static void do_reload(void *data) { |
@@ -48,8 +46,7 @@ static void do_reload(void *data) { | |||
48 | } | 46 | } |
49 | list_free_items_and_destroy(bar_ids); | 47 | list_free_items_and_destroy(bar_ids); |
50 | 48 | ||
51 | config_update_font_height(true); | 49 | root_for_each_container(title_bar_update_iterator, NULL); |
52 | root_for_each_container(rebuild_textures_iterator, NULL); | ||
53 | 50 | ||
54 | arrange_root(); | 51 | arrange_root(); |
55 | } | 52 | } |
diff --git a/sway/commands/rename.c b/sway/commands/rename.c index 3b855fdf..0d36cc21 100644 --- a/sway/commands/rename.c +++ b/sway/commands/rename.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "sway/config.h" | 7 | #include "sway/config.h" |
8 | #include "sway/ipc-server.h" | 8 | #include "sway/ipc-server.h" |
9 | #include "sway/output.h" | 9 | #include "sway/output.h" |
10 | #include "sway/desktop/launcher.h" | ||
10 | #include "sway/tree/container.h" | 11 | #include "sway/tree/container.h" |
11 | #include "sway/tree/workspace.h" | 12 | #include "sway/tree/workspace.h" |
12 | #include "sway/tree/root.h" | 13 | #include "sway/tree/root.h" |
@@ -25,7 +26,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) { | |||
25 | "Can't run this command while there's no outputs connected."); | 26 | "Can't run this command while there's no outputs connected."); |
26 | } | 27 | } |
27 | if (strcasecmp(argv[0], "workspace") != 0) { | 28 | if (strcasecmp(argv[0], "workspace") != 0) { |
28 | return cmd_results_new(CMD_INVALID, expected_syntax); | 29 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
29 | } | 30 | } |
30 | 31 | ||
31 | int argn = 1; | 32 | int argn = 1; |
@@ -64,7 +65,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) { | |||
64 | ++argn; // move past "to" | 65 | ++argn; // move past "to" |
65 | 66 | ||
66 | if (argn >= argc) { | 67 | if (argn >= argc) { |
67 | return cmd_results_new(CMD_INVALID, expected_syntax); | 68 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
68 | } | 69 | } |
69 | 70 | ||
70 | char *new_name = join_args(argv + argn, argc - argn); | 71 | char *new_name = join_args(argv + argn, argc - argn); |
@@ -91,8 +92,6 @@ struct cmd_results *cmd_rename(int argc, char **argv) { | |||
91 | 92 | ||
92 | sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); | 93 | sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); |
93 | 94 | ||
94 | root_rename_pid_workspaces(workspace->name, new_name); | ||
95 | |||
96 | free(workspace->name); | 95 | free(workspace->name); |
97 | workspace->name = new_name; | 96 | workspace->name = new_name; |
98 | 97 | ||
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index ca36e858..32b746ea 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -57,7 +57,7 @@ struct sway_container *container_find_resize_parent(struct sway_container *con, | |||
57 | (allow_last || index < siblings->length - 1)) { | 57 | (allow_last || index < siblings->length - 1)) { |
58 | return con; | 58 | return con; |
59 | } | 59 | } |
60 | con = con->parent; | 60 | con = con->pending.parent; |
61 | } | 61 | } |
62 | 62 | ||
63 | return NULL; | 63 | return NULL; |
@@ -75,6 +75,10 @@ void container_resize_tiled(struct sway_container *con, | |||
75 | return; | 75 | return; |
76 | } | 76 | } |
77 | 77 | ||
78 | if (container_is_scratchpad_hidden_or_child(con)) { | ||
79 | return; | ||
80 | } | ||
81 | |||
78 | // For HORIZONTAL or VERTICAL, we are growing in two directions so select | 82 | // For HORIZONTAL or VERTICAL, we are growing in two directions so select |
79 | // both adjacent siblings. For RIGHT or DOWN, just select the next sibling. | 83 | // both adjacent siblings. For RIGHT or DOWN, just select the next sibling. |
80 | // For LEFT or UP, convert it to a RIGHT or DOWN resize and reassign con to | 84 | // For LEFT or UP, convert it to a RIGHT or DOWN resize and reassign con to |
@@ -115,13 +119,13 @@ void container_resize_tiled(struct sway_container *con, | |||
115 | int sibling_amount = prev ? ceil((double)amount / 2.0) : amount; | 119 | int sibling_amount = prev ? ceil((double)amount / 2.0) : amount; |
116 | 120 | ||
117 | if (is_horizontal(axis)) { | 121 | if (is_horizontal(axis)) { |
118 | if (con->width + amount < MIN_SANE_W) { | 122 | if (con->pending.width + amount < MIN_SANE_W) { |
119 | return; | 123 | return; |
120 | } | 124 | } |
121 | if (next->width - sibling_amount < MIN_SANE_W) { | 125 | if (next->pending.width - sibling_amount < MIN_SANE_W) { |
122 | return; | 126 | return; |
123 | } | 127 | } |
124 | if (prev && prev->width - sibling_amount < MIN_SANE_W) { | 128 | if (prev && prev->pending.width - sibling_amount < MIN_SANE_W) { |
125 | return; | 129 | return; |
126 | } | 130 | } |
127 | if (con->child_total_width <= 0) { | 131 | if (con->child_total_width <= 0) { |
@@ -133,7 +137,7 @@ void container_resize_tiled(struct sway_container *con, | |||
133 | list_t *siblings = container_get_siblings(con); | 137 | list_t *siblings = container_get_siblings(con); |
134 | for (int i = 0; i < siblings->length; ++i) { | 138 | for (int i = 0; i < siblings->length; ++i) { |
135 | struct sway_container *con = siblings->items[i]; | 139 | struct sway_container *con = siblings->items[i]; |
136 | con->width_fraction = con->width / con->child_total_width; | 140 | con->width_fraction = con->pending.width / con->child_total_width; |
137 | } | 141 | } |
138 | 142 | ||
139 | double amount_fraction = (double)amount / con->child_total_width; | 143 | double amount_fraction = (double)amount / con->child_total_width; |
@@ -146,13 +150,13 @@ void container_resize_tiled(struct sway_container *con, | |||
146 | prev->width_fraction -= sibling_amount_fraction; | 150 | prev->width_fraction -= sibling_amount_fraction; |
147 | } | 151 | } |
148 | } else { | 152 | } else { |
149 | if (con->height + amount < MIN_SANE_H) { | 153 | if (con->pending.height + amount < MIN_SANE_H) { |
150 | return; | 154 | return; |
151 | } | 155 | } |
152 | if (next->height - sibling_amount < MIN_SANE_H) { | 156 | if (next->pending.height - sibling_amount < MIN_SANE_H) { |
153 | return; | 157 | return; |
154 | } | 158 | } |
155 | if (prev && prev->height - sibling_amount < MIN_SANE_H) { | 159 | if (prev && prev->pending.height - sibling_amount < MIN_SANE_H) { |
156 | return; | 160 | return; |
157 | } | 161 | } |
158 | if (con->child_total_height <= 0) { | 162 | if (con->child_total_height <= 0) { |
@@ -164,7 +168,7 @@ void container_resize_tiled(struct sway_container *con, | |||
164 | list_t *siblings = container_get_siblings(con); | 168 | list_t *siblings = container_get_siblings(con); |
165 | for (int i = 0; i < siblings->length; ++i) { | 169 | for (int i = 0; i < siblings->length; ++i) { |
166 | struct sway_container *con = siblings->items[i]; | 170 | struct sway_container *con = siblings->items[i]; |
167 | con->height_fraction = con->height / con->child_total_height; | 171 | con->height_fraction = con->pending.height / con->child_total_height; |
168 | } | 172 | } |
169 | 173 | ||
170 | double amount_fraction = (double)amount / con->child_total_height; | 174 | double amount_fraction = (double)amount / con->child_total_height; |
@@ -178,10 +182,10 @@ void container_resize_tiled(struct sway_container *con, | |||
178 | } | 182 | } |
179 | } | 183 | } |
180 | 184 | ||
181 | if (con->parent) { | 185 | if (con->pending.parent) { |
182 | arrange_container(con->parent); | 186 | arrange_container(con->pending.parent); |
183 | } else { | 187 | } else { |
184 | arrange_workspace(con->workspace); | 188 | arrange_workspace(con->pending.workspace); |
185 | } | 189 | } |
186 | } | 190 | } |
187 | 191 | ||
@@ -203,15 +207,15 @@ static struct cmd_results *resize_adjust_floating(uint32_t axis, | |||
203 | int min_width, max_width, min_height, max_height; | 207 | int min_width, max_width, min_height, max_height; |
204 | floating_calculate_constraints(&min_width, &max_width, | 208 | floating_calculate_constraints(&min_width, &max_width, |
205 | &min_height, &max_height); | 209 | &min_height, &max_height); |
206 | if (con->width + grow_width < min_width) { | 210 | if (con->pending.width + grow_width < min_width) { |
207 | grow_width = min_width - con->width; | 211 | grow_width = min_width - con->pending.width; |
208 | } else if (con->width + grow_width > max_width) { | 212 | } else if (con->pending.width + grow_width > max_width) { |
209 | grow_width = max_width - con->width; | 213 | grow_width = max_width - con->pending.width; |
210 | } | 214 | } |
211 | if (con->height + grow_height < min_height) { | 215 | if (con->pending.height + grow_height < min_height) { |
212 | grow_height = min_height - con->height; | 216 | grow_height = min_height - con->pending.height; |
213 | } else if (con->height + grow_height > max_height) { | 217 | } else if (con->pending.height + grow_height > max_height) { |
214 | grow_height = max_height - con->height; | 218 | grow_height = max_height - con->pending.height; |
215 | } | 219 | } |
216 | int grow_x = 0, grow_y = 0; | 220 | int grow_x = 0, grow_y = 0; |
217 | 221 | ||
@@ -227,15 +231,15 @@ static struct cmd_results *resize_adjust_floating(uint32_t axis, | |||
227 | if (grow_width == 0 && grow_height == 0) { | 231 | if (grow_width == 0 && grow_height == 0) { |
228 | return cmd_results_new(CMD_INVALID, "Cannot resize any further"); | 232 | return cmd_results_new(CMD_INVALID, "Cannot resize any further"); |
229 | } | 233 | } |
230 | con->x += grow_x; | 234 | con->pending.x += grow_x; |
231 | con->y += grow_y; | 235 | con->pending.y += grow_y; |
232 | con->width += grow_width; | 236 | con->pending.width += grow_width; |
233 | con->height += grow_height; | 237 | con->pending.height += grow_height; |
234 | 238 | ||
235 | con->content_x += grow_x; | 239 | con->pending.content_x += grow_x; |
236 | con->content_y += grow_y; | 240 | con->pending.content_y += grow_y; |
237 | con->content_width += grow_width; | 241 | con->pending.content_width += grow_width; |
238 | con->content_height += grow_height; | 242 | con->pending.content_height += grow_height; |
239 | 243 | ||
240 | arrange_container(con); | 244 | arrange_container(con); |
241 | 245 | ||
@@ -249,16 +253,35 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis, | |||
249 | struct movement_amount *amount) { | 253 | struct movement_amount *amount) { |
250 | struct sway_container *current = config->handler_context.container; | 254 | struct sway_container *current = config->handler_context.container; |
251 | 255 | ||
256 | if (container_is_scratchpad_hidden_or_child(current)) { | ||
257 | return cmd_results_new(CMD_FAILURE, "Cannot resize a hidden scratchpad container"); | ||
258 | } | ||
259 | |||
252 | if (amount->unit == MOVEMENT_UNIT_DEFAULT) { | 260 | if (amount->unit == MOVEMENT_UNIT_DEFAULT) { |
253 | amount->unit = MOVEMENT_UNIT_PPT; | 261 | amount->unit = MOVEMENT_UNIT_PPT; |
254 | } | 262 | } |
255 | if (amount->unit == MOVEMENT_UNIT_PPT) { | 263 | if (amount->unit == MOVEMENT_UNIT_PPT) { |
264 | struct sway_container *parent = current->pending.parent; | ||
256 | float pct = amount->amount / 100.0f; | 265 | float pct = amount->amount / 100.0f; |
257 | 266 | ||
258 | if (is_horizontal(axis)) { | 267 | if (is_horizontal(axis)) { |
259 | amount->amount = (float)current->width * pct; | 268 | while (parent && parent->pending.layout != L_HORIZ) { |
269 | parent = parent->pending.parent; | ||
270 | } | ||
271 | if (parent) { | ||
272 | amount->amount = (float)parent->pending.width * pct; | ||
273 | } else { | ||
274 | amount->amount = (float)current->pending.workspace->width * pct; | ||
275 | } | ||
260 | } else { | 276 | } else { |
261 | amount->amount = (float)current->height * pct; | 277 | while (parent && parent->pending.layout != L_VERT) { |
278 | parent = parent->pending.parent; | ||
279 | } | ||
280 | if (parent) { | ||
281 | amount->amount = (float)parent->pending.height * pct; | ||
282 | } else { | ||
283 | amount->amount = (float)current->pending.workspace->height * pct; | ||
284 | } | ||
262 | } | 285 | } |
263 | } | 286 | } |
264 | 287 | ||
@@ -277,24 +300,29 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis, | |||
277 | */ | 300 | */ |
278 | static struct cmd_results *resize_set_tiled(struct sway_container *con, | 301 | static struct cmd_results *resize_set_tiled(struct sway_container *con, |
279 | struct movement_amount *width, struct movement_amount *height) { | 302 | struct movement_amount *width, struct movement_amount *height) { |
303 | |||
304 | if (container_is_scratchpad_hidden_or_child(con)) { | ||
305 | return cmd_results_new(CMD_FAILURE, "Cannot resize a hidden scratchpad container"); | ||
306 | } | ||
307 | |||
280 | if (width->amount) { | 308 | if (width->amount) { |
281 | if (width->unit == MOVEMENT_UNIT_PPT || | 309 | if (width->unit == MOVEMENT_UNIT_PPT || |
282 | width->unit == MOVEMENT_UNIT_DEFAULT) { | 310 | width->unit == MOVEMENT_UNIT_DEFAULT) { |
283 | // Convert to px | 311 | // Convert to px |
284 | struct sway_container *parent = con->parent; | 312 | struct sway_container *parent = con->pending.parent; |
285 | while (parent && parent->layout != L_HORIZ) { | 313 | while (parent && parent->pending.layout != L_HORIZ) { |
286 | parent = parent->parent; | 314 | parent = parent->pending.parent; |
287 | } | 315 | } |
288 | if (parent) { | 316 | if (parent) { |
289 | width->amount = parent->width * width->amount / 100; | 317 | width->amount = parent->pending.width * width->amount / 100; |
290 | } else { | 318 | } else { |
291 | width->amount = con->workspace->width * width->amount / 100; | 319 | width->amount = con->pending.workspace->width * width->amount / 100; |
292 | } | 320 | } |
293 | width->unit = MOVEMENT_UNIT_PX; | 321 | width->unit = MOVEMENT_UNIT_PX; |
294 | } | 322 | } |
295 | if (width->unit == MOVEMENT_UNIT_PX) { | 323 | if (width->unit == MOVEMENT_UNIT_PX) { |
296 | container_resize_tiled(con, AXIS_HORIZONTAL, | 324 | container_resize_tiled(con, AXIS_HORIZONTAL, |
297 | width->amount - con->width); | 325 | width->amount - con->pending.width); |
298 | } | 326 | } |
299 | } | 327 | } |
300 | 328 | ||
@@ -302,20 +330,20 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con, | |||
302 | if (height->unit == MOVEMENT_UNIT_PPT || | 330 | if (height->unit == MOVEMENT_UNIT_PPT || |
303 | height->unit == MOVEMENT_UNIT_DEFAULT) { | 331 | height->unit == MOVEMENT_UNIT_DEFAULT) { |
304 | // Convert to px | 332 | // Convert to px |
305 | struct sway_container *parent = con->parent; | 333 | struct sway_container *parent = con->pending.parent; |
306 | while (parent && parent->layout != L_VERT) { | 334 | while (parent && parent->pending.layout != L_VERT) { |
307 | parent = parent->parent; | 335 | parent = parent->pending.parent; |
308 | } | 336 | } |
309 | if (parent) { | 337 | if (parent) { |
310 | height->amount = parent->height * height->amount / 100; | 338 | height->amount = parent->pending.height * height->amount / 100; |
311 | } else { | 339 | } else { |
312 | height->amount = con->workspace->height * height->amount / 100; | 340 | height->amount = con->pending.workspace->height * height->amount / 100; |
313 | } | 341 | } |
314 | height->unit = MOVEMENT_UNIT_PX; | 342 | height->unit = MOVEMENT_UNIT_PX; |
315 | } | 343 | } |
316 | if (height->unit == MOVEMENT_UNIT_PX) { | 344 | if (height->unit == MOVEMENT_UNIT_PX) { |
317 | container_resize_tiled(con, AXIS_VERTICAL, | 345 | container_resize_tiled(con, AXIS_VERTICAL, |
318 | height->amount - con->height); | 346 | height->amount - con->pending.height); |
319 | } | 347 | } |
320 | } | 348 | } |
321 | 349 | ||
@@ -339,15 +367,15 @@ static struct cmd_results *resize_set_floating(struct sway_container *con, | |||
339 | "Cannot resize a hidden scratchpad container by ppt"); | 367 | "Cannot resize a hidden scratchpad container by ppt"); |
340 | } | 368 | } |
341 | // Convert to px | 369 | // Convert to px |
342 | width->amount = con->workspace->width * width->amount / 100; | 370 | width->amount = con->pending.workspace->width * width->amount / 100; |
343 | width->unit = MOVEMENT_UNIT_PX; | 371 | width->unit = MOVEMENT_UNIT_PX; |
344 | // Falls through | 372 | // Falls through |
345 | case MOVEMENT_UNIT_PX: | 373 | case MOVEMENT_UNIT_PX: |
346 | case MOVEMENT_UNIT_DEFAULT: | 374 | case MOVEMENT_UNIT_DEFAULT: |
347 | width->amount = fmax(min_width, fmin(width->amount, max_width)); | 375 | width->amount = fmax(min_width, fmin(width->amount, max_width)); |
348 | grow_width = width->amount - con->width; | 376 | grow_width = width->amount - con->pending.width; |
349 | con->x -= grow_width / 2; | 377 | con->pending.x -= grow_width / 2; |
350 | con->width = width->amount; | 378 | con->pending.width = width->amount; |
351 | break; | 379 | break; |
352 | case MOVEMENT_UNIT_INVALID: | 380 | case MOVEMENT_UNIT_INVALID: |
353 | sway_assert(false, "invalid width unit"); | 381 | sway_assert(false, "invalid width unit"); |
@@ -363,15 +391,15 @@ static struct cmd_results *resize_set_floating(struct sway_container *con, | |||
363 | "Cannot resize a hidden scratchpad container by ppt"); | 391 | "Cannot resize a hidden scratchpad container by ppt"); |
364 | } | 392 | } |
365 | // Convert to px | 393 | // Convert to px |
366 | height->amount = con->workspace->height * height->amount / 100; | 394 | height->amount = con->pending.workspace->height * height->amount / 100; |
367 | height->unit = MOVEMENT_UNIT_PX; | 395 | height->unit = MOVEMENT_UNIT_PX; |
368 | // Falls through | 396 | // Falls through |
369 | case MOVEMENT_UNIT_PX: | 397 | case MOVEMENT_UNIT_PX: |
370 | case MOVEMENT_UNIT_DEFAULT: | 398 | case MOVEMENT_UNIT_DEFAULT: |
371 | height->amount = fmax(min_height, fmin(height->amount, max_height)); | 399 | height->amount = fmax(min_height, fmin(height->amount, max_height)); |
372 | grow_height = height->amount - con->height; | 400 | grow_height = height->amount - con->pending.height; |
373 | con->y -= grow_height / 2; | 401 | con->pending.y -= grow_height / 2; |
374 | con->height = height->amount; | 402 | con->pending.height = height->amount; |
375 | break; | 403 | break; |
376 | case MOVEMENT_UNIT_INVALID: | 404 | case MOVEMENT_UNIT_INVALID: |
377 | sway_assert(false, "invalid height unit"); | 405 | sway_assert(false, "invalid height unit"); |
@@ -379,10 +407,10 @@ static struct cmd_results *resize_set_floating(struct sway_container *con, | |||
379 | } | 407 | } |
380 | } | 408 | } |
381 | 409 | ||
382 | con->content_x -= grow_width / 2; | 410 | con->pending.content_x -= grow_width / 2; |
383 | con->content_y -= grow_height / 2; | 411 | con->pending.content_y -= grow_height / 2; |
384 | con->content_width += grow_width; | 412 | con->pending.content_width += grow_width; |
385 | con->content_height += grow_height; | 413 | con->pending.content_height += grow_height; |
386 | 414 | ||
387 | arrange_container(con); | 415 | arrange_container(con); |
388 | 416 | ||
@@ -415,7 +443,7 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) { | |||
415 | argc -= num_consumed_args; | 443 | argc -= num_consumed_args; |
416 | argv += num_consumed_args; | 444 | argv += num_consumed_args; |
417 | if (width.unit == MOVEMENT_UNIT_INVALID) { | 445 | if (width.unit == MOVEMENT_UNIT_INVALID) { |
418 | return cmd_results_new(CMD_INVALID, usage); | 446 | return cmd_results_new(CMD_INVALID, "%s", usage); |
419 | } | 447 | } |
420 | } | 448 | } |
421 | 449 | ||
@@ -427,20 +455,20 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) { | |||
427 | } | 455 | } |
428 | int num_consumed_args = parse_movement_amount(argc, argv, &height); | 456 | int num_consumed_args = parse_movement_amount(argc, argv, &height); |
429 | if (argc > num_consumed_args) { | 457 | if (argc > num_consumed_args) { |
430 | return cmd_results_new(CMD_INVALID, usage); | 458 | return cmd_results_new(CMD_INVALID, "%s", usage); |
431 | } | 459 | } |
432 | if (width.unit == MOVEMENT_UNIT_INVALID) { | 460 | if (width.unit == MOVEMENT_UNIT_INVALID) { |
433 | return cmd_results_new(CMD_INVALID, usage); | 461 | return cmd_results_new(CMD_INVALID, "%s", usage); |
434 | } | 462 | } |
435 | } | 463 | } |
436 | 464 | ||
437 | // If 0, don't resize that dimension | 465 | // If 0, don't resize that dimension |
438 | struct sway_container *con = config->handler_context.container; | 466 | struct sway_container *con = config->handler_context.container; |
439 | if (width.amount <= 0) { | 467 | if (width.amount <= 0) { |
440 | width.amount = con->width; | 468 | width.amount = con->pending.width; |
441 | } | 469 | } |
442 | if (height.amount <= 0) { | 470 | if (height.amount <= 0) { |
443 | height.amount = con->height; | 471 | height.amount = con->pending.height; |
444 | } | 472 | } |
445 | 473 | ||
446 | if (container_is_floating(con)) { | 474 | if (container_is_floating(con)) { |
@@ -462,7 +490,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | |||
462 | "[<amount> px|ppt [or <amount> px|ppt]]'"; | 490 | "[<amount> px|ppt [or <amount> px|ppt]]'"; |
463 | uint32_t axis = parse_resize_axis(*argv); | 491 | uint32_t axis = parse_resize_axis(*argv); |
464 | if (axis == WLR_EDGE_NONE) { | 492 | if (axis == WLR_EDGE_NONE) { |
465 | return cmd_results_new(CMD_INVALID, usage); | 493 | return cmd_results_new(CMD_INVALID, "%s", usage); |
466 | } | 494 | } |
467 | --argc; ++argv; | 495 | --argc; ++argv; |
468 | 496 | ||
@@ -473,7 +501,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | |||
473 | argc -= num_consumed_args; | 501 | argc -= num_consumed_args; |
474 | argv += num_consumed_args; | 502 | argv += num_consumed_args; |
475 | if (first_amount.unit == MOVEMENT_UNIT_INVALID) { | 503 | if (first_amount.unit == MOVEMENT_UNIT_INVALID) { |
476 | return cmd_results_new(CMD_INVALID, usage); | 504 | return cmd_results_new(CMD_INVALID, "%s", usage); |
477 | } | 505 | } |
478 | } else { | 506 | } else { |
479 | first_amount.amount = 10; | 507 | first_amount.amount = 10; |
@@ -483,7 +511,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | |||
483 | // "or" | 511 | // "or" |
484 | if (argc) { | 512 | if (argc) { |
485 | if (strcmp(*argv, "or") != 0) { | 513 | if (strcmp(*argv, "or") != 0) { |
486 | return cmd_results_new(CMD_INVALID, usage); | 514 | return cmd_results_new(CMD_INVALID, "%s", usage); |
487 | } | 515 | } |
488 | --argc; ++argv; | 516 | --argc; ++argv; |
489 | } | 517 | } |
@@ -493,10 +521,10 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | |||
493 | if (argc) { | 521 | if (argc) { |
494 | int num_consumed_args = parse_movement_amount(argc, argv, &second_amount); | 522 | int num_consumed_args = parse_movement_amount(argc, argv, &second_amount); |
495 | if (argc > num_consumed_args) { | 523 | if (argc > num_consumed_args) { |
496 | return cmd_results_new(CMD_INVALID, usage); | 524 | return cmd_results_new(CMD_INVALID, "%s", usage); |
497 | } | 525 | } |
498 | if (second_amount.unit == MOVEMENT_UNIT_INVALID) { | 526 | if (second_amount.unit == MOVEMENT_UNIT_INVALID) { |
499 | return cmd_results_new(CMD_INVALID, usage); | 527 | return cmd_results_new(CMD_INVALID, "%s", usage); |
500 | } | 528 | } |
501 | } else { | 529 | } else { |
502 | second_amount.amount = 0; | 530 | second_amount.amount = 0; |
@@ -566,5 +594,5 @@ struct cmd_results *cmd_resize(int argc, char **argv) { | |||
566 | const char usage[] = "Expected 'resize <shrink|grow> " | 594 | const char usage[] = "Expected 'resize <shrink|grow> " |
567 | "<width|height|up|down|left|right> [<amount>] [px|ppt]'"; | 595 | "<width|height|up|down|left|right> [<amount>] [px|ppt]'"; |
568 | 596 | ||
569 | return cmd_results_new(CMD_INVALID, usage); | 597 | return cmd_results_new(CMD_INVALID, "%s", usage); |
570 | } | 598 | } |
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c index 34871bc6..c995f2f0 100644 --- a/sway/commands/scratchpad.c +++ b/sway/commands/scratchpad.c | |||
@@ -21,8 +21,8 @@ static void scratchpad_toggle_auto(void) { | |||
21 | // If the focus is in a floating split container, | 21 | // If the focus is in a floating split container, |
22 | // operate on the split container instead of the child. | 22 | // operate on the split container instead of the child. |
23 | if (focus && container_is_floating_or_child(focus)) { | 23 | if (focus && container_is_floating_or_child(focus)) { |
24 | while (focus->parent) { | 24 | while (focus->pending.parent) { |
25 | focus = focus->parent; | 25 | focus = focus->pending.parent; |
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
@@ -52,7 +52,7 @@ static void scratchpad_toggle_auto(void) { | |||
52 | // In this case we move it to the current workspace. | 52 | // In this case we move it to the current workspace. |
53 | for (int i = 0; i < root->scratchpad->length; ++i) { | 53 | for (int i = 0; i < root->scratchpad->length; ++i) { |
54 | struct sway_container *con = root->scratchpad->items[i]; | 54 | struct sway_container *con = root->scratchpad->items[i]; |
55 | if (con->parent) { | 55 | if (con->pending.parent) { |
56 | sway_log(SWAY_DEBUG, | 56 | sway_log(SWAY_DEBUG, |
57 | "Moving a visible scratchpad window (%s) to this workspace", | 57 | "Moving a visible scratchpad window (%s) to this workspace", |
58 | con->title); | 58 | con->title); |
@@ -80,7 +80,7 @@ static void scratchpad_toggle_container(struct sway_container *con) { | |||
80 | struct sway_seat *seat = input_manager_current_seat(); | 80 | struct sway_seat *seat = input_manager_current_seat(); |
81 | struct sway_workspace *ws = seat_get_focused_workspace(seat); | 81 | struct sway_workspace *ws = seat_get_focused_workspace(seat); |
82 | // Check if it matches a currently visible scratchpad window and hide it. | 82 | // Check if it matches a currently visible scratchpad window and hide it. |
83 | if (con->workspace && ws == con->workspace) { | 83 | if (con->pending.workspace && ws == con->pending.workspace) { |
84 | root_scratchpad_hide(con); | 84 | root_scratchpad_hide(con); |
85 | return; | 85 | return; |
86 | } | 86 | } |
@@ -105,21 +105,22 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) { | |||
105 | return cmd_results_new(CMD_INVALID, "Scratchpad is empty"); | 105 | return cmd_results_new(CMD_INVALID, "Scratchpad is empty"); |
106 | } | 106 | } |
107 | 107 | ||
108 | if (config->handler_context.using_criteria) { | 108 | if (config->handler_context.node_overridden) { |
109 | struct sway_container *con = config->handler_context.container; | 109 | struct sway_container *con = config->handler_context.container; |
110 | 110 | ||
111 | // If the container is in a floating split container, | 111 | // If the container is in a floating split container, |
112 | // operate on the split container instead of the child. | 112 | // operate on the split container instead of the child. |
113 | if (container_is_floating_or_child(con)) { | 113 | if (con && container_is_floating_or_child(con)) { |
114 | while (con->parent) { | 114 | while (con->pending.parent) { |
115 | con = con->parent; | 115 | con = con->pending.parent; |
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | // If using criteria, this command is executed for every container which | 119 | // If using criteria, this command is executed for every container which |
120 | // matches the criteria. If this container isn't in the scratchpad, | 120 | // matches the criteria. If this container isn't in the scratchpad, |
121 | // we'll just silently return a success. | 121 | // we'll just silently return a success. The same is true if the |
122 | if (!con->scratchpad) { | 122 | // overridden node is not a container. |
123 | if (!con || !con->scratchpad) { | ||
123 | return cmd_results_new(CMD_SUCCESS, NULL); | 124 | return cmd_results_new(CMD_SUCCESS, NULL); |
124 | } | 125 | } |
125 | scratchpad_toggle_container(con); | 126 | scratchpad_toggle_container(con); |
diff --git a/sway/commands/seat.c b/sway/commands/seat.c index 84c6ba53..2d197b69 100644 --- a/sway/commands/seat.c +++ b/sway/commands/seat.c | |||
@@ -8,13 +8,13 @@ | |||
8 | 8 | ||
9 | // must be in order for the bsearch | 9 | // must be in order for the bsearch |
10 | // these handlers perform actions on the seat | 10 | // these handlers perform actions on the seat |
11 | static struct cmd_handler seat_action_handlers[] = { | 11 | static const struct cmd_handler seat_action_handlers[] = { |
12 | { "cursor", seat_cmd_cursor }, | 12 | { "cursor", seat_cmd_cursor }, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | // must be in order for the bsearch | 15 | // must be in order for the bsearch |
16 | // these handlers alter the seat config | 16 | // these handlers alter the seat config |
17 | static struct cmd_handler seat_handlers[] = { | 17 | static const struct cmd_handler seat_handlers[] = { |
18 | { "attach", seat_cmd_attach }, | 18 | { "attach", seat_cmd_attach }, |
19 | { "fallback", seat_cmd_fallback }, | 19 | { "fallback", seat_cmd_fallback }, |
20 | { "hide_cursor", seat_cmd_hide_cursor }, | 20 | { "hide_cursor", seat_cmd_hide_cursor }, |
diff --git a/sway/commands/seat/attach.c b/sway/commands/seat/attach.c index 7615eef9..47d18546 100644 --- a/sway/commands/seat/attach.c +++ b/sway/commands/seat/attach.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -12,7 +11,7 @@ struct cmd_results *seat_cmd_attach(int argc, char **argv) { | |||
12 | if (!config->handler_context.seat_config) { | 11 | if (!config->handler_context.seat_config) { |
13 | return cmd_results_new(CMD_FAILURE, "No seat defined"); | 12 | return cmd_results_new(CMD_FAILURE, "No seat defined"); |
14 | } | 13 | } |
15 | if (config->reading) { | 14 | if (!config->active) { |
16 | return cmd_results_new(CMD_DEFER, NULL); | 15 | return cmd_results_new(CMD_DEFER, NULL); |
17 | } | 16 | } |
18 | 17 | ||
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index 749235eb..df7c379d 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <linux/input-event-codes.h> | 1 | #include <linux/input-event-codes.h> |
3 | 2 | ||
4 | #include <strings.h> | 3 | #include <strings.h> |
@@ -18,7 +17,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor, | |||
18 | int argc, char **argv) { | 17 | int argc, char **argv) { |
19 | if (strcasecmp(argv[0], "move") == 0) { | 18 | if (strcasecmp(argv[0], "move") == 0) { |
20 | if (argc < 3) { | 19 | if (argc < 3) { |
21 | return cmd_results_new(CMD_INVALID, expected_syntax); | 20 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
22 | } | 21 | } |
23 | int delta_x = strtol(argv[1], NULL, 10); | 22 | int delta_x = strtol(argv[1], NULL, 10); |
24 | int delta_y = strtol(argv[2], NULL, 10); | 23 | int delta_y = strtol(argv[2], NULL, 10); |
@@ -27,7 +26,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor, | |||
27 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); | 26 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); |
28 | } else if (strcasecmp(argv[0], "set") == 0) { | 27 | } else if (strcasecmp(argv[0], "set") == 0) { |
29 | if (argc < 3) { | 28 | if (argc < 3) { |
30 | return cmd_results_new(CMD_INVALID, expected_syntax); | 29 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
31 | } | 30 | } |
32 | // map absolute coords (0..1,0..1) to root container coords | 31 | // map absolute coords (0..1,0..1) to root container coords |
33 | float x = strtof(argv[1], NULL) / root->width; | 32 | float x = strtof(argv[1], NULL) / root->width; |
@@ -37,7 +36,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor, | |||
37 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); | 36 | wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); |
38 | } else { | 37 | } else { |
39 | if (argc < 2) { | 38 | if (argc < 2) { |
40 | return cmd_results_new(CMD_INVALID, expected_syntax); | 39 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
41 | } | 40 | } |
42 | struct cmd_results *error = NULL; | 41 | struct cmd_results *error = NULL; |
43 | if ((error = press_or_release(cursor, argv[0], argv[1]))) { | 42 | if ((error = press_or_release(cursor, argv[0], argv[1]))) { |
@@ -85,36 +84,36 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
85 | 84 | ||
86 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, | 85 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, |
87 | char *action, char *button_str) { | 86 | char *action, char *button_str) { |
88 | enum wlr_button_state state; | 87 | enum wl_pointer_button_state state; |
89 | uint32_t button; | 88 | uint32_t button; |
90 | if (strcasecmp(action, "press") == 0) { | 89 | if (strcasecmp(action, "press") == 0) { |
91 | state = WLR_BUTTON_PRESSED; | 90 | state = WL_POINTER_BUTTON_STATE_PRESSED; |
92 | } else if (strcasecmp(action, "release") == 0) { | 91 | } else if (strcasecmp(action, "release") == 0) { |
93 | state = WLR_BUTTON_RELEASED; | 92 | state = WL_POINTER_BUTTON_STATE_RELEASED; |
94 | } else { | 93 | } else { |
95 | return cmd_results_new(CMD_INVALID, expected_syntax); | 94 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
96 | } | 95 | } |
97 | 96 | ||
98 | char *message = NULL; | 97 | char *message = NULL; |
99 | button = get_mouse_button(button_str, &message); | 98 | button = get_mouse_button(button_str, &message); |
100 | if (message) { | 99 | if (message) { |
101 | struct cmd_results *error = | 100 | struct cmd_results *error = |
102 | cmd_results_new(CMD_INVALID, message); | 101 | cmd_results_new(CMD_INVALID, "%s", message); |
103 | free(message); | 102 | free(message); |
104 | return error; | 103 | return error; |
105 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN | 104 | } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN |
106 | || button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { | 105 | || button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { |
107 | // Dispatch axis event | 106 | // Dispatch axis event |
108 | enum wlr_axis_orientation orientation = | 107 | enum wl_pointer_axis orientation = |
109 | (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN) | 108 | (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN) |
110 | ? WLR_AXIS_ORIENTATION_VERTICAL | 109 | ? WL_POINTER_AXIS_VERTICAL_SCROLL |
111 | : WLR_AXIS_ORIENTATION_HORIZONTAL; | 110 | : WL_POINTER_AXIS_HORIZONTAL_SCROLL; |
112 | double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) | 111 | double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) |
113 | ? -1 : 1; | 112 | ? -1 : 1; |
114 | struct wlr_event_pointer_axis event = { | 113 | struct wlr_pointer_axis_event event = { |
115 | .device = NULL, | 114 | .pointer = NULL, |
116 | .time_msec = 0, | 115 | .time_msec = 0, |
117 | .source = WLR_AXIS_SOURCE_WHEEL, | 116 | .source = WL_POINTER_AXIS_SOURCE_WHEEL, |
118 | .orientation = orientation, | 117 | .orientation = orientation, |
119 | .delta = delta * 15, | 118 | .delta = delta * 15, |
120 | .delta_discrete = delta | 119 | .delta_discrete = delta |
diff --git a/sway/commands/seat/hide_cursor.c b/sway/commands/seat/hide_cursor.c index e09b82d9..f5177a47 100644 --- a/sway/commands/seat/hide_cursor.c +++ b/sway/commands/seat/hide_cursor.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/seat/idle.c b/sway/commands/seat/idle.c index 82428f2c..2974453e 100644 --- a/sway/commands/seat/idle.c +++ b/sway/commands/seat/idle.c | |||
@@ -1,8 +1,8 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
5 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include "log.h" | ||
6 | #include "sway/commands.h" | 6 | #include "sway/commands.h" |
7 | #include "sway/config.h" | 7 | #include "sway/config.h" |
8 | #include "sway/input/seat.h" | 8 | #include "sway/input/seat.h" |
@@ -69,5 +69,10 @@ struct cmd_results *seat_cmd_idle_wake(int argc, char **argv) { | |||
69 | return cmd_results_new(CMD_FAILURE, "Invalid idle source"); | 69 | return cmd_results_new(CMD_FAILURE, "Invalid idle source"); |
70 | } | 70 | } |
71 | config->handler_context.seat_config->idle_wake_sources = sources; | 71 | config->handler_context.seat_config->idle_wake_sources = sources; |
72 | sway_log(SWAY_INFO, "Warning: seat idle_wake is deprecated"); | ||
73 | if (config->reading) { | ||
74 | config_add_swaynag_warning("seat idle_wake is deprecated. " | ||
75 | "Only seat idle_inhibit is supported."); | ||
76 | } | ||
72 | return cmd_results_new(CMD_SUCCESS, NULL); | 77 | return cmd_results_new(CMD_SUCCESS, NULL); |
73 | } | 78 | } |
diff --git a/sway/commands/seat/xcursor_theme.c b/sway/commands/seat/xcursor_theme.c index 202f35b9..61322a57 100644 --- a/sway/commands/seat/xcursor_theme.c +++ b/sway/commands/seat/xcursor_theme.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
diff --git a/sway/commands/set.c b/sway/commands/set.c index c539e9fc..ba384c7c 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdio.h> | 1 | #include <stdio.h> |
3 | #include <string.h> | 2 | #include <string.h> |
4 | #include <strings.h> | 3 | #include <strings.h> |
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c index 0d373b80..60cef9fa 100644 --- a/sway/commands/show_marks.c +++ b/sway/commands/show_marks.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -10,8 +9,8 @@ | |||
10 | #include "stringop.h" | 9 | #include "stringop.h" |
11 | #include "util.h" | 10 | #include "util.h" |
12 | 11 | ||
13 | static void rebuild_marks_iterator(struct sway_container *con, void *data) { | 12 | static void title_bar_update_iterator(struct sway_container *con, void *data) { |
14 | container_update_marks_textures(con); | 13 | container_update_marks(con); |
15 | } | 14 | } |
16 | 15 | ||
17 | struct cmd_results *cmd_show_marks(int argc, char **argv) { | 16 | struct cmd_results *cmd_show_marks(int argc, char **argv) { |
@@ -23,12 +22,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) { | |||
23 | config->show_marks = parse_boolean(argv[0], config->show_marks); | 22 | config->show_marks = parse_boolean(argv[0], config->show_marks); |
24 | 23 | ||
25 | if (config->show_marks) { | 24 | if (config->show_marks) { |
26 | root_for_each_container(rebuild_marks_iterator, NULL); | 25 | root_for_each_container(title_bar_update_iterator, NULL); |
27 | } | ||
28 | |||
29 | for (int i = 0; i < root->outputs->length; ++i) { | ||
30 | struct sway_output *output = root->outputs->items[i]; | ||
31 | output_damage_whole(output); | ||
32 | } | 26 | } |
33 | 27 | ||
34 | return cmd_results_new(CMD_SUCCESS, NULL); | 28 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/smart_gaps.c b/sway/commands/smart_gaps.c index b27f9ccd..a6d165dc 100644 --- a/sway/commands/smart_gaps.c +++ b/sway/commands/smart_gaps.c | |||
@@ -15,7 +15,12 @@ struct cmd_results *cmd_smart_gaps(int argc, char **argv) { | |||
15 | return error; | 15 | return error; |
16 | } | 16 | } |
17 | 17 | ||
18 | config->smart_gaps = parse_boolean(argv[0], config->smart_gaps); | 18 | if (strcmp(argv[0], "inverse_outer") == 0) { |
19 | config->smart_gaps = SMART_GAPS_INVERSE_OUTER; | ||
20 | } else { | ||
21 | config->smart_gaps = parse_boolean(argv[0], config->smart_gaps) | ||
22 | ? SMART_GAPS_ON : SMART_GAPS_OFF; | ||
23 | } | ||
19 | 24 | ||
20 | arrange_root(); | 25 | arrange_root(); |
21 | 26 | ||
diff --git a/sway/commands/split.c b/sway/commands/split.c index 782bab02..500a497d 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c | |||
@@ -14,7 +14,7 @@ static struct cmd_results *do_split(int layout) { | |||
14 | struct sway_workspace *ws = config->handler_context.workspace; | 14 | struct sway_workspace *ws = config->handler_context.workspace; |
15 | if (con) { | 15 | if (con) { |
16 | if (container_is_scratchpad_hidden_or_child(con) && | 16 | if (container_is_scratchpad_hidden_or_child(con) && |
17 | con->fullscreen_mode != FULLSCREEN_GLOBAL) { | 17 | con->pending.fullscreen_mode != FULLSCREEN_GLOBAL) { |
18 | return cmd_results_new(CMD_FAILURE, | 18 | return cmd_results_new(CMD_FAILURE, |
19 | "Cannot split a hidden scratchpad container"); | 19 | "Cannot split a hidden scratchpad container"); |
20 | } | 20 | } |
@@ -32,6 +32,24 @@ static struct cmd_results *do_split(int layout) { | |||
32 | return cmd_results_new(CMD_SUCCESS, NULL); | 32 | return cmd_results_new(CMD_SUCCESS, NULL); |
33 | } | 33 | } |
34 | 34 | ||
35 | static struct cmd_results *do_unsplit(void) { | ||
36 | struct sway_container *con = config->handler_context.container; | ||
37 | struct sway_workspace *ws = config->handler_context.workspace; | ||
38 | |||
39 | if (con && con->pending.parent && con->pending.parent->pending.children->length == 1) { | ||
40 | container_flatten(con->pending.parent); | ||
41 | } else { | ||
42 | return cmd_results_new(CMD_FAILURE, "Can only flatten a child container with no siblings"); | ||
43 | } | ||
44 | |||
45 | if (root->fullscreen_global) { | ||
46 | arrange_root(); | ||
47 | } else { | ||
48 | arrange_workspace(ws); | ||
49 | } | ||
50 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
51 | } | ||
52 | |||
35 | struct cmd_results *cmd_split(int argc, char **argv) { | 53 | struct cmd_results *cmd_split(int argc, char **argv) { |
36 | struct cmd_results *error = NULL; | 54 | struct cmd_results *error = NULL; |
37 | if ((error = checkarg(argc, "split", EXPECTED_EQUAL_TO, 1))) { | 55 | if ((error = checkarg(argc, "split", EXPECTED_EQUAL_TO, 1))) { |
@@ -55,6 +73,9 @@ struct cmd_results *cmd_split(int argc, char **argv) { | |||
55 | } else { | 73 | } else { |
56 | return do_split(L_VERT); | 74 | return do_split(L_VERT); |
57 | } | 75 | } |
76 | } else if (strcasecmp(argv[0], "n") == 0 || | ||
77 | strcasecmp(argv[0], "none") == 0) { | ||
78 | return do_unsplit(); | ||
58 | } else { | 79 | } else { |
59 | return cmd_results_new(CMD_FAILURE, | 80 | return cmd_results_new(CMD_FAILURE, |
60 | "Invalid split command (expected either horizontal or vertical)."); | 81 | "Invalid split command (expected either horizontal or vertical)."); |
diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c index 3c93a276..9b09a0f9 100644 --- a/sway/commands/sticky.c +++ b/sway/commands/sticky.c | |||
@@ -29,14 +29,14 @@ struct cmd_results *cmd_sticky(int argc, char **argv) { | |||
29 | !container_is_scratchpad_hidden(container)) { | 29 | !container_is_scratchpad_hidden(container)) { |
30 | // move container to active workspace | 30 | // move container to active workspace |
31 | struct sway_workspace *active_workspace = | 31 | struct sway_workspace *active_workspace = |
32 | output_get_active_workspace(container->workspace->output); | 32 | output_get_active_workspace(container->pending.workspace->output); |
33 | if (!sway_assert(active_workspace, | 33 | if (!sway_assert(active_workspace, |
34 | "Expected output to have a workspace")) { | 34 | "Expected output to have a workspace")) { |
35 | return cmd_results_new(CMD_FAILURE, | 35 | return cmd_results_new(CMD_FAILURE, |
36 | "Expected output to have a workspace"); | 36 | "Expected output to have a workspace"); |
37 | } | 37 | } |
38 | if (container->workspace != active_workspace) { | 38 | if (container->pending.workspace != active_workspace) { |
39 | struct sway_workspace *old_workspace = container->workspace; | 39 | struct sway_workspace *old_workspace = container->pending.workspace; |
40 | container_detach(container); | 40 | container_detach(container); |
41 | workspace_add_floating(active_workspace, container); | 41 | workspace_add_floating(active_workspace, container); |
42 | container_handle_fullscreen_reparent(container); | 42 | container_handle_fullscreen_reparent(container); |
diff --git a/sway/commands/swap.c b/sway/commands/swap.c index a7f9691b..c0b0d0b9 100644 --- a/sway/commands/swap.c +++ b/sway/commands/swap.c | |||
@@ -1,10 +1,10 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <strings.h> | 1 | #include <strings.h> |
3 | #include "config.h" | 2 | #include "config.h" |
4 | #include "log.h" | 3 | #include "log.h" |
5 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
6 | #include "sway/output.h" | 5 | #include "sway/output.h" |
7 | #include "sway/tree/arrange.h" | 6 | #include "sway/tree/arrange.h" |
7 | #include "sway/tree/container.h" | ||
8 | #include "sway/tree/root.h" | 8 | #include "sway/tree/root.h" |
9 | #include "sway/tree/view.h" | 9 | #include "sway/tree/view.h" |
10 | #include "sway/tree/workspace.h" | 10 | #include "sway/tree/workspace.h" |
@@ -13,186 +13,12 @@ | |||
13 | static const char expected_syntax[] = | 13 | static const char expected_syntax[] = |
14 | "Expected 'swap container with id|con_id|mark <arg>'"; | 14 | "Expected 'swap container with id|con_id|mark <arg>'"; |
15 | 15 | ||
16 | static void swap_places(struct sway_container *con1, | ||
17 | struct sway_container *con2) { | ||
18 | struct sway_container *temp = malloc(sizeof(struct sway_container)); | ||
19 | temp->x = con1->x; | ||
20 | temp->y = con1->y; | ||
21 | temp->width = con1->width; | ||
22 | temp->height = con1->height; | ||
23 | temp->width_fraction = con1->width_fraction; | ||
24 | temp->height_fraction = con1->height_fraction; | ||
25 | temp->parent = con1->parent; | ||
26 | temp->workspace = con1->workspace; | ||
27 | bool temp_floating = container_is_floating(con1); | ||
28 | |||
29 | con1->x = con2->x; | ||
30 | con1->y = con2->y; | ||
31 | con1->width = con2->width; | ||
32 | con1->height = con2->height; | ||
33 | con1->width_fraction = con2->width_fraction; | ||
34 | con1->height_fraction = con2->height_fraction; | ||
35 | |||
36 | con2->x = temp->x; | ||
37 | con2->y = temp->y; | ||
38 | con2->width = temp->width; | ||
39 | con2->height = temp->height; | ||
40 | con2->width_fraction = temp->width_fraction; | ||
41 | con2->height_fraction = temp->height_fraction; | ||
42 | |||
43 | int temp_index = container_sibling_index(con1); | ||
44 | if (con2->parent) { | ||
45 | container_insert_child(con2->parent, con1, | ||
46 | container_sibling_index(con2)); | ||
47 | } else if (container_is_floating(con2)) { | ||
48 | workspace_add_floating(con2->workspace, con1); | ||
49 | } else { | ||
50 | workspace_insert_tiling(con2->workspace, con1, | ||
51 | container_sibling_index(con2)); | ||
52 | } | ||
53 | if (temp->parent) { | ||
54 | container_insert_child(temp->parent, con2, temp_index); | ||
55 | } else if (temp_floating) { | ||
56 | workspace_add_floating(temp->workspace, con2); | ||
57 | } else { | ||
58 | workspace_insert_tiling(temp->workspace, con2, temp_index); | ||
59 | } | ||
60 | |||
61 | free(temp); | ||
62 | } | ||
63 | |||
64 | static void swap_focus(struct sway_container *con1, | ||
65 | struct sway_container *con2, struct sway_seat *seat, | ||
66 | struct sway_container *focus) { | ||
67 | if (focus == con1 || focus == con2) { | ||
68 | struct sway_workspace *ws1 = con1->workspace; | ||
69 | struct sway_workspace *ws2 = con2->workspace; | ||
70 | enum sway_container_layout layout1 = container_parent_layout(con1); | ||
71 | enum sway_container_layout layout2 = container_parent_layout(con2); | ||
72 | if (focus == con1 && (layout2 == L_TABBED || layout2 == L_STACKED)) { | ||
73 | if (workspace_is_visible(ws2)) { | ||
74 | seat_set_focus(seat, &con2->node); | ||
75 | } | ||
76 | seat_set_focus_container(seat, ws1 != ws2 ? con2 : con1); | ||
77 | } else if (focus == con2 && (layout1 == L_TABBED | ||
78 | || layout1 == L_STACKED)) { | ||
79 | if (workspace_is_visible(ws1)) { | ||
80 | seat_set_focus(seat, &con1->node); | ||
81 | } | ||
82 | seat_set_focus_container(seat, ws1 != ws2 ? con1 : con2); | ||
83 | } else if (ws1 != ws2) { | ||
84 | seat_set_focus_container(seat, focus == con1 ? con2 : con1); | ||
85 | } else { | ||
86 | seat_set_focus_container(seat, focus); | ||
87 | } | ||
88 | } else { | ||
89 | seat_set_focus_container(seat, focus); | ||
90 | } | ||
91 | |||
92 | if (root->fullscreen_global) { | ||
93 | seat_set_focus(seat, | ||
94 | seat_get_focus_inactive(seat, &root->fullscreen_global->node)); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | void container_swap(struct sway_container *con1, struct sway_container *con2) { | ||
99 | if (!sway_assert(con1 && con2, "Cannot swap with nothing")) { | ||
100 | return; | ||
101 | } | ||
102 | if (!sway_assert(!container_has_ancestor(con1, con2) | ||
103 | && !container_has_ancestor(con2, con1), | ||
104 | "Cannot swap ancestor and descendant")) { | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | sway_log(SWAY_DEBUG, "Swapping containers %zu and %zu", | ||
109 | con1->node.id, con2->node.id); | ||
110 | |||
111 | bool scratch1 = con1->scratchpad; | ||
112 | bool hidden1 = container_is_scratchpad_hidden(con1); | ||
113 | bool scratch2 = con2->scratchpad; | ||
114 | bool hidden2 = container_is_scratchpad_hidden(con2); | ||
115 | if (scratch1) { | ||
116 | if (hidden1) { | ||
117 | root_scratchpad_show(con1); | ||
118 | } | ||
119 | root_scratchpad_remove_container(con1); | ||
120 | } | ||
121 | if (scratch2) { | ||
122 | if (hidden2) { | ||
123 | root_scratchpad_show(con2); | ||
124 | } | ||
125 | root_scratchpad_remove_container(con2); | ||
126 | } | ||
127 | |||
128 | enum sway_fullscreen_mode fs1 = con1->fullscreen_mode; | ||
129 | enum sway_fullscreen_mode fs2 = con2->fullscreen_mode; | ||
130 | if (fs1) { | ||
131 | container_fullscreen_disable(con1); | ||
132 | } | ||
133 | if (fs2) { | ||
134 | container_fullscreen_disable(con2); | ||
135 | } | ||
136 | |||
137 | struct sway_seat *seat = config->handler_context.seat; | ||
138 | struct sway_container *focus = seat_get_focused_container(seat); | ||
139 | struct sway_workspace *vis1 = | ||
140 | output_get_active_workspace(con1->workspace->output); | ||
141 | struct sway_workspace *vis2 = | ||
142 | output_get_active_workspace(con2->workspace->output); | ||
143 | if (!sway_assert(vis1 && vis2, "con1 or con2 are on an output without a" | ||
144 | "workspace. This should not happen")) { | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | char *stored_prev_name = NULL; | ||
149 | if (seat->prev_workspace_name) { | ||
150 | stored_prev_name = strdup(seat->prev_workspace_name); | ||
151 | } | ||
152 | |||
153 | swap_places(con1, con2); | ||
154 | |||
155 | if (!workspace_is_visible(vis1)) { | ||
156 | seat_set_focus(seat, seat_get_focus_inactive(seat, &vis1->node)); | ||
157 | } | ||
158 | if (!workspace_is_visible(vis2)) { | ||
159 | seat_set_focus(seat, seat_get_focus_inactive(seat, &vis2->node)); | ||
160 | } | ||
161 | |||
162 | swap_focus(con1, con2, seat, focus); | ||
163 | |||
164 | if (stored_prev_name) { | ||
165 | free(seat->prev_workspace_name); | ||
166 | seat->prev_workspace_name = stored_prev_name; | ||
167 | } | ||
168 | |||
169 | if (scratch1) { | ||
170 | root_scratchpad_add_container(con2, NULL); | ||
171 | if (!hidden1) { | ||
172 | root_scratchpad_show(con2); | ||
173 | } | ||
174 | } | ||
175 | if (scratch2) { | ||
176 | root_scratchpad_add_container(con1, NULL); | ||
177 | if (!hidden2) { | ||
178 | root_scratchpad_show(con1); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | if (fs1) { | ||
183 | container_set_fullscreen(con2, fs1); | ||
184 | } | ||
185 | if (fs2) { | ||
186 | container_set_fullscreen(con1, fs2); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static bool test_con_id(struct sway_container *container, void *data) { | 16 | static bool test_con_id(struct sway_container *container, void *data) { |
191 | size_t *con_id = data; | 17 | size_t *con_id = data; |
192 | return container->node.id == *con_id; | 18 | return container->node.id == *con_id; |
193 | } | 19 | } |
194 | 20 | ||
195 | #if HAVE_XWAYLAND | 21 | #if WLR_HAS_XWAYLAND |
196 | static bool test_id(struct sway_container *container, void *data) { | 22 | static bool test_id(struct sway_container *container, void *data) { |
197 | xcb_window_t *wid = data; | 23 | xcb_window_t *wid = data; |
198 | return (container->view && container->view->type == SWAY_VIEW_XWAYLAND | 24 | return (container->view && container->view->type == SWAY_VIEW_XWAYLAND |
@@ -219,7 +45,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
219 | } | 45 | } |
220 | 46 | ||
221 | if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) { | 47 | if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) { |
222 | return cmd_results_new(CMD_INVALID, expected_syntax); | 48 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
223 | } | 49 | } |
224 | 50 | ||
225 | struct sway_container *current = config->handler_context.container; | 51 | struct sway_container *current = config->handler_context.container; |
@@ -227,7 +53,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
227 | 53 | ||
228 | char *value = join_args(argv + 3, argc - 3); | 54 | char *value = join_args(argv + 3, argc - 3); |
229 | if (strcasecmp(argv[2], "id") == 0) { | 55 | if (strcasecmp(argv[2], "id") == 0) { |
230 | #if HAVE_XWAYLAND | 56 | #if WLR_HAS_XWAYLAND |
231 | xcb_window_t id = strtol(value, NULL, 0); | 57 | xcb_window_t id = strtol(value, NULL, 0); |
232 | other = root_find_container(test_id, &id); | 58 | other = root_find_container(test_id, &id); |
233 | #endif | 59 | #endif |
@@ -238,7 +64,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
238 | other = root_find_container(test_mark, value); | 64 | other = root_find_container(test_mark, value); |
239 | } else { | 65 | } else { |
240 | free(value); | 66 | free(value); |
241 | return cmd_results_new(CMD_INVALID, expected_syntax); | 67 | return cmd_results_new(CMD_INVALID, "%s", expected_syntax); |
242 | } | 68 | } |
243 | 69 | ||
244 | if (!other) { | 70 | if (!other) { |
@@ -247,6 +73,9 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
247 | } else if (!current) { | 73 | } else if (!current) { |
248 | error = cmd_results_new(CMD_FAILURE, | 74 | error = cmd_results_new(CMD_FAILURE, |
249 | "Can only swap with containers and views"); | 75 | "Can only swap with containers and views"); |
76 | } else if (current == other) { | ||
77 | error = cmd_results_new(CMD_FAILURE, | ||
78 | "Cannot swap a container with itself"); | ||
250 | } else if (container_has_ancestor(current, other) | 79 | } else if (container_has_ancestor(current, other) |
251 | || container_has_ancestor(other, current)) { | 80 | || container_has_ancestor(other, current)) { |
252 | error = cmd_results_new(CMD_FAILURE, | 81 | error = cmd_results_new(CMD_FAILURE, |
diff --git a/sway/commands/title_align.c b/sway/commands/title_align.c index c30355de..be298a29 100644 --- a/sway/commands/title_align.c +++ b/sway/commands/title_align.c | |||
@@ -4,6 +4,10 @@ | |||
4 | #include "sway/tree/container.h" | 4 | #include "sway/tree/container.h" |
5 | #include "sway/tree/root.h" | 5 | #include "sway/tree/root.h" |
6 | 6 | ||
7 | static void arrange_title_bar_iterator(struct sway_container *con, void *data) { | ||
8 | container_arrange_title_bar(con); | ||
9 | } | ||
10 | |||
7 | struct cmd_results *cmd_title_align(int argc, char **argv) { | 11 | struct cmd_results *cmd_title_align(int argc, char **argv) { |
8 | struct cmd_results *error = NULL; | 12 | struct cmd_results *error = NULL; |
9 | if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { | 13 | if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { |
@@ -21,10 +25,7 @@ struct cmd_results *cmd_title_align(int argc, char **argv) { | |||
21 | "Expected 'title_align left|center|right'"); | 25 | "Expected 'title_align left|center|right'"); |
22 | } | 26 | } |
23 | 27 | ||
24 | for (int i = 0; i < root->outputs->length; ++i) { | 28 | root_for_each_container(arrange_title_bar_iterator, NULL); |
25 | struct sway_output *output = root->outputs->items[i]; | ||
26 | output_damage_whole(output); | ||
27 | } | ||
28 | 29 | ||
29 | return cmd_results_new(CMD_SUCCESS, NULL); | 30 | return cmd_results_new(CMD_SUCCESS, NULL); |
30 | } | 31 | } |
diff --git a/sway/commands/title_format.c b/sway/commands/title_format.c index 9d312470..0b2ea265 100644 --- a/sway/commands/title_format.c +++ b/sway/commands/title_format.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -23,6 +22,5 @@ struct cmd_results *cmd_title_format(int argc, char **argv) { | |||
23 | } | 22 | } |
24 | view->title_format = format; | 23 | view->title_format = format; |
25 | view_update_title(view, true); | 24 | view_update_title(view, true); |
26 | config_update_font_height(true); | ||
27 | return cmd_results_new(CMD_SUCCESS, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL); |
28 | } | 26 | } |
diff --git a/sway/commands/titlebar_border_thickness.c b/sway/commands/titlebar_border_thickness.c index 7c27c163..fa3db3c5 100644 --- a/sway/commands/titlebar_border_thickness.c +++ b/sway/commands/titlebar_border_thickness.c | |||
@@ -27,7 +27,6 @@ struct cmd_results *cmd_titlebar_border_thickness(int argc, char **argv) { | |||
27 | "Expected output to have a workspace"); | 27 | "Expected output to have a workspace"); |
28 | } | 28 | } |
29 | arrange_workspace(ws); | 29 | arrange_workspace(ws); |
30 | output_damage_whole(output); | ||
31 | } | 30 | } |
32 | 31 | ||
33 | return cmd_results_new(CMD_SUCCESS, NULL); | 32 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/titlebar_padding.c b/sway/commands/titlebar_padding.c index 29ce59ff..6999f7a2 100644 --- a/sway/commands/titlebar_padding.c +++ b/sway/commands/titlebar_padding.c | |||
@@ -33,7 +33,6 @@ struct cmd_results *cmd_titlebar_padding(int argc, char **argv) { | |||
33 | for (int i = 0; i < root->outputs->length; ++i) { | 33 | for (int i = 0; i < root->outputs->length; ++i) { |
34 | struct sway_output *output = root->outputs->items[i]; | 34 | struct sway_output *output = root->outputs->items[i]; |
35 | arrange_workspace(output_get_active_workspace(output)); | 35 | arrange_workspace(output_get_active_workspace(output)); |
36 | output_damage_whole(output); | ||
37 | } | 36 | } |
38 | 37 | ||
39 | return cmd_results_new(CMD_SUCCESS, NULL); | 38 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index cedfcfb2..4aba5bae 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | 1 | #include <string.h> |
3 | #include "sway/commands.h" | 2 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 3 | #include "sway/config.h" |
@@ -8,9 +7,13 @@ | |||
8 | #include "log.h" | 7 | #include "log.h" |
9 | #include "stringop.h" | 8 | #include "stringop.h" |
10 | 9 | ||
11 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { | 10 | static void remove_mark(struct sway_container *con) { |
12 | container_clear_marks(con); | 11 | container_clear_marks(con); |
13 | container_update_marks_textures(con); | 12 | container_update_marks(con); |
13 | } | ||
14 | |||
15 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { | ||
16 | remove_mark(con); | ||
14 | } | 17 | } |
15 | 18 | ||
16 | // unmark Remove all marks from all views | 19 | // unmark Remove all marks from all views |
@@ -21,7 +24,7 @@ static void remove_all_marks_iterator(struct sway_container *con, void *data) { | |||
21 | struct cmd_results *cmd_unmark(int argc, char **argv) { | 24 | struct cmd_results *cmd_unmark(int argc, char **argv) { |
22 | // Determine the container | 25 | // Determine the container |
23 | struct sway_container *con = NULL; | 26 | struct sway_container *con = NULL; |
24 | if (config->handler_context.using_criteria) { | 27 | if (config->handler_context.node_overridden) { |
25 | con = config->handler_context.container; | 28 | con = config->handler_context.container; |
26 | } | 29 | } |
27 | 30 | ||
@@ -38,8 +41,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { | |||
38 | } | 41 | } |
39 | } else if (con && !mark) { | 42 | } else if (con && !mark) { |
40 | // Clear all marks from the given container | 43 | // Clear all marks from the given container |
41 | container_clear_marks(con); | 44 | remove_mark(con); |
42 | container_update_marks_textures(con); | ||
43 | } else if (!con && mark) { | 45 | } else if (!con && mark) { |
44 | // Remove mark from whichever container has it | 46 | // Remove mark from whichever container has it |
45 | container_find_and_unmark(mark); | 47 | container_find_and_unmark(mark); |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 9ff1c97d..37a201b4 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <limits.h> | 2 | #include <limits.h> |
4 | #include <string.h> | 3 | #include <string.h> |
@@ -61,7 +60,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv, | |||
61 | const char expected[] = "Expected 'workspace <name> gaps " | 60 | const char expected[] = "Expected 'workspace <name> gaps " |
62 | "inner|outer|horizontal|vertical|top|right|bottom|left <px>'"; | 61 | "inner|outer|horizontal|vertical|top|right|bottom|left <px>'"; |
63 | if (gaps_location == 0) { | 62 | if (gaps_location == 0) { |
64 | return cmd_results_new(CMD_INVALID, expected); | 63 | return cmd_results_new(CMD_INVALID, "%s", expected); |
65 | } | 64 | } |
66 | struct cmd_results *error = NULL; | 65 | struct cmd_results *error = NULL; |
67 | if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, | 66 | if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, |
@@ -79,7 +78,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv, | |||
79 | char *end; | 78 | char *end; |
80 | int amount = strtol(argv[gaps_location + 2], &end, 10); | 79 | int amount = strtol(argv[gaps_location + 2], &end, 10); |
81 | if (strlen(end)) { | 80 | if (strlen(end)) { |
82 | return cmd_results_new(CMD_FAILURE, expected); | 81 | return cmd_results_new(CMD_FAILURE, "%s", expected); |
83 | } | 82 | } |
84 | 83 | ||
85 | bool valid = false; | 84 | bool valid = false; |
@@ -110,7 +109,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv, | |||
110 | } | 109 | } |
111 | } | 110 | } |
112 | if (!valid) { | 111 | if (!valid) { |
113 | return cmd_results_new(CMD_INVALID, expected); | 112 | return cmd_results_new(CMD_INVALID, "%s", expected); |
114 | } | 113 | } |
115 | 114 | ||
116 | // Prevent invalid gaps configurations. | 115 | // Prevent invalid gaps configurations. |
@@ -178,25 +177,20 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
178 | } | 177 | } |
179 | 178 | ||
180 | if (root->fullscreen_global) { | 179 | if (root->fullscreen_global) { |
181 | return cmd_results_new(CMD_FAILURE, "workspace", | 180 | return cmd_results_new(CMD_FAILURE, |
182 | "Can't switch workspaces while fullscreen global"); | 181 | "Can't switch workspaces while fullscreen global"); |
183 | } | 182 | } |
184 | 183 | ||
185 | bool no_auto_back_and_forth = false; | 184 | bool auto_back_and_forth = true; |
186 | while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { | 185 | while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { |
187 | no_auto_back_and_forth = true; | 186 | auto_back_and_forth = false; |
188 | if ((error = checkarg(--argc, "workspace", EXPECTED_AT_LEAST, 1))) { | 187 | if ((error = checkarg(--argc, "workspace", EXPECTED_AT_LEAST, 1))) { |
189 | return error; | 188 | return error; |
190 | } | 189 | } |
191 | ++argv; | 190 | ++argv; |
192 | } | 191 | } |
193 | 192 | ||
194 | bool create = argc > 1 && strcasecmp(argv[1], "--create") == 0; | ||
195 | struct sway_seat *seat = config->handler_context.seat; | 193 | struct sway_seat *seat = config->handler_context.seat; |
196 | struct sway_workspace *current = seat_get_focused_workspace(seat); | ||
197 | if (!current) { | ||
198 | return cmd_results_new(CMD_FAILURE, "No workspace to switch from"); | ||
199 | } | ||
200 | 194 | ||
201 | struct sway_workspace *ws = NULL; | 195 | struct sway_workspace *ws = NULL; |
202 | if (strcasecmp(argv[0], "number") == 0) { | 196 | if (strcasecmp(argv[0], "number") == 0) { |
@@ -213,14 +207,15 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
213 | ws = workspace_create(NULL, name); | 207 | ws = workspace_create(NULL, name); |
214 | free(name); | 208 | free(name); |
215 | } | 209 | } |
210 | if (ws && auto_back_and_forth) { | ||
211 | ws = workspace_auto_back_and_forth(ws); | ||
212 | } | ||
216 | } else if (strcasecmp(argv[0], "next") == 0 || | 213 | } else if (strcasecmp(argv[0], "next") == 0 || |
217 | strcasecmp(argv[0], "prev") == 0 || | 214 | strcasecmp(argv[0], "prev") == 0 || |
215 | strcasecmp(argv[0], "next_on_output") == 0 || | ||
216 | strcasecmp(argv[0], "prev_on_output") == 0 || | ||
218 | strcasecmp(argv[0], "current") == 0) { | 217 | strcasecmp(argv[0], "current") == 0) { |
219 | ws = workspace_by_name(argv[0]); | 218 | ws = workspace_by_name(argv[0]); |
220 | } else if (strcasecmp(argv[0], "next_on_output") == 0) { | ||
221 | ws = workspace_output_next(current, create); | ||
222 | } else if (strcasecmp(argv[0], "prev_on_output") == 0) { | ||
223 | ws = workspace_output_prev(current, create); | ||
224 | } else if (strcasecmp(argv[0], "back_and_forth") == 0) { | 219 | } else if (strcasecmp(argv[0], "back_and_forth") == 0) { |
225 | if (!seat->prev_workspace_name) { | 220 | if (!seat->prev_workspace_name) { |
226 | return cmd_results_new(CMD_INVALID, | 221 | return cmd_results_new(CMD_INVALID, |
@@ -235,11 +230,14 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
235 | ws = workspace_create(NULL, name); | 230 | ws = workspace_create(NULL, name); |
236 | } | 231 | } |
237 | free(name); | 232 | free(name); |
233 | if (ws && auto_back_and_forth) { | ||
234 | ws = workspace_auto_back_and_forth(ws); | ||
235 | } | ||
238 | } | 236 | } |
239 | if (!ws) { | 237 | if (!ws) { |
240 | return cmd_results_new(CMD_FAILURE, "No workspace to switch to"); | 238 | return cmd_results_new(CMD_FAILURE, "No workspace to switch to"); |
241 | } | 239 | } |
242 | workspace_switch(ws, no_auto_back_and_forth); | 240 | workspace_switch(ws); |
243 | seat_consider_warp_to_focus(seat); | 241 | seat_consider_warp_to_focus(seat); |
244 | } | 242 | } |
245 | return cmd_results_new(CMD_SUCCESS, NULL); | 243 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/xwayland.c b/sway/commands/xwayland.c index 6ca26923..c0b175fc 100644 --- a/sway/commands/xwayland.c +++ b/sway/commands/xwayland.c | |||
@@ -10,7 +10,7 @@ struct cmd_results *cmd_xwayland(int argc, char **argv) { | |||
10 | return error; | 10 | return error; |
11 | } | 11 | } |
12 | 12 | ||
13 | #ifdef HAVE_XWAYLAND | 13 | #ifdef WLR_HAS_XWAYLAND |
14 | enum xwayland_mode xwayland; | 14 | enum xwayland_mode xwayland; |
15 | if (strcmp(argv[0], "force") == 0) { | 15 | if (strcmp(argv[0], "force") == 0) { |
16 | xwayland = XWAYLAND_MODE_IMMEDIATE; | 16 | xwayland = XWAYLAND_MODE_IMMEDIATE; |
@@ -20,6 +20,8 @@ struct cmd_results *cmd_xwayland(int argc, char **argv) { | |||
20 | xwayland = XWAYLAND_MODE_DISABLED; | 20 | xwayland = XWAYLAND_MODE_DISABLED; |
21 | } | 21 | } |
22 | 22 | ||
23 | // config->xwayland is reset to the previous value on reload in | ||
24 | // load_main_config() | ||
23 | if (config->reloading && config->xwayland != xwayland) { | 25 | if (config->reloading && config->xwayland != xwayland) { |
24 | return cmd_results_new(CMD_FAILURE, | 26 | return cmd_results_new(CMD_FAILURE, |
25 | "xwayland can only be enabled/disabled at launch"); | 27 | "xwayland can only be enabled/disabled at launch"); |