diff options
Diffstat (limited to 'sway/commands')
72 files changed, 982 insertions, 235 deletions
diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 9d15e166..0bc0929a 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c | |||
@@ -27,6 +27,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) { | |||
27 | 27 | ||
28 | if (strncmp(*argv, "→", strlen("→")) == 0) { | 28 | if (strncmp(*argv, "→", strlen("→")) == 0) { |
29 | if (argc < 3) { | 29 | if (argc < 3) { |
30 | free(criteria); | ||
30 | return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); | 31 | return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); |
31 | } | 32 | } |
32 | ++argv; | 33 | ++argv; |
@@ -44,7 +45,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) { | |||
44 | criteria->target = join_args(argv, target_len); | 45 | criteria->target = join_args(argv, target_len); |
45 | 46 | ||
46 | list_add(config->criteria, criteria); | 47 | list_add(config->criteria, criteria); |
47 | wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", criteria->raw, | 48 | wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw, |
48 | criteria->target); | 49 | criteria->target); |
49 | 50 | ||
50 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 51 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/bar.c b/sway/commands/bar.c index d84ce808..f6a70c17 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c | |||
@@ -63,13 +63,13 @@ struct cmd_results *cmd_bar(int argc, char **argv) { | |||
63 | for (int i = 0; i < config->bars->length; ++i) { | 63 | for (int i = 0; i < config->bars->length; ++i) { |
64 | struct bar_config *item = config->bars->items[i]; | 64 | struct bar_config *item = config->bars->items[i]; |
65 | if (strcmp(item->id, argv[0]) == 0) { | 65 | if (strcmp(item->id, argv[0]) == 0) { |
66 | wlr_log(L_DEBUG, "Selecting bar: %s", argv[0]); | 66 | wlr_log(WLR_DEBUG, "Selecting bar: %s", argv[0]); |
67 | bar = item; | 67 | bar = item; |
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | } | 70 | } |
71 | if (!bar) { | 71 | if (!bar) { |
72 | wlr_log(L_DEBUG, "Creating bar: %s", argv[0]); | 72 | wlr_log(WLR_DEBUG, "Creating bar: %s", argv[0]); |
73 | bar = default_bar_config(); | 73 | bar = default_bar_config(); |
74 | if (!bar) { | 74 | if (!bar) { |
75 | return cmd_results_new(CMD_FAILURE, "bar", | 75 | return cmd_results_new(CMD_FAILURE, "bar", |
@@ -108,7 +108,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) { | |||
108 | 108 | ||
109 | // Set current bar | 109 | // Set current bar |
110 | config->current_bar = bar; | 110 | config->current_bar = bar; |
111 | wlr_log(L_DEBUG, "Creating bar %s", bar->id); | 111 | wlr_log(WLR_DEBUG, "Creating bar %s", bar->id); |
112 | } | 112 | } |
113 | 113 | ||
114 | return config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers)); | 114 | return config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers)); |
diff --git a/sway/commands/bar/binding_mode_indicator.c b/sway/commands/bar/binding_mode_indicator.c index 3ba5f33f..0c48bee9 100644 --- a/sway/commands/bar/binding_mode_indicator.c +++ b/sway/commands/bar/binding_mode_indicator.c | |||
@@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) { | |||
15 | } | 15 | } |
16 | if (strcasecmp("yes", argv[0]) == 0) { | 16 | if (strcasecmp("yes", argv[0]) == 0) { |
17 | config->current_bar->binding_mode_indicator = true; | 17 | config->current_bar->binding_mode_indicator = true; |
18 | wlr_log(L_DEBUG, "Enabling binding mode indicator on bar: %s", | 18 | wlr_log(WLR_DEBUG, "Enabling binding mode indicator on bar: %s", |
19 | config->current_bar->id); | 19 | config->current_bar->id); |
20 | } else if (strcasecmp("no", argv[0]) == 0) { | 20 | } else if (strcasecmp("no", argv[0]) == 0) { |
21 | config->current_bar->binding_mode_indicator = false; | 21 | config->current_bar->binding_mode_indicator = false; |
22 | wlr_log(L_DEBUG, "Disabling binding mode indicator on bar: %s", | 22 | wlr_log(WLR_DEBUG, "Disabling binding mode indicator on bar: %s", |
23 | config->current_bar->id); | 23 | config->current_bar->id); |
24 | } | 24 | } |
25 | return cmd_results_new(CMD_INVALID, "binding_mode_indicator", | 25 | return cmd_results_new(CMD_INVALID, "binding_mode_indicator", |
diff --git a/sway/commands/bar/font.c b/sway/commands/bar/font.c index 80b7a593..2aa4e895 100644 --- a/sway/commands/bar/font.c +++ b/sway/commands/bar/font.c | |||
@@ -14,8 +14,8 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | char *font = join_args(argv, argc); | 15 | char *font = join_args(argv, argc); |
16 | free(config->current_bar->font); | 16 | free(config->current_bar->font); |
17 | config->current_bar->font = strdup(font); | 17 | config->current_bar->font = font; |
18 | wlr_log(L_DEBUG, "Settings font '%s' for bar: %s", | 18 | wlr_log(WLR_DEBUG, "Settings font '%s' for bar: %s", |
19 | config->current_bar->font, config->current_bar->id); | 19 | config->current_bar->font, config->current_bar->id); |
20 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 20 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
21 | } | 21 | } |
diff --git a/sway/commands/bar/height.c b/sway/commands/bar/height.c index 3160caed..18258526 100644 --- a/sway/commands/bar/height.c +++ b/sway/commands/bar/height.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_height(int argc, char **argv) { | |||
14 | "Invalid height value: %s", argv[0]); | 14 | "Invalid height value: %s", argv[0]); |
15 | } | 15 | } |
16 | config->current_bar->height = height; | 16 | config->current_bar->height = height; |
17 | wlr_log(L_DEBUG, "Setting bar height to %d on bar: %s", | 17 | wlr_log(WLR_DEBUG, "Setting bar height to %d on bar: %s", |
18 | height, config->current_bar->id); | 18 | height, config->current_bar->id); |
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
20 | } | 20 | } |
diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c index 6641f184..502ce2c4 100644 --- a/sway/commands/bar/hidden_state.c +++ b/sway/commands/bar/hidden_state.c | |||
@@ -27,7 +27,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar, | |||
27 | if (!config->reading) { | 27 | if (!config->reading) { |
28 | ipc_event_barconfig_update(bar); | 28 | ipc_event_barconfig_update(bar); |
29 | } | 29 | } |
30 | wlr_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s", | 30 | wlr_log(WLR_DEBUG, "Setting hidden_state: '%s' for bar: %s", |
31 | bar->hidden_state, bar->id); | 31 | bar->hidden_state, bar->id); |
32 | } | 32 | } |
33 | // free old mode | 33 | // free old mode |
diff --git a/sway/commands/bar/id.c b/sway/commands/bar/id.c index 6ce86fef..65fa69fd 100644 --- a/sway/commands/bar/id.c +++ b/sway/commands/bar/id.c | |||
@@ -24,7 +24,7 @@ struct cmd_results *bar_cmd_id(int argc, char **argv) { | |||
24 | } | 24 | } |
25 | } | 25 | } |
26 | 26 | ||
27 | wlr_log(L_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name); | 27 | wlr_log(WLR_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name); |
28 | 28 | ||
29 | // free old bar id | 29 | // free old bar id |
30 | free(config->current_bar->id); | 30 | free(config->current_bar->id); |
diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 34bb0a4f..28e2d77b 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c | |||
@@ -28,7 +28,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode | |||
28 | if (!config->reading) { | 28 | if (!config->reading) { |
29 | ipc_event_barconfig_update(bar); | 29 | ipc_event_barconfig_update(bar); |
30 | } | 30 | } |
31 | wlr_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id); | 31 | wlr_log(WLR_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id); |
32 | } | 32 | } |
33 | 33 | ||
34 | // free old mode | 34 | // free old mode |
diff --git a/sway/commands/bar/modifier.c b/sway/commands/bar/modifier.c index 7ba4b125..09025fff 100644 --- a/sway/commands/bar/modifier.c +++ b/sway/commands/bar/modifier.c | |||
@@ -22,14 +22,15 @@ struct cmd_results *bar_cmd_modifier(int argc, char **argv) { | |||
22 | mod |= tmp_mod; | 22 | mod |= tmp_mod; |
23 | continue; | 23 | continue; |
24 | } else { | 24 | } else { |
25 | error = cmd_results_new(CMD_INVALID, "modifier", | ||
26 | "Unknown modifier '%s'", split->items[i]); | ||
25 | free_flat_list(split); | 27 | free_flat_list(split); |
26 | return cmd_results_new(CMD_INVALID, "modifier", | 28 | return error; |
27 | "Unknown modifier '%s'", split->items[i]); | ||
28 | } | 29 | } |
29 | } | 30 | } |
30 | free_flat_list(split); | 31 | free_flat_list(split); |
31 | config->current_bar->modifier = mod; | 32 | config->current_bar->modifier = mod; |
32 | wlr_log(L_DEBUG, | 33 | wlr_log(WLR_DEBUG, |
33 | "Show/Hide the bar when pressing '%s' in hide mode.", argv[0]); | 34 | "Show/Hide the bar when pressing '%s' in hide mode.", argv[0]); |
34 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 35 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
35 | } | 36 | } |
diff --git a/sway/commands/bar/output.c b/sway/commands/bar/output.c index f7ca0aa4..72754e05 100644 --- a/sway/commands/bar/output.c +++ b/sway/commands/bar/output.c | |||
@@ -42,7 +42,7 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) { | |||
42 | 42 | ||
43 | if (add_output) { | 43 | if (add_output) { |
44 | list_add(outputs, strdup(output)); | 44 | list_add(outputs, strdup(output)); |
45 | wlr_log(L_DEBUG, "Adding bar: '%s' to output '%s'", | 45 | wlr_log(WLR_DEBUG, "Adding bar: '%s' to output '%s'", |
46 | config->current_bar->id, output); | 46 | config->current_bar->id, output); |
47 | } | 47 | } |
48 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 48 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/bar/pango_markup.c b/sway/commands/bar/pango_markup.c index 480af724..857571fb 100644 --- a/sway/commands/bar/pango_markup.c +++ b/sway/commands/bar/pango_markup.c | |||
@@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) { | |||
13 | } | 13 | } |
14 | if (strcasecmp("enabled", argv[0]) == 0) { | 14 | if (strcasecmp("enabled", argv[0]) == 0) { |
15 | config->current_bar->pango_markup = true; | 15 | config->current_bar->pango_markup = true; |
16 | wlr_log(L_DEBUG, "Enabling pango markup for bar: %s", | 16 | wlr_log(WLR_DEBUG, "Enabling pango markup for bar: %s", |
17 | config->current_bar->id); | 17 | config->current_bar->id); |
18 | } else if (strcasecmp("disabled", argv[0]) == 0) { | 18 | } else if (strcasecmp("disabled", argv[0]) == 0) { |
19 | config->current_bar->pango_markup = false; | 19 | config->current_bar->pango_markup = false; |
20 | wlr_log(L_DEBUG, "Disabling pango markup for bar: %s", | 20 | wlr_log(WLR_DEBUG, "Disabling pango markup for bar: %s", |
21 | config->current_bar->id); | 21 | config->current_bar->id); |
22 | } else { | 22 | } else { |
23 | error = cmd_results_new(CMD_INVALID, "pango_markup", | 23 | error = cmd_results_new(CMD_INVALID, "pango_markup", |
diff --git a/sway/commands/bar/position.c b/sway/commands/bar/position.c index 9c580483..44bb4ae3 100644 --- a/sway/commands/bar/position.c +++ b/sway/commands/bar/position.c | |||
@@ -15,8 +15,9 @@ struct cmd_results *bar_cmd_position(int argc, char **argv) { | |||
15 | char *valid[] = { "top", "bottom", "left", "right" }; | 15 | char *valid[] = { "top", "bottom", "left", "right" }; |
16 | for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) { | 16 | for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) { |
17 | if (strcasecmp(valid[i], argv[0]) == 0) { | 17 | if (strcasecmp(valid[i], argv[0]) == 0) { |
18 | wlr_log(L_DEBUG, "Setting bar position '%s' for bar: %s", | 18 | wlr_log(WLR_DEBUG, "Setting bar position '%s' for bar: %s", |
19 | argv[0], config->current_bar->id); | 19 | argv[0], config->current_bar->id); |
20 | free(config->current_bar->position); | ||
20 | config->current_bar->position = strdup(argv[0]); | 21 | config->current_bar->position = strdup(argv[0]); |
21 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 22 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
22 | } | 23 | } |
diff --git a/sway/commands/bar/separator_symbol.c b/sway/commands/bar/separator_symbol.c index 1e08df6d..392ab730 100644 --- a/sway/commands/bar/separator_symbol.c +++ b/sway/commands/bar/separator_symbol.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | free(config->current_bar->separator_symbol); | 15 | free(config->current_bar->separator_symbol); |
16 | config->current_bar->separator_symbol = strdup(argv[0]); | 16 | config->current_bar->separator_symbol = strdup(argv[0]); |
17 | wlr_log(L_DEBUG, "Settings separator_symbol '%s' for bar: %s", | 17 | wlr_log(WLR_DEBUG, "Settings separator_symbol '%s' for bar: %s", |
18 | config->current_bar->separator_symbol, config->current_bar->id); | 18 | config->current_bar->separator_symbol, config->current_bar->id); |
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
20 | } | 20 | } |
diff --git a/sway/commands/bar/status_command.c b/sway/commands/bar/status_command.c index 5e199cde..6f6f81a3 100644 --- a/sway/commands/bar/status_command.c +++ b/sway/commands/bar/status_command.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | free(config->current_bar->status_command); | 15 | free(config->current_bar->status_command); |
16 | config->current_bar->status_command = join_args(argv, argc); | 16 | config->current_bar->status_command = join_args(argv, argc); |
17 | wlr_log(L_DEBUG, "Feeding bar with status command: %s", | 17 | wlr_log(WLR_DEBUG, "Feeding bar with status command: %s", |
18 | config->current_bar->status_command); | 18 | config->current_bar->status_command); |
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
20 | } | 20 | } |
diff --git a/sway/commands/bar/strip_workspace_numbers.c b/sway/commands/bar/strip_workspace_numbers.c index 4f24a356..4e47d047 100644 --- a/sway/commands/bar/strip_workspace_numbers.c +++ b/sway/commands/bar/strip_workspace_numbers.c | |||
@@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) { | |||
15 | } | 15 | } |
16 | if (strcasecmp("yes", argv[0]) == 0) { | 16 | if (strcasecmp("yes", argv[0]) == 0) { |
17 | config->current_bar->strip_workspace_numbers = true; | 17 | config->current_bar->strip_workspace_numbers = true; |
18 | wlr_log(L_DEBUG, "Stripping workspace numbers on bar: %s", | 18 | wlr_log(WLR_DEBUG, "Stripping workspace numbers on bar: %s", |
19 | config->current_bar->id); | 19 | config->current_bar->id); |
20 | } else if (strcasecmp("no", argv[0]) == 0) { | 20 | } else if (strcasecmp("no", argv[0]) == 0) { |
21 | config->current_bar->strip_workspace_numbers = false; | 21 | config->current_bar->strip_workspace_numbers = false; |
22 | wlr_log(L_DEBUG, "Enabling workspace numbers on bar: %s", | 22 | wlr_log(WLR_DEBUG, "Enabling workspace numbers on bar: %s", |
23 | config->current_bar->id); | 23 | config->current_bar->id); |
24 | } else { | 24 | } else { |
25 | return cmd_results_new(CMD_INVALID, | 25 | return cmd_results_new(CMD_INVALID, |
diff --git a/sway/commands/bar/swaybar_command.c b/sway/commands/bar/swaybar_command.c index 520cdd11..04e78e77 100644 --- a/sway/commands/bar/swaybar_command.c +++ b/sway/commands/bar/swaybar_command.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | free(config->current_bar->swaybar_command); | 15 | free(config->current_bar->swaybar_command); |
16 | config->current_bar->swaybar_command = join_args(argv, argc); | 16 | config->current_bar->swaybar_command = join_args(argv, argc); |
17 | wlr_log(L_DEBUG, "Using custom swaybar command: %s", | 17 | wlr_log(WLR_DEBUG, "Using custom swaybar command: %s", |
18 | config->current_bar->swaybar_command); | 18 | config->current_bar->swaybar_command); |
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
20 | } | 20 | } |
diff --git a/sway/commands/bar/workspace_buttons.c b/sway/commands/bar/workspace_buttons.c index 6edc3a0d..a4079b2a 100644 --- a/sway/commands/bar/workspace_buttons.c +++ b/sway/commands/bar/workspace_buttons.c | |||
@@ -14,11 +14,11 @@ struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | if (strcasecmp("yes", argv[0]) == 0) { | 15 | if (strcasecmp("yes", argv[0]) == 0) { |
16 | config->current_bar->workspace_buttons = true; | 16 | config->current_bar->workspace_buttons = true; |
17 | wlr_log(L_DEBUG, "Enabling workspace buttons on bar: %s", | 17 | wlr_log(WLR_DEBUG, "Enabling workspace buttons on bar: %s", |
18 | config->current_bar->id); | 18 | config->current_bar->id); |
19 | } else if (strcasecmp("no", argv[0]) == 0) { | 19 | } else if (strcasecmp("no", argv[0]) == 0) { |
20 | config->current_bar->workspace_buttons = false; | 20 | config->current_bar->workspace_buttons = false; |
21 | wlr_log(L_DEBUG, "Disabling workspace buttons on bar: %s", | 21 | wlr_log(WLR_DEBUG, "Disabling workspace buttons on bar: %s", |
22 | config->current_bar->id); | 22 | config->current_bar->id); |
23 | } else { | 23 | } else { |
24 | return cmd_results_new(CMD_INVALID, "workspace_buttons", | 24 | return cmd_results_new(CMD_INVALID, "workspace_buttons", |
diff --git a/sway/commands/bar/wrap_scroll.c b/sway/commands/bar/wrap_scroll.c index 7386f82c..701de00a 100644 --- a/sway/commands/bar/wrap_scroll.c +++ b/sway/commands/bar/wrap_scroll.c | |||
@@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) { | |||
13 | } | 13 | } |
14 | if (strcasecmp("yes", argv[0]) == 0) { | 14 | if (strcasecmp("yes", argv[0]) == 0) { |
15 | config->current_bar->wrap_scroll = true; | 15 | config->current_bar->wrap_scroll = true; |
16 | wlr_log(L_DEBUG, "Enabling wrap scroll on bar: %s", | 16 | wlr_log(WLR_DEBUG, "Enabling wrap scroll on bar: %s", |
17 | config->current_bar->id); | 17 | config->current_bar->id); |
18 | } else if (strcasecmp("no", argv[0]) == 0) { | 18 | } else if (strcasecmp("no", argv[0]) == 0) { |
19 | config->current_bar->wrap_scroll = false; | 19 | config->current_bar->wrap_scroll = false; |
20 | wlr_log(L_DEBUG, "Disabling wrap scroll on bar: %s", | 20 | wlr_log(WLR_DEBUG, "Disabling wrap scroll on bar: %s", |
21 | config->current_bar->id); | 21 | config->current_bar->id); |
22 | } else { | 22 | } else { |
23 | return cmd_results_new(CMD_INVALID, | 23 | return cmd_results_new(CMD_INVALID, |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 821f9cd1..83e9e432 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -184,7 +184,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
184 | for (int i = 0; i < mode_bindings->length; ++i) { | 184 | for (int i = 0; i < mode_bindings->length; ++i) { |
185 | struct sway_binding *config_binding = mode_bindings->items[i]; | 185 | struct sway_binding *config_binding = mode_bindings->items[i]; |
186 | if (binding_key_compare(binding, config_binding)) { | 186 | if (binding_key_compare(binding, config_binding)) { |
187 | wlr_log(L_DEBUG, "overwriting old binding with command '%s'", | 187 | wlr_log(WLR_DEBUG, "overwriting old binding with command '%s'", |
188 | config_binding->command); | 188 | config_binding->command); |
189 | free_sway_binding(config_binding); | 189 | free_sway_binding(config_binding); |
190 | mode_bindings->items[i] = binding; | 190 | mode_bindings->items[i] = binding; |
@@ -196,7 +196,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
196 | list_add(mode_bindings, binding); | 196 | list_add(mode_bindings, binding); |
197 | } | 197 | } |
198 | 198 | ||
199 | wlr_log(L_DEBUG, "%s - Bound %s to command %s", | 199 | wlr_log(WLR_DEBUG, "%s - Bound %s to command %s", |
200 | bindtype, argv[0], binding->command); | 200 | bindtype, argv[0], binding->command); |
201 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 201 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
202 | 202 | ||
diff --git a/sway/commands/border.c b/sway/commands/border.c index 6db85395..9c19e20a 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c | |||
@@ -42,7 +42,7 @@ struct cmd_results *cmd_border(int argc, char **argv) { | |||
42 | container_set_geometry_from_floating_view(view->swayc); | 42 | container_set_geometry_from_floating_view(view->swayc); |
43 | } | 43 | } |
44 | 44 | ||
45 | arrange_and_commit(view->swayc); | 45 | arrange_windows(view->swayc); |
46 | 46 | ||
47 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 47 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
48 | if (seat->cursor) { | 48 | if (seat->cursor) { |
diff --git a/sway/commands/default_floating_border.c b/sway/commands/default_floating_border.c new file mode 100644 index 00000000..1bfc24af --- /dev/null +++ b/sway/commands/default_floating_border.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include "log.h" | ||
2 | #include "sway/commands.h" | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/tree/container.h" | ||
5 | |||
6 | struct cmd_results *cmd_default_floating_border(int argc, char **argv) { | ||
7 | struct cmd_results *error = NULL; | ||
8 | if ((error = checkarg(argc, "default_floating_border", | ||
9 | EXPECTED_AT_LEAST, 1))) { | ||
10 | return error; | ||
11 | } | ||
12 | |||
13 | if (strcmp(argv[0], "none") == 0) { | ||
14 | config->floating_border = B_NONE; | ||
15 | } else if (strcmp(argv[0], "normal") == 0) { | ||
16 | config->floating_border = B_NORMAL; | ||
17 | } else if (strcmp(argv[0], "pixel") == 0) { | ||
18 | config->floating_border = B_PIXEL; | ||
19 | } else { | ||
20 | return cmd_results_new(CMD_INVALID, "default_floating_border", | ||
21 | "Expected 'default_floating_border <none|normal|pixel>' " | ||
22 | "or 'default_floating_border <normal|pixel> <px>'"); | ||
23 | } | ||
24 | if (argc == 2) { | ||
25 | config->floating_border_thickness = atoi(argv[1]); | ||
26 | } | ||
27 | |||
28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
29 | } | ||
diff --git a/sway/commands/exec.c b/sway/commands/exec.c index 363d5bef..7fc54123 100644 --- a/sway/commands/exec.c +++ b/sway/commands/exec.c | |||
@@ -8,7 +8,7 @@ struct cmd_results *cmd_exec(int argc, char **argv) { | |||
8 | if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL); | 8 | if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL); |
9 | if (config->reloading) { | 9 | if (config->reloading) { |
10 | char *args = join_args(argv, argc); | 10 | char *args = join_args(argv, argc); |
11 | wlr_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args); | 11 | wlr_log(WLR_DEBUG, "Ignoring 'exec %s' due to reload", args); |
12 | free(args); | 12 | free(args); |
13 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 13 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
14 | } | 14 | } |
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index abd52e59..9bf2b320 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c | |||
@@ -20,7 +20,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { | |||
20 | 20 | ||
21 | char *tmp = NULL; | 21 | char *tmp = NULL; |
22 | if (strcmp((char*)*argv, "--no-startup-id") == 0) { | 22 | if (strcmp((char*)*argv, "--no-startup-id") == 0) { |
23 | wlr_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored."); | 23 | wlr_log(WLR_INFO, "exec switch '--no-startup-id' not supported, ignored."); |
24 | if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { | 24 | if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { |
25 | return error; | 25 | return error; |
26 | } | 26 | } |
@@ -35,50 +35,49 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { | |||
35 | strncpy(cmd, tmp, sizeof(cmd) - 1); | 35 | strncpy(cmd, tmp, sizeof(cmd) - 1); |
36 | cmd[sizeof(cmd) - 1] = 0; | 36 | cmd[sizeof(cmd) - 1] = 0; |
37 | free(tmp); | 37 | free(tmp); |
38 | wlr_log(L_DEBUG, "Executing %s", cmd); | 38 | wlr_log(WLR_DEBUG, "Executing %s", cmd); |
39 | 39 | ||
40 | int fd[2]; | 40 | int fd[2]; |
41 | if (pipe(fd) != 0) { | 41 | if (pipe(fd) != 0) { |
42 | wlr_log(L_ERROR, "Unable to create pipe for fork"); | 42 | wlr_log(WLR_ERROR, "Unable to create pipe for fork"); |
43 | } | 43 | } |
44 | 44 | ||
45 | pid_t pid; | 45 | pid_t pid, child; |
46 | pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space | ||
47 | if (!child) { | ||
48 | return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid"); | ||
49 | } | ||
50 | // Fork process | 46 | // Fork process |
51 | if ((pid = fork()) == 0) { | 47 | if ((pid = fork()) == 0) { |
52 | // Fork child process again | 48 | // Fork child process again |
53 | setsid(); | 49 | setsid(); |
54 | if ((*child = fork()) == 0) { | 50 | close(fd[0]); |
51 | if ((child = fork()) == 0) { | ||
52 | close(fd[1]); | ||
55 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); | 53 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); |
56 | // Not reached | 54 | _exit(0); |
57 | } | 55 | } |
58 | close(fd[0]); | ||
59 | ssize_t s = 0; | 56 | ssize_t s = 0; |
60 | while ((size_t)s < sizeof(pid_t)) { | 57 | while ((size_t)s < sizeof(pid_t)) { |
61 | s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s); | 58 | s += write(fd[1], ((uint8_t *)&child) + s, sizeof(pid_t) - s); |
62 | } | 59 | } |
63 | close(fd[1]); | 60 | close(fd[1]); |
64 | _exit(0); // Close child process | 61 | _exit(0); // Close child process |
65 | } else if (pid < 0) { | 62 | } else if (pid < 0) { |
66 | free(child); | 63 | close(fd[0]); |
64 | close(fd[1]); | ||
67 | return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); | 65 | return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); |
68 | } | 66 | } |
69 | close(fd[1]); // close write | 67 | close(fd[1]); // close write |
70 | ssize_t s = 0; | 68 | ssize_t s = 0; |
71 | while ((size_t)s < sizeof(pid_t)) { | 69 | while ((size_t)s < sizeof(pid_t)) { |
72 | s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s); | 70 | s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s); |
73 | } | 71 | } |
74 | close(fd[0]); | 72 | close(fd[0]); |
75 | // cleanup child process | 73 | // cleanup child process |
76 | waitpid(pid, NULL, 0); | 74 | waitpid(pid, NULL, 0); |
77 | if (*child > 0) { | 75 | if (child > 0) { |
78 | wlr_log(L_DEBUG, "Child process created with pid %d", *child); | 76 | wlr_log(WLR_DEBUG, "Child process created with pid %d", child); |
79 | workspace_record_pid(*child); | 77 | workspace_record_pid(child); |
80 | } else { | 78 | } else { |
81 | free(child); | 79 | return cmd_results_new(CMD_FAILURE, "exec_always", |
80 | "Second fork() failed"); | ||
82 | } | 81 | } |
83 | 82 | ||
84 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 83 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/floating.c b/sway/commands/floating.c index e6003521..6ab56c3b 100644 --- a/sway/commands/floating.c +++ b/sway/commands/floating.c | |||
@@ -37,7 +37,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) { | |||
37 | container_set_floating(container, wants_floating); | 37 | container_set_floating(container, wants_floating); |
38 | 38 | ||
39 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); | 39 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); |
40 | arrange_and_commit(workspace); | 40 | arrange_windows(workspace); |
41 | 41 | ||
42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
43 | } | 43 | } |
diff --git a/sway/commands/floating_minmax_size.c b/sway/commands/floating_minmax_size.c new file mode 100644 index 00000000..0af78908 --- /dev/null +++ b/sway/commands/floating_minmax_size.c | |||
@@ -0,0 +1,53 @@ | |||
1 | #include <errno.h> | ||
2 | #include <math.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <strings.h> | ||
7 | #include <wlr/util/log.h> | ||
8 | #include "sway/commands.h" | ||
9 | #include "log.h" | ||
10 | |||
11 | static const char* min_usage = | ||
12 | "Expected 'floating_minimum_size <width> x <height>'"; | ||
13 | |||
14 | static const char* max_usage = | ||
15 | "Expected 'floating_maximum_size <width> x <height>'"; | ||
16 | |||
17 | static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | ||
18 | const char *usage, int *config_width, int *config_height) { | ||
19 | struct cmd_results *error; | ||
20 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 3))) { | ||
21 | return error; | ||
22 | } | ||
23 | |||
24 | char *err; | ||
25 | int width = (int)strtol(argv[0], &err, 10); | ||
26 | if (*err) { | ||
27 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | ||
28 | } | ||
29 | |||
30 | if (strcmp(argv[1], "x") != 0) { | ||
31 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | ||
32 | } | ||
33 | |||
34 | int height = (int)strtol(argv[2], &err, 10); | ||
35 | if (*err) { | ||
36 | return cmd_results_new(CMD_INVALID, cmd_name, usage); | ||
37 | } | ||
38 | |||
39 | *config_width = width; | ||
40 | *config_height = height; | ||
41 | |||
42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
43 | } | ||
44 | |||
45 | struct cmd_results *cmd_floating_minimum_size(int argc, char **argv) { | ||
46 | return handle_command(argc, argv, "floating_minimum_size", min_usage, | ||
47 | &config->floating_minimum_width, &config->floating_minimum_height); | ||
48 | } | ||
49 | |||
50 | struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) { | ||
51 | return handle_command(argc, argv, "floating_maximum_size", max_usage, | ||
52 | &config->floating_maximum_width, &config->floating_maximum_height); | ||
53 | } | ||
diff --git a/sway/commands/floating_modifier.c b/sway/commands/floating_modifier.c new file mode 100644 index 00000000..9432c9f1 --- /dev/null +++ b/sway/commands/floating_modifier.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include "sway/commands.h" | ||
2 | #include "sway/config.h" | ||
3 | #include "util.h" | ||
4 | |||
5 | struct cmd_results *cmd_floating_modifier(int argc, char **argv) { | ||
6 | struct cmd_results *error = NULL; | ||
7 | if ((error = checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1))) { | ||
8 | return error; | ||
9 | } | ||
10 | |||
11 | uint32_t mod = get_modifier_mask_by_name(argv[0]); | ||
12 | if (!mod) { | ||
13 | return cmd_results_new(CMD_INVALID, "floating_modifier", | ||
14 | "Invalid modifier"); | ||
15 | } | ||
16 | |||
17 | config->floating_mod = mod; | ||
18 | |||
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
20 | } | ||
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 74d9d535..9cd8bfae 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -1,10 +1,14 @@ | |||
1 | #include <strings.h> | 1 | #include <strings.h> |
2 | #include <wlr/util/log.h> | 2 | #include <wlr/util/log.h> |
3 | #include "log.h" | 3 | #include "log.h" |
4 | #include "sway/commands.h" | ||
4 | #include "sway/input/input-manager.h" | 5 | #include "sway/input/input-manager.h" |
5 | #include "sway/input/seat.h" | 6 | #include "sway/input/seat.h" |
7 | #include "sway/output.h" | ||
8 | #include "sway/tree/arrange.h" | ||
6 | #include "sway/tree/view.h" | 9 | #include "sway/tree/view.h" |
7 | #include "sway/commands.h" | 10 | #include "sway/tree/workspace.h" |
11 | #include "stringop.h" | ||
8 | 12 | ||
9 | static bool parse_movement_direction(const char *name, | 13 | static bool parse_movement_direction(const char *name, |
10 | enum movement_direction *out) { | 14 | enum movement_direction *out) { |
@@ -27,7 +31,55 @@ static bool parse_movement_direction(const char *name, | |||
27 | return true; | 31 | return true; |
28 | } | 32 | } |
29 | 33 | ||
34 | static struct cmd_results *focus_mode(struct sway_container *con, | ||
35 | struct sway_seat *seat, bool floating) { | ||
36 | struct sway_container *ws = con->type == C_WORKSPACE ? | ||
37 | con : container_parent(con, C_WORKSPACE); | ||
38 | struct sway_container *new_focus = ws; | ||
39 | if (floating) { | ||
40 | new_focus = ws->sway_workspace->floating; | ||
41 | if (new_focus->children->length == 0) { | ||
42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
43 | } | ||
44 | } | ||
45 | seat_set_focus(seat, seat_get_active_child(seat, new_focus)); | ||
46 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
47 | } | ||
48 | |||
49 | static struct cmd_results *focus_output(struct sway_container *con, | ||
50 | struct sway_seat *seat, int argc, char **argv) { | ||
51 | if (!argc) { | ||
52 | return cmd_results_new(CMD_INVALID, "focus", | ||
53 | "Expected 'focus output <direction|name>'"); | ||
54 | } | ||
55 | char *identifier = join_args(argv, argc); | ||
56 | struct sway_container *output = output_by_name(identifier); | ||
57 | |||
58 | if (!output) { | ||
59 | enum movement_direction direction; | ||
60 | if (!parse_movement_direction(identifier, &direction) || | ||
61 | direction == MOVE_PARENT || direction == MOVE_CHILD) { | ||
62 | free(identifier); | ||
63 | return cmd_results_new(CMD_INVALID, "focus", | ||
64 | "There is no output with that name"); | ||
65 | } | ||
66 | struct sway_container *focus = seat_get_focus(seat); | ||
67 | focus = container_parent(focus, C_OUTPUT); | ||
68 | output = container_get_in_direction(focus, seat, direction); | ||
69 | } | ||
70 | |||
71 | free(identifier); | ||
72 | if (output) { | ||
73 | seat_set_focus(seat, seat_get_focus_inactive(seat, output)); | ||
74 | } | ||
75 | |||
76 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
77 | } | ||
78 | |||
30 | struct cmd_results *cmd_focus(int argc, char **argv) { | 79 | struct cmd_results *cmd_focus(int argc, char **argv) { |
80 | if (config->reading || !config->active) { | ||
81 | return cmd_results_new(CMD_DEFER, NULL, NULL); | ||
82 | } | ||
31 | struct sway_container *con = config->handler_context.current_container; | 83 | struct sway_container *con = config->handler_context.current_container; |
32 | struct sway_seat *seat = config->handler_context.seat; | 84 | struct sway_seat *seat = config->handler_context.seat; |
33 | if (con->type < C_WORKSPACE) { | 85 | if (con->type < C_WORKSPACE) { |
@@ -40,11 +92,24 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
40 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 92 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
41 | } | 93 | } |
42 | 94 | ||
43 | // TODO mode_toggle | 95 | if (strcmp(argv[0], "floating") == 0) { |
96 | return focus_mode(con, seat, true); | ||
97 | } else if (strcmp(argv[0], "tiling") == 0) { | ||
98 | return focus_mode(con, seat, false); | ||
99 | } else if (strcmp(argv[0], "mode_toggle") == 0) { | ||
100 | return focus_mode(con, seat, !container_is_floating(con)); | ||
101 | } | ||
102 | |||
103 | if (strcmp(argv[0], "output") == 0) { | ||
104 | argc--; argv++; | ||
105 | return focus_output(con, seat, argc, argv); | ||
106 | } | ||
107 | |||
44 | enum movement_direction direction = 0; | 108 | enum movement_direction direction = 0; |
45 | if (!parse_movement_direction(argv[0], &direction)) { | 109 | if (!parse_movement_direction(argv[0], &direction)) { |
46 | return cmd_results_new(CMD_INVALID, "focus", | 110 | return cmd_results_new(CMD_INVALID, "focus", |
47 | "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'"); | 111 | "Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " |
112 | "or 'focus output <direction|name>'"); | ||
48 | } | 113 | } |
49 | 114 | ||
50 | struct sway_container *next_focus = container_get_in_direction( | 115 | struct sway_container *next_focus = container_get_in_direction( |
diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index 8c425a1d..ac4d6563 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c | |||
@@ -24,7 +24,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { | |||
24 | criteria->cmdlist = join_args(argv + 1, argc - 1); | 24 | criteria->cmdlist = join_args(argv + 1, argc - 1); |
25 | 25 | ||
26 | list_add(config->criteria, criteria); | 26 | list_add(config->criteria, criteria); |
27 | wlr_log(L_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist); | 27 | wlr_log(WLR_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist); |
28 | 28 | ||
29 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 29 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
30 | } | 30 | } |
diff --git a/sway/commands/force_display_urgency_hint.c b/sway/commands/force_display_urgency_hint.c new file mode 100644 index 00000000..5e5e2d55 --- /dev/null +++ b/sway/commands/force_display_urgency_hint.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include "sway/commands.h" | ||
2 | #include "sway/config.h" | ||
3 | |||
4 | struct cmd_results *cmd_force_display_urgency_hint(int argc, char **argv) { | ||
5 | struct cmd_results *error = NULL; | ||
6 | if ((error = checkarg(argc, "force_display_urgency_hint", | ||
7 | EXPECTED_AT_LEAST, 1))) { | ||
8 | return error; | ||
9 | } | ||
10 | |||
11 | char *err; | ||
12 | int timeout = (int)strtol(argv[0], &err, 10); | ||
13 | if (*err) { | ||
14 | if (strcmp(err, "ms") != 0) { | ||
15 | return cmd_results_new(CMD_INVALID, "force_display_urgency_hint", | ||
16 | "Expected 'force_display_urgency_hint <timeout> ms'"); | ||
17 | } | ||
18 | } | ||
19 | |||
20 | config->urgent_timeout = timeout > 0 ? timeout : 0; | ||
21 | |||
22 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
23 | } | ||
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index 1a4d8b41..0b5beaa2 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c | |||
@@ -34,7 +34,7 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
34 | view_set_fullscreen(view, wants_fullscreen); | 34 | view_set_fullscreen(view, wants_fullscreen); |
35 | 35 | ||
36 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); | 36 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); |
37 | arrange_and_commit(workspace->parent); | 37 | arrange_windows(workspace->parent); |
38 | 38 | ||
39 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 39 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
40 | } | 40 | } |
diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c index 801fb179..3906eb70 100644 --- a/sway/commands/gaps.c +++ b/sway/commands/gaps.c | |||
@@ -43,7 +43,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { | |||
43 | return cmd_results_new(CMD_INVALID, "gaps", | 43 | return cmd_results_new(CMD_INVALID, "gaps", |
44 | "gaps edge_gaps on|off|toggle"); | 44 | "gaps edge_gaps on|off|toggle"); |
45 | } | 45 | } |
46 | arrange_and_commit(&root_container); | 46 | arrange_windows(&root_container); |
47 | } else { | 47 | } else { |
48 | int amount_idx = 0; // the current index in argv | 48 | int amount_idx = 0; // the current index in argv |
49 | enum gaps_op op = GAPS_OP_SET; | 49 | enum gaps_op op = GAPS_OP_SET; |
@@ -124,7 +124,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { | |||
124 | if (amount_idx == 0) { // gaps <amount> | 124 | if (amount_idx == 0) { // gaps <amount> |
125 | config->gaps_inner = val; | 125 | config->gaps_inner = val; |
126 | config->gaps_outer = val; | 126 | config->gaps_outer = val; |
127 | arrange_and_commit(&root_container); | 127 | arrange_windows(&root_container); |
128 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 128 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
129 | } | 129 | } |
130 | // Other variants. The middle-length variant (gaps inner|outer <amount>) | 130 | // Other variants. The middle-length variant (gaps inner|outer <amount>) |
@@ -155,7 +155,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { | |||
155 | } else { | 155 | } else { |
156 | config->gaps_outer = total; | 156 | config->gaps_outer = total; |
157 | } | 157 | } |
158 | arrange_and_commit(&root_container); | 158 | arrange_windows(&root_container); |
159 | } else { | 159 | } else { |
160 | struct sway_container *c = | 160 | struct sway_container *c = |
161 | config->handler_context.current_container; | 161 | config->handler_context.current_container; |
@@ -169,7 +169,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { | |||
169 | c->gaps_outer = total; | 169 | c->gaps_outer = total; |
170 | } | 170 | } |
171 | 171 | ||
172 | arrange_and_commit(c->parent ? c->parent : &root_container); | 172 | arrange_windows(c->parent ? c->parent : &root_container); |
173 | } | 173 | } |
174 | } | 174 | } |
175 | 175 | ||
diff --git a/sway/commands/input.c b/sway/commands/input.c index 678c57c4..5b203ea0 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c | |||
@@ -20,8 +20,10 @@ static struct cmd_handler input_handlers[] = { | |||
20 | { "pointer_accel", input_cmd_pointer_accel }, | 20 | { "pointer_accel", input_cmd_pointer_accel }, |
21 | { "repeat_delay", input_cmd_repeat_delay }, | 21 | { "repeat_delay", input_cmd_repeat_delay }, |
22 | { "repeat_rate", input_cmd_repeat_rate }, | 22 | { "repeat_rate", input_cmd_repeat_rate }, |
23 | { "scroll_button", input_cmd_scroll_button }, | ||
23 | { "scroll_method", input_cmd_scroll_method }, | 24 | { "scroll_method", input_cmd_scroll_method }, |
24 | { "tap", input_cmd_tap }, | 25 | { "tap", input_cmd_tap }, |
26 | { "tap_button_map", input_cmd_tap_button_map }, | ||
25 | { "xkb_layout", input_cmd_xkb_layout }, | 27 | { "xkb_layout", input_cmd_xkb_layout }, |
26 | { "xkb_model", input_cmd_xkb_model }, | 28 | { "xkb_model", input_cmd_xkb_model }, |
27 | { "xkb_options", input_cmd_xkb_options }, | 29 | { "xkb_options", input_cmd_xkb_options }, |
@@ -35,7 +37,7 @@ struct cmd_results *cmd_input(int argc, char **argv) { | |||
35 | return error; | 37 | return error; |
36 | } | 38 | } |
37 | 39 | ||
38 | wlr_log(L_DEBUG, "entering input block: %s", argv[0]); | 40 | wlr_log(WLR_DEBUG, "entering input block: %s", argv[0]); |
39 | 41 | ||
40 | config->handler_context.input_config = new_input_config(argv[0]); | 42 | config->handler_context.input_config = new_input_config(argv[0]); |
41 | if (!config->handler_context.input_config) { | 43 | if (!config->handler_context.input_config) { |
diff --git a/sway/commands/input/accel_profile.c b/sway/commands/input/accel_profile.c index 37d6e133..a4108ec3 100644 --- a/sway/commands/input/accel_profile.c +++ b/sway/commands/input/accel_profile.c | |||
@@ -23,6 +23,7 @@ struct cmd_results *input_cmd_accel_profile(int argc, char **argv) { | |||
23 | } else if (strcasecmp(argv[0], "flat") == 0) { | 23 | } else if (strcasecmp(argv[0], "flat") == 0) { |
24 | new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; | 24 | new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; |
25 | } else { | 25 | } else { |
26 | free_input_config(new_config); | ||
26 | return cmd_results_new(CMD_INVALID, "accel_profile", | 27 | return cmd_results_new(CMD_INVALID, "accel_profile", |
27 | "Expected 'accel_profile <adaptive|flat>'"); | 28 | "Expected 'accel_profile <adaptive|flat>'"); |
28 | } | 29 | } |
diff --git a/sway/commands/input/click_method.c b/sway/commands/input/click_method.c index 8f1f0aa7..5d0d8cc2 100644 --- a/sway/commands/input/click_method.c +++ b/sway/commands/input/click_method.c | |||
@@ -26,6 +26,7 @@ struct cmd_results *input_cmd_click_method(int argc, char **argv) { | |||
26 | } else if (strcasecmp(argv[0], "clickfinger") == 0) { | 26 | } else if (strcasecmp(argv[0], "clickfinger") == 0) { |
27 | new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; | 27 | new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; |
28 | } else { | 28 | } else { |
29 | free_input_config(new_config); | ||
29 | return cmd_results_new(CMD_INVALID, "click_method", | 30 | return cmd_results_new(CMD_INVALID, "click_method", |
30 | "Expected 'click_method <none|button_areas|clickfinger'"); | 31 | "Expected 'click_method <none|button_areas|clickfinger'"); |
31 | } | 32 | } |
diff --git a/sway/commands/input/drag_lock.c b/sway/commands/input/drag_lock.c index 8273a7d4..9e32816f 100644 --- a/sway/commands/input/drag_lock.c +++ b/sway/commands/input/drag_lock.c | |||
@@ -23,6 +23,7 @@ struct cmd_results *input_cmd_drag_lock(int argc, char **argv) { | |||
23 | } else if (strcasecmp(argv[0], "disabled") == 0) { | 23 | } else if (strcasecmp(argv[0], "disabled") == 0) { |
24 | new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; | 24 | new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; |
25 | } else { | 25 | } else { |
26 | free_input_config(new_config); | ||
26 | return cmd_results_new(CMD_INVALID, "drag_lock", | 27 | return cmd_results_new(CMD_INVALID, "drag_lock", |
27 | "Expected 'drag_lock <enabled|disabled>'"); | 28 | "Expected 'drag_lock <enabled|disabled>'"); |
28 | } | 29 | } |
diff --git a/sway/commands/input/dwt.c b/sway/commands/input/dwt.c index 995a2f47..73937507 100644 --- a/sway/commands/input/dwt.c +++ b/sway/commands/input/dwt.c | |||
@@ -22,6 +22,7 @@ struct cmd_results *input_cmd_dwt(int argc, char **argv) { | |||
22 | } else if (strcasecmp(argv[0], "disabled") == 0) { | 22 | } else if (strcasecmp(argv[0], "disabled") == 0) { |
23 | new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED; | 23 | new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED; |
24 | } else { | 24 | } else { |
25 | free_input_config(new_config); | ||
25 | return cmd_results_new(CMD_INVALID, "dwt", | 26 | return cmd_results_new(CMD_INVALID, "dwt", |
26 | "Expected 'dwt <enabled|disabled>'"); | 27 | "Expected 'dwt <enabled|disabled>'"); |
27 | } | 28 | } |
diff --git a/sway/commands/input/events.c b/sway/commands/input/events.c index 2217f5ce..abfe3b12 100644 --- a/sway/commands/input/events.c +++ b/sway/commands/input/events.c | |||
@@ -16,7 +16,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) { | |||
16 | return cmd_results_new(CMD_FAILURE, "events", | 16 | return cmd_results_new(CMD_FAILURE, "events", |
17 | "No input device defined."); | 17 | "No input device defined."); |
18 | } | 18 | } |
19 | wlr_log(L_DEBUG, "events for device: %s", | 19 | wlr_log(WLR_DEBUG, "events for device: %s", |
20 | current_input_config->identifier); | 20 | current_input_config->identifier); |
21 | struct input_config *new_config = | 21 | struct input_config *new_config = |
22 | new_input_config(current_input_config->identifier); | 22 | new_input_config(current_input_config->identifier); |
@@ -29,6 +29,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) { | |||
29 | new_config->send_events = | 29 | new_config->send_events = |
30 | LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; | 30 | LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; |
31 | } else { | 31 | } else { |
32 | free_input_config(new_config); | ||
32 | return cmd_results_new(CMD_INVALID, "events", | 33 | return cmd_results_new(CMD_INVALID, "events", |
33 | "Expected 'events <enabled|disabled|disabled_on_external_mouse>'"); | 34 | "Expected 'events <enabled|disabled|disabled_on_external_mouse>'"); |
34 | } | 35 | } |
diff --git a/sway/commands/input/left_handed.c b/sway/commands/input/left_handed.c index 94b8e03e..769ce98c 100644 --- a/sway/commands/input/left_handed.c +++ b/sway/commands/input/left_handed.c | |||
@@ -23,6 +23,7 @@ struct cmd_results *input_cmd_left_handed(int argc, char **argv) { | |||
23 | } else if (strcasecmp(argv[0], "disabled") == 0) { | 23 | } else if (strcasecmp(argv[0], "disabled") == 0) { |
24 | new_config->left_handed = 0; | 24 | new_config->left_handed = 0; |
25 | } else { | 25 | } else { |
26 | free_input_config(new_config); | ||
26 | return cmd_results_new(CMD_INVALID, "left_handed", | 27 | return cmd_results_new(CMD_INVALID, "left_handed", |
27 | "Expected 'left_handed <enabled|disabled>'"); | 28 | "Expected 'left_handed <enabled|disabled>'"); |
28 | } | 29 | } |
diff --git a/sway/commands/input/map_from_region.c b/sway/commands/input/map_from_region.c index 80bb856d..40f04214 100644 --- a/sway/commands/input/map_from_region.c +++ b/sway/commands/input/map_from_region.c | |||
@@ -54,20 +54,28 @@ struct cmd_results *input_cmd_map_from_region(int argc, char **argv) { | |||
54 | bool mm1, mm2; | 54 | bool mm1, mm2; |
55 | if (!parse_coords(argv[0], &new_config->mapped_from_region->x1, | 55 | if (!parse_coords(argv[0], &new_config->mapped_from_region->x1, |
56 | &new_config->mapped_from_region->y1, &mm1)) { | 56 | &new_config->mapped_from_region->y1, &mm1)) { |
57 | free(new_config->mapped_from_region); | ||
58 | free_input_config(new_config); | ||
57 | return cmd_results_new(CMD_FAILURE, "map_from_region", | 59 | return cmd_results_new(CMD_FAILURE, "map_from_region", |
58 | "Invalid top-left coordinates"); | 60 | "Invalid top-left coordinates"); |
59 | } | 61 | } |
60 | if (!parse_coords(argv[1], &new_config->mapped_from_region->x2, | 62 | if (!parse_coords(argv[1], &new_config->mapped_from_region->x2, |
61 | &new_config->mapped_from_region->y2, &mm2)) { | 63 | &new_config->mapped_from_region->y2, &mm2)) { |
64 | free(new_config->mapped_from_region); | ||
65 | free_input_config(new_config); | ||
62 | return cmd_results_new(CMD_FAILURE, "map_from_region", | 66 | return cmd_results_new(CMD_FAILURE, "map_from_region", |
63 | "Invalid bottom-right coordinates"); | 67 | "Invalid bottom-right coordinates"); |
64 | } | 68 | } |
65 | if (new_config->mapped_from_region->x1 > new_config->mapped_from_region->x2 || | 69 | if (new_config->mapped_from_region->x1 > new_config->mapped_from_region->x2 || |
66 | new_config->mapped_from_region->y1 > new_config->mapped_from_region->y2) { | 70 | new_config->mapped_from_region->y1 > new_config->mapped_from_region->y2) { |
71 | free(new_config->mapped_from_region); | ||
72 | free_input_config(new_config); | ||
67 | return cmd_results_new(CMD_FAILURE, "map_from_region", | 73 | return cmd_results_new(CMD_FAILURE, "map_from_region", |
68 | "Invalid rectangle"); | 74 | "Invalid rectangle"); |
69 | } | 75 | } |
70 | if (mm1 != mm2) { | 76 | if (mm1 != mm2) { |
77 | free(new_config->mapped_from_region); | ||
78 | free_input_config(new_config); | ||
71 | return cmd_results_new(CMD_FAILURE, "map_from_region", | 79 | return cmd_results_new(CMD_FAILURE, "map_from_region", |
72 | "Both coordinates must be in the same unit"); | 80 | "Both coordinates must be in the same unit"); |
73 | } | 81 | } |
diff --git a/sway/commands/input/middle_emulation.c b/sway/commands/input/middle_emulation.c index a551fd51..7ca01629 100644 --- a/sway/commands/input/middle_emulation.c +++ b/sway/commands/input/middle_emulation.c | |||
@@ -24,6 +24,7 @@ struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) { | |||
24 | new_config->middle_emulation = | 24 | new_config->middle_emulation = |
25 | LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; | 25 | LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; |
26 | } else { | 26 | } else { |
27 | free_input_config(new_config); | ||
27 | return cmd_results_new(CMD_INVALID, "middle_emulation", | 28 | return cmd_results_new(CMD_INVALID, "middle_emulation", |
28 | "Expected 'middle_emulation <enabled|disabled>'"); | 29 | "Expected 'middle_emulation <enabled|disabled>'"); |
29 | } | 30 | } |
diff --git a/sway/commands/input/natural_scroll.c b/sway/commands/input/natural_scroll.c index c4e19b78..55236790 100644 --- a/sway/commands/input/natural_scroll.c +++ b/sway/commands/input/natural_scroll.c | |||
@@ -23,6 +23,7 @@ struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) { | |||
23 | } else if (strcasecmp(argv[0], "disabled") == 0) { | 23 | } else if (strcasecmp(argv[0], "disabled") == 0) { |
24 | new_config->natural_scroll = 0; | 24 | new_config->natural_scroll = 0; |
25 | } else { | 25 | } else { |
26 | free_input_config(new_config); | ||
26 | return cmd_results_new(CMD_INVALID, "natural_scroll", | 27 | return cmd_results_new(CMD_INVALID, "natural_scroll", |
27 | "Expected 'natural_scroll <enabled|disabled>'"); | 28 | "Expected 'natural_scroll <enabled|disabled>'"); |
28 | } | 29 | } |
diff --git a/sway/commands/input/pointer_accel.c b/sway/commands/input/pointer_accel.c index 171063aa..8bbd0724 100644 --- a/sway/commands/input/pointer_accel.c +++ b/sway/commands/input/pointer_accel.c | |||
@@ -20,6 +20,7 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) { | |||
20 | 20 | ||
21 | float pointer_accel = atof(argv[0]); | 21 | float pointer_accel = atof(argv[0]); |
22 | if (pointer_accel < -1 || pointer_accel > 1) { | 22 | if (pointer_accel < -1 || pointer_accel > 1) { |
23 | free_input_config(new_config); | ||
23 | return cmd_results_new(CMD_INVALID, "pointer_accel", | 24 | return cmd_results_new(CMD_INVALID, "pointer_accel", |
24 | "Input out of range [-1, 1]"); | 25 | "Input out of range [-1, 1]"); |
25 | } | 26 | } |
diff --git a/sway/commands/input/repeat_delay.c b/sway/commands/input/repeat_delay.c index ce265841..c9ddbf0e 100644 --- a/sway/commands/input/repeat_delay.c +++ b/sway/commands/input/repeat_delay.c | |||
@@ -20,6 +20,7 @@ struct cmd_results *input_cmd_repeat_delay(int argc, char **argv) { | |||
20 | 20 | ||
21 | int repeat_delay = atoi(argv[0]); | 21 | int repeat_delay = atoi(argv[0]); |
22 | if (repeat_delay < 0) { | 22 | if (repeat_delay < 0) { |
23 | free_input_config(new_config); | ||
23 | return cmd_results_new(CMD_INVALID, "repeat_delay", | 24 | return cmd_results_new(CMD_INVALID, "repeat_delay", |
24 | "Repeat delay cannot be negative"); | 25 | "Repeat delay cannot be negative"); |
25 | } | 26 | } |
diff --git a/sway/commands/input/repeat_rate.c b/sway/commands/input/repeat_rate.c index f2ea2e69..56878176 100644 --- a/sway/commands/input/repeat_rate.c +++ b/sway/commands/input/repeat_rate.c | |||
@@ -20,6 +20,7 @@ struct cmd_results *input_cmd_repeat_rate(int argc, char **argv) { | |||
20 | 20 | ||
21 | int repeat_rate = atoi(argv[0]); | 21 | int repeat_rate = atoi(argv[0]); |
22 | if (repeat_rate < 0) { | 22 | if (repeat_rate < 0) { |
23 | free_input_config(new_config); | ||
23 | return cmd_results_new(CMD_INVALID, "repeat_rate", | 24 | return cmd_results_new(CMD_INVALID, "repeat_rate", |
24 | "Repeat rate cannot be negative"); | 25 | "Repeat rate cannot be negative"); |
25 | } | 26 | } |
diff --git a/sway/commands/input/scroll_button.c b/sway/commands/input/scroll_button.c new file mode 100644 index 00000000..350fcca2 --- /dev/null +++ b/sway/commands/input/scroll_button.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <string.h> | ||
2 | #include <strings.h> | ||
3 | #include <errno.h> | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/commands.h" | ||
6 | #include "sway/input/input-manager.h" | ||
7 | |||
8 | struct cmd_results *input_cmd_scroll_button(int argc, char **argv) { | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "scroll_button", EXPECTED_AT_LEAST, 1))) { | ||
11 | return error; | ||
12 | } | ||
13 | struct input_config *current_input_config = | ||
14 | config->handler_context.input_config; | ||
15 | if (!current_input_config) { | ||
16 | return cmd_results_new(CMD_FAILURE, "scroll_button", | ||
17 | "No input device defined."); | ||
18 | } | ||
19 | struct input_config *new_config = | ||
20 | new_input_config(current_input_config->identifier); | ||
21 | |||
22 | errno = 0; | ||
23 | char *endptr; | ||
24 | int scroll_button = strtol(*argv, &endptr, 10); | ||
25 | if (endptr == *argv && scroll_button == 0) { | ||
26 | free_input_config(new_config); | ||
27 | return cmd_results_new(CMD_INVALID, "scroll_button", | ||
28 | "Scroll button identifier must be an integer."); | ||
29 | } | ||
30 | if (errno == ERANGE) { | ||
31 | free_input_config(new_config); | ||
32 | return cmd_results_new(CMD_INVALID, "scroll_button", | ||
33 | "Scroll button identifier out of range."); | ||
34 | } | ||
35 | if (scroll_button < 0) { | ||
36 | free_input_config(new_config); | ||
37 | return cmd_results_new(CMD_INVALID, "scroll_button", | ||
38 | "Scroll button identifier cannot be negative."); | ||
39 | } | ||
40 | new_config->scroll_button = scroll_button; | ||
41 | |||
42 | apply_input_config(new_config); | ||
43 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
44 | } | ||
diff --git a/sway/commands/input/scroll_method.c b/sway/commands/input/scroll_method.c index 0a1c57ac..4c6ac6b6 100644 --- a/sway/commands/input/scroll_method.c +++ b/sway/commands/input/scroll_method.c | |||
@@ -27,6 +27,7 @@ struct cmd_results *input_cmd_scroll_method(int argc, char **argv) { | |||
27 | } else if (strcasecmp(argv[0], "on_button_down") == 0) { | 27 | } else if (strcasecmp(argv[0], "on_button_down") == 0) { |
28 | new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; | 28 | new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; |
29 | } else { | 29 | } else { |
30 | free_input_config(new_config); | ||
30 | return cmd_results_new(CMD_INVALID, "scroll_method", | 31 | return cmd_results_new(CMD_INVALID, "scroll_method", |
31 | "Expected 'scroll_method <none|two_finger|edge|on_button_down>'"); | 32 | "Expected 'scroll_method <none|two_finger|edge|on_button_down>'"); |
32 | } | 33 | } |
diff --git a/sway/commands/input/tap.c b/sway/commands/input/tap.c index e7f03058..a8d1a10c 100644 --- a/sway/commands/input/tap.c +++ b/sway/commands/input/tap.c | |||
@@ -23,11 +23,12 @@ struct cmd_results *input_cmd_tap(int argc, char **argv) { | |||
23 | } else if (strcasecmp(argv[0], "disabled") == 0) { | 23 | } else if (strcasecmp(argv[0], "disabled") == 0) { |
24 | new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED; | 24 | new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED; |
25 | } else { | 25 | } else { |
26 | free_input_config(new_config); | ||
26 | return cmd_results_new(CMD_INVALID, "tap", | 27 | return cmd_results_new(CMD_INVALID, "tap", |
27 | "Expected 'tap <enabled|disabled>'"); | 28 | "Expected 'tap <enabled|disabled>'"); |
28 | } | 29 | } |
29 | 30 | ||
30 | wlr_log(L_DEBUG, "apply-tap for device: %s", | 31 | wlr_log(WLR_DEBUG, "apply-tap for device: %s", |
31 | current_input_config->identifier); | 32 | current_input_config->identifier); |
32 | apply_input_config(new_config); | 33 | apply_input_config(new_config); |
33 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 34 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/input/tap_button_map.c b/sway/commands/input/tap_button_map.c new file mode 100644 index 00000000..bdbba472 --- /dev/null +++ b/sway/commands/input/tap_button_map.c | |||
@@ -0,0 +1,33 @@ | |||
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 | |||
7 | struct cmd_results *input_cmd_tap_button_map(int argc, char **argv) { | ||
8 | struct cmd_results *error = NULL; | ||
9 | if ((error = checkarg(argc, "tap_button_map", EXPECTED_AT_LEAST, 1))) { | ||
10 | return error; | ||
11 | } | ||
12 | struct input_config *current_input_config = | ||
13 | config->handler_context.input_config; | ||
14 | if (!current_input_config) { | ||
15 | return cmd_results_new(CMD_FAILURE, "tap_button_map", | ||
16 | "No input device defined."); | ||
17 | } | ||
18 | struct input_config *new_config = | ||
19 | new_input_config(current_input_config->identifier); | ||
20 | |||
21 | if (strcasecmp(argv[0], "lrm") == 0) { | ||
22 | new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; | ||
23 | } else if (strcasecmp(argv[0], "lmr") == 0) { | ||
24 | new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LMR; | ||
25 | } else { | ||
26 | free_input_config(new_config); | ||
27 | return cmd_results_new(CMD_INVALID, "tap_button_map", | ||
28 | "Expected 'tap_button_map <lrm|lmr>'"); | ||
29 | } | ||
30 | |||
31 | apply_input_config(new_config); | ||
32 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
33 | } | ||
diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c index 867e65d3..9fa5a344 100644 --- a/sway/commands/input/xkb_layout.c +++ b/sway/commands/input/xkb_layout.c | |||
@@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_layout(int argc, char **argv) { | |||
19 | 19 | ||
20 | new_config->xkb_layout = strdup(argv[0]); | 20 | new_config->xkb_layout = strdup(argv[0]); |
21 | 21 | ||
22 | wlr_log(L_DEBUG, "apply-xkb_layout for device: %s layout: %s", | 22 | wlr_log(WLR_DEBUG, "apply-xkb_layout for device: %s layout: %s", |
23 | current_input_config->identifier, new_config->xkb_layout); | 23 | current_input_config->identifier, new_config->xkb_layout); |
24 | apply_input_config(new_config); | 24 | apply_input_config(new_config); |
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c index e8c8e04e..0d082625 100644 --- a/sway/commands/input/xkb_model.c +++ b/sway/commands/input/xkb_model.c | |||
@@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_model(int argc, char **argv) { | |||
19 | 19 | ||
20 | new_config->xkb_model = strdup(argv[0]); | 20 | new_config->xkb_model = strdup(argv[0]); |
21 | 21 | ||
22 | wlr_log(L_DEBUG, "apply-xkb_model for device: %s model: %s", | 22 | wlr_log(WLR_DEBUG, "apply-xkb_model for device: %s model: %s", |
23 | current_input_config->identifier, new_config->xkb_model); | 23 | current_input_config->identifier, new_config->xkb_model); |
24 | apply_input_config(new_config); | 24 | apply_input_config(new_config); |
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c index e9ddd6e3..3059d941 100644 --- a/sway/commands/input/xkb_options.c +++ b/sway/commands/input/xkb_options.c | |||
@@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_options(int argc, char **argv) { | |||
19 | 19 | ||
20 | new_config->xkb_options = strdup(argv[0]); | 20 | new_config->xkb_options = strdup(argv[0]); |
21 | 21 | ||
22 | wlr_log(L_DEBUG, "apply-xkb_options for device: %s options: %s", | 22 | wlr_log(WLR_DEBUG, "apply-xkb_options for device: %s options: %s", |
23 | current_input_config->identifier, new_config->xkb_options); | 23 | current_input_config->identifier, new_config->xkb_options); |
24 | apply_input_config(new_config); | 24 | apply_input_config(new_config); |
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c index 926d0ac1..560f088e 100644 --- a/sway/commands/input/xkb_rules.c +++ b/sway/commands/input/xkb_rules.c | |||
@@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_rules(int argc, char **argv) { | |||
19 | 19 | ||
20 | new_config->xkb_rules = strdup(argv[0]); | 20 | new_config->xkb_rules = strdup(argv[0]); |
21 | 21 | ||
22 | wlr_log(L_DEBUG, "apply-xkb_rules for device: %s rules: %s", | 22 | wlr_log(WLR_DEBUG, "apply-xkb_rules for device: %s rules: %s", |
23 | current_input_config->identifier, new_config->xkb_rules); | 23 | current_input_config->identifier, new_config->xkb_rules); |
24 | apply_input_config(new_config); | 24 | apply_input_config(new_config); |
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c index 0e3ffd41..0aa03440 100644 --- a/sway/commands/input/xkb_variant.c +++ b/sway/commands/input/xkb_variant.c | |||
@@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_variant(int argc, char **argv) { | |||
19 | 19 | ||
20 | new_config->xkb_variant = strdup(argv[0]); | 20 | new_config->xkb_variant = strdup(argv[0]); |
21 | 21 | ||
22 | wlr_log(L_DEBUG, "apply-xkb_variant for device: %s variant: %s", | 22 | wlr_log(WLR_DEBUG, "apply-xkb_variant for device: %s variant: %s", |
23 | current_input_config->identifier, new_config->xkb_variant); | 23 | current_input_config->identifier, new_config->xkb_variant); |
24 | apply_input_config(new_config); | 24 | apply_input_config(new_config); |
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 9945fa5c..c446f1f9 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -49,7 +49,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
49 | } | 49 | } |
50 | 50 | ||
51 | container_notify_subtree_changed(parent); | 51 | container_notify_subtree_changed(parent); |
52 | arrange_and_commit(parent); | 52 | arrange_windows(parent); |
53 | 53 | ||
54 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 54 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
55 | } | 55 | } |
diff --git a/sway/commands/mode.c b/sway/commands/mode.c index 00331ccc..b460fcb5 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c | |||
@@ -26,7 +26,17 @@ struct cmd_results *cmd_mode(int argc, char **argv) { | |||
26 | "mode", "Can only be used in config file."); | 26 | "mode", "Can only be used in config file."); |
27 | } | 27 | } |
28 | 28 | ||
29 | const char *mode_name = argv[0]; | 29 | bool pango = strcmp(*argv, "--pango_markup") == 0; |
30 | if (pango) { | ||
31 | argc--; argv++; | ||
32 | if (argc == 0) { | ||
33 | return cmd_results_new(CMD_FAILURE, "mode", | ||
34 | "Mode name is missing"); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | char *mode_name = *argv; | ||
39 | strip_quotes(mode_name); | ||
30 | struct sway_mode *mode = NULL; | 40 | struct sway_mode *mode = NULL; |
31 | // Find mode | 41 | // Find mode |
32 | for (int i = 0; i < config->modes->length; ++i) { | 42 | for (int i = 0; i < config->modes->length; ++i) { |
@@ -46,6 +56,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) { | |||
46 | mode->name = strdup(mode_name); | 56 | mode->name = strdup(mode_name); |
47 | mode->keysym_bindings = create_list(); | 57 | mode->keysym_bindings = create_list(); |
48 | mode->keycode_bindings = create_list(); | 58 | mode->keycode_bindings = create_list(); |
59 | mode->pango = pango; | ||
49 | list_add(config->modes, mode); | 60 | list_add(config->modes, mode); |
50 | } | 61 | } |
51 | if (!mode) { | 62 | if (!mode) { |
@@ -54,13 +65,15 @@ struct cmd_results *cmd_mode(int argc, char **argv) { | |||
54 | return error; | 65 | return error; |
55 | } | 66 | } |
56 | if ((config->reading && argc > 1) || (!config->reading && argc == 1)) { | 67 | if ((config->reading && argc > 1) || (!config->reading && argc == 1)) { |
57 | wlr_log(L_DEBUG, "Switching to mode `%s'",mode->name); | 68 | wlr_log(WLR_DEBUG, "Switching to mode `%s' (pango=%d)", |
69 | mode->name, mode->pango); | ||
58 | } | 70 | } |
59 | // Set current mode | 71 | // Set current mode |
60 | config->current_mode = mode; | 72 | config->current_mode = mode; |
61 | if (argc == 1) { | 73 | if (argc == 1) { |
62 | // trigger IPC mode event | 74 | // trigger IPC mode event |
63 | ipc_event_mode(config->current_mode->name); | 75 | ipc_event_mode(config->current_mode->name, |
76 | config->current_mode->pango); | ||
64 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 77 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
65 | } | 78 | } |
66 | 79 | ||
diff --git a/sway/commands/move.c b/sway/commands/move.c index a4fae388..1940043d 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -1,13 +1,15 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <strings.h> | 3 | #include <strings.h> |
4 | #include <wlr/types/wlr_cursor.h> | ||
4 | #include <wlr/types/wlr_output.h> | 5 | #include <wlr/types/wlr_output.h> |
5 | #include <wlr/types/wlr_output_layout.h> | 6 | #include <wlr/types/wlr_output_layout.h> |
6 | #include <wlr/util/log.h> | 7 | #include <wlr/util/log.h> |
7 | #include "sway/commands.h" | 8 | #include "sway/commands.h" |
8 | #include "sway/desktop/transaction.h" | 9 | #include "sway/input/cursor.h" |
9 | #include "sway/input/seat.h" | 10 | #include "sway/input/seat.h" |
10 | #include "sway/output.h" | 11 | #include "sway/output.h" |
12 | #include "sway/scratchpad.h" | ||
11 | #include "sway/tree/arrange.h" | 13 | #include "sway/tree/arrange.h" |
12 | #include "sway/tree/container.h" | 14 | #include "sway/tree/container.h" |
13 | #include "sway/tree/layout.h" | 15 | #include "sway/tree/layout.h" |
@@ -103,10 +105,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
103 | // TODO: Ideally we would arrange the surviving parent after reaping, | 105 | // TODO: Ideally we would arrange the surviving parent after reaping, |
104 | // but container_reap_empty does not return it, so we arrange the | 106 | // but container_reap_empty does not return it, so we arrange the |
105 | // workspace instead. | 107 | // workspace instead. |
106 | struct sway_transaction *txn = transaction_create(); | 108 | arrange_windows(old_ws); |
107 | arrange_windows(old_ws, txn); | 109 | arrange_windows(destination->parent); |
108 | arrange_windows(destination->parent, txn); | ||
109 | transaction_commit(txn); | ||
110 | 110 | ||
111 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 111 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
112 | } else if (strcasecmp(argv[1], "to") == 0 | 112 | } else if (strcasecmp(argv[1], "to") == 0 |
@@ -142,10 +142,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
142 | // TODO: Ideally we would arrange the surviving parent after reaping, | 142 | // TODO: Ideally we would arrange the surviving parent after reaping, |
143 | // but container_reap_empty does not return it, so we arrange the | 143 | // but container_reap_empty does not return it, so we arrange the |
144 | // workspace instead. | 144 | // workspace instead. |
145 | struct sway_transaction *txn = transaction_create(); | 145 | arrange_windows(old_ws); |
146 | arrange_windows(old_ws, txn); | 146 | arrange_windows(focus->parent); |
147 | arrange_windows(focus->parent, txn); | ||
148 | transaction_commit(txn); | ||
149 | 147 | ||
150 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 148 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
151 | } | 149 | } |
@@ -175,20 +173,56 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current, | |||
175 | } | 173 | } |
176 | container_move_to(current, destination); | 174 | container_move_to(current, destination); |
177 | 175 | ||
178 | struct sway_transaction *txn = transaction_create(); | 176 | arrange_windows(source); |
179 | arrange_windows(source, txn); | 177 | arrange_windows(destination); |
180 | arrange_windows(destination, txn); | ||
181 | transaction_commit(txn); | ||
182 | 178 | ||
183 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 179 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
184 | } | 180 | } |
185 | 181 | ||
186 | static struct cmd_results *move_in_direction(struct sway_container *container, | 182 | static struct cmd_results *move_in_direction(struct sway_container *container, |
187 | enum movement_direction direction, int move_amt) { | 183 | enum movement_direction direction, int argc, char **argv) { |
184 | int move_amt = 10; | ||
185 | if (argc > 1) { | ||
186 | char *inv; | ||
187 | move_amt = (int)strtol(argv[1], &inv, 10); | ||
188 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
189 | return cmd_results_new(CMD_FAILURE, "move", | ||
190 | "Invalid distance specified"); | ||
191 | } | ||
192 | } | ||
193 | |||
188 | if (container->type == C_WORKSPACE) { | 194 | if (container->type == C_WORKSPACE) { |
189 | return cmd_results_new(CMD_FAILURE, "move", | 195 | return cmd_results_new(CMD_FAILURE, "move", |
190 | "Cannot move workspaces in a direction"); | 196 | "Cannot move workspaces in a direction"); |
191 | } | 197 | } |
198 | if (container_is_floating(container)) { | ||
199 | if (container->type == C_VIEW && container->sway_view->is_fullscreen) { | ||
200 | return cmd_results_new(CMD_FAILURE, "move", | ||
201 | "Cannot move fullscreen floating container"); | ||
202 | } | ||
203 | double lx = container->x; | ||
204 | double ly = container->y; | ||
205 | switch (direction) { | ||
206 | case MOVE_LEFT: | ||
207 | lx -= move_amt; | ||
208 | break; | ||
209 | case MOVE_RIGHT: | ||
210 | lx += move_amt; | ||
211 | break; | ||
212 | case MOVE_UP: | ||
213 | ly -= move_amt; | ||
214 | break; | ||
215 | case MOVE_DOWN: | ||
216 | ly += move_amt; | ||
217 | break; | ||
218 | case MOVE_PARENT: | ||
219 | case MOVE_CHILD: | ||
220 | return cmd_results_new(CMD_FAILURE, "move", | ||
221 | "Cannot move floating container to parent or child"); | ||
222 | } | ||
223 | container_floating_move_to(container, lx, ly); | ||
224 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
225 | } | ||
192 | // For simplicity, we'll arrange the entire workspace. The reason for this | 226 | // For simplicity, we'll arrange the entire workspace. The reason for this |
193 | // is moving the container might reap the old parent, and container_move | 227 | // is moving the container might reap the old parent, and container_move |
194 | // does not return a surviving parent. | 228 | // does not return a surviving parent. |
@@ -198,54 +232,112 @@ static struct cmd_results *move_in_direction(struct sway_container *container, | |||
198 | container_move(container, direction, move_amt); | 232 | container_move(container, direction, move_amt); |
199 | struct sway_container *new_ws = container_parent(container, C_WORKSPACE); | 233 | struct sway_container *new_ws = container_parent(container, C_WORKSPACE); |
200 | 234 | ||
201 | struct sway_transaction *txn = transaction_create(); | 235 | arrange_windows(old_ws); |
202 | arrange_windows(old_ws, txn); | ||
203 | if (new_ws != old_ws) { | 236 | if (new_ws != old_ws) { |
204 | arrange_windows(new_ws, txn); | 237 | arrange_windows(new_ws); |
205 | } | 238 | } |
206 | transaction_commit(txn); | ||
207 | 239 | ||
208 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 240 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
209 | } | 241 | } |
210 | 242 | ||
243 | static const char* expected_position_syntax = | ||
244 | "Expected 'move [absolute] position <x> <y>' or " | ||
245 | "'move [absolute] position mouse'"; | ||
246 | |||
247 | static struct cmd_results *move_to_position(struct sway_container *container, | ||
248 | int argc, char **argv) { | ||
249 | if (!container_is_floating(container)) { | ||
250 | return cmd_results_new(CMD_FAILURE, "move", | ||
251 | "Only floating containers " | ||
252 | "can be moved to an absolute position"); | ||
253 | } | ||
254 | if (!argc) { | ||
255 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
256 | } | ||
257 | if (strcmp(argv[0], "absolute") == 0) { | ||
258 | --argc; | ||
259 | ++argv; | ||
260 | } | ||
261 | if (!argc) { | ||
262 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
263 | } | ||
264 | if (strcmp(argv[0], "position") == 0) { | ||
265 | --argc; | ||
266 | ++argv; | ||
267 | } | ||
268 | if (!argc) { | ||
269 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
270 | } | ||
271 | if (strcmp(argv[0], "mouse") == 0) { | ||
272 | struct sway_seat *seat = config->handler_context.seat; | ||
273 | if (!seat->cursor) { | ||
274 | return cmd_results_new(CMD_FAILURE, "move", "No cursor device"); | ||
275 | } | ||
276 | double lx = seat->cursor->cursor->x - container->width / 2; | ||
277 | double ly = seat->cursor->cursor->y - container->height / 2; | ||
278 | container_floating_move_to(container, lx, ly); | ||
279 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
280 | } | ||
281 | if (argc != 2) { | ||
282 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
283 | } | ||
284 | double lx, ly; | ||
285 | char *inv; | ||
286 | lx = (double)strtol(argv[0], &inv, 10); | ||
287 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
288 | return cmd_results_new(CMD_FAILURE, "move", | ||
289 | "Invalid position specified"); | ||
290 | } | ||
291 | ly = (double)strtol(argv[1], &inv, 10); | ||
292 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
293 | return cmd_results_new(CMD_FAILURE, "move", | ||
294 | "Invalid position specified"); | ||
295 | } | ||
296 | container_floating_move_to(container, lx, ly); | ||
297 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
298 | } | ||
299 | |||
300 | static struct cmd_results *move_to_scratchpad(struct sway_container *con) { | ||
301 | if (con->type != C_CONTAINER && con->type != C_VIEW) { | ||
302 | return cmd_results_new(CMD_INVALID, "move", | ||
303 | "Only views and containers can be moved to the scratchpad"); | ||
304 | } | ||
305 | if (con->scratchpad) { | ||
306 | return cmd_results_new(CMD_INVALID, "move", | ||
307 | "Container is already in the scratchpad"); | ||
308 | } | ||
309 | scratchpad_add_container(con); | ||
310 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
311 | } | ||
312 | |||
211 | struct cmd_results *cmd_move(int argc, char **argv) { | 313 | struct cmd_results *cmd_move(int argc, char **argv) { |
212 | struct cmd_results *error = NULL; | 314 | struct cmd_results *error = NULL; |
213 | int move_amt = 10; | ||
214 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { | 315 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { |
215 | return error; | 316 | return error; |
216 | } | 317 | } |
217 | struct sway_container *current = config->handler_context.current_container; | 318 | struct sway_container *current = config->handler_context.current_container; |
218 | 319 | ||
219 | if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) { | ||
220 | char *inv; | ||
221 | move_amt = (int)strtol(argv[1], &inv, 10); | ||
222 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
223 | return cmd_results_new(CMD_FAILURE, "move", | ||
224 | "Invalid distance specified"); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if (strcasecmp(argv[0], "left") == 0) { | 320 | if (strcasecmp(argv[0], "left") == 0) { |
229 | return move_in_direction(current, MOVE_LEFT, move_amt); | 321 | return move_in_direction(current, MOVE_LEFT, argc, argv); |
230 | } else if (strcasecmp(argv[0], "right") == 0) { | 322 | } else if (strcasecmp(argv[0], "right") == 0) { |
231 | return move_in_direction(current, MOVE_RIGHT, move_amt); | 323 | return move_in_direction(current, MOVE_RIGHT, argc, argv); |
232 | } else if (strcasecmp(argv[0], "up") == 0) { | 324 | } else if (strcasecmp(argv[0], "up") == 0) { |
233 | return move_in_direction(current, MOVE_UP, move_amt); | 325 | return move_in_direction(current, MOVE_UP, argc, argv); |
234 | } else if (strcasecmp(argv[0], "down") == 0) { | 326 | } else if (strcasecmp(argv[0], "down") == 0) { |
235 | return move_in_direction(current, MOVE_DOWN, move_amt); | 327 | return move_in_direction(current, MOVE_DOWN, argc, argv); |
236 | } else if (strcasecmp(argv[0], "container") == 0 | 328 | } else if (strcasecmp(argv[0], "container") == 0 |
237 | || strcasecmp(argv[0], "window") == 0) { | 329 | || strcasecmp(argv[0], "window") == 0) { |
238 | return cmd_move_container(current, argc, argv); | 330 | return cmd_move_container(current, argc, argv); |
239 | } else if (strcasecmp(argv[0], "workspace") == 0) { | 331 | } else if (strcasecmp(argv[0], "workspace") == 0) { |
240 | return cmd_move_workspace(current, argc, argv); | 332 | return cmd_move_workspace(current, argc, argv); |
241 | } else if (strcasecmp(argv[0], "scratchpad") == 0 | 333 | } else if (strcasecmp(argv[0], "scratchpad") == 0 |
242 | || (strcasecmp(argv[0], "to") == 0 | 334 | || (strcasecmp(argv[0], "to") == 0 && argc == 2 |
243 | && strcasecmp(argv[1], "scratchpad") == 0)) { | 335 | && strcasecmp(argv[1], "scratchpad") == 0)) { |
244 | // TODO: scratchpad | 336 | return move_to_scratchpad(current); |
245 | return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); | ||
246 | } else if (strcasecmp(argv[0], "position") == 0) { | 337 | } else if (strcasecmp(argv[0], "position") == 0) { |
247 | // TODO: floating | 338 | return move_to_position(current, argc, argv); |
248 | return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); | 339 | } else if (strcasecmp(argv[0], "absolute") == 0) { |
340 | return move_to_position(current, argc, argv); | ||
249 | } else { | 341 | } else { |
250 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); | 342 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); |
251 | } | 343 | } |
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c new file mode 100644 index 00000000..61a8de7e --- /dev/null +++ b/sway/commands/no_focus.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <string.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/criteria.h" | ||
5 | #include "list.h" | ||
6 | #include "log.h" | ||
7 | |||
8 | struct cmd_results *cmd_no_focus(int argc, char **argv) { | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "no_focus", EXPECTED_AT_LEAST, 1))) { | ||
11 | return error; | ||
12 | } | ||
13 | |||
14 | char *err_str = NULL; | ||
15 | struct criteria *criteria = criteria_parse(argv[0], &err_str); | ||
16 | if (!criteria) { | ||
17 | error = cmd_results_new(CMD_INVALID, "no_focus", err_str); | ||
18 | free(err_str); | ||
19 | return error; | ||
20 | } | ||
21 | |||
22 | criteria->type = CT_NO_FOCUS; | ||
23 | list_add(config->criteria, criteria); | ||
24 | |||
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
26 | } | ||
diff --git a/sway/commands/output.c b/sway/commands/output.c index f955bf90..ef1b7a69 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -29,7 +29,7 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
29 | 29 | ||
30 | struct output_config *output = new_output_config(argv[0]); | 30 | struct output_config *output = new_output_config(argv[0]); |
31 | if (!output) { | 31 | if (!output) { |
32 | wlr_log(L_ERROR, "Failed to allocate output config"); | 32 | wlr_log(WLR_ERROR, "Failed to allocate output config"); |
33 | return NULL; | 33 | return NULL; |
34 | } | 34 | } |
35 | argc--; argv++; | 35 | argc--; argv++; |
@@ -60,53 +60,13 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
60 | config->handler_context.leftovers.argc = 0; | 60 | config->handler_context.leftovers.argc = 0; |
61 | config->handler_context.leftovers.argv = NULL; | 61 | config->handler_context.leftovers.argv = NULL; |
62 | 62 | ||
63 | int i = list_seq_find(config->output_configs, output_name_cmp, output->name); | 63 | output = store_output_config(output); |
64 | if (i >= 0) { | ||
65 | // Merge existing config | ||
66 | struct output_config *current = config->output_configs->items[i]; | ||
67 | merge_output_config(current, output); | ||
68 | free_output_config(output); | ||
69 | output = current; | ||
70 | } else { | ||
71 | list_add(config->output_configs, output); | ||
72 | } | ||
73 | |||
74 | wlr_log(L_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " | ||
75 | "position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)", | ||
76 | output->name, output->enabled, output->width, output->height, | ||
77 | output->refresh_rate, output->x, output->y, output->scale, | ||
78 | output->transform, output->background, output->background_option, output->dpms_state); | ||
79 | |||
80 | // Try to find the output container and apply configuration now. If | ||
81 | // this is during startup then there will be no container and config | ||
82 | // will be applied during normal "new output" event from wlroots. | ||
83 | char identifier[128]; | ||
84 | bool all = strcmp(output->name, "*") == 0; | ||
85 | struct sway_output *sway_output; | ||
86 | wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) { | ||
87 | output_get_identifier(identifier, sizeof(identifier), sway_output); | ||
88 | wlr_log(L_DEBUG, "Checking identifier %s", identifier); | ||
89 | if (all || strcmp(sway_output->wlr_output->name, output->name) == 0 | ||
90 | || strcmp(identifier, output->name) == 0) { | ||
91 | if (!sway_output->swayc) { | ||
92 | if (!output->enabled) { | ||
93 | if (!all) { | ||
94 | break; | ||
95 | } | ||
96 | continue; | ||
97 | } | ||
98 | 64 | ||
99 | output_enable(sway_output); | 65 | // If reloading, the output configs will be applied after reading the |
100 | } | 66 | // entire config and before the deferred commands so that an auto generated |
101 | 67 | // workspace name is not given to re-enabled outputs. | |
102 | apply_output_config(output, sway_output->swayc); | 68 | if (!config->reloading) { |
103 | 69 | apply_output_config_to_outputs(output); | |
104 | if (!all) { | ||
105 | // Stop looking if the output config isn't applicable to all | ||
106 | // outputs | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | } | 70 | } |
111 | 71 | ||
112 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 72 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index 55cbdff0..4ed56c2a 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c | |||
@@ -72,7 +72,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
72 | src = strdup(p.we_wordv[0]); | 72 | src = strdup(p.we_wordv[0]); |
73 | wordfree(&p); | 73 | wordfree(&p); |
74 | if (!src) { | 74 | if (!src) { |
75 | wlr_log(L_ERROR, "Failed to duplicate string"); | 75 | wlr_log(WLR_ERROR, "Failed to duplicate string"); |
76 | return cmd_results_new(CMD_FAILURE, "output", | 76 | return cmd_results_new(CMD_FAILURE, "output", |
77 | "Unable to allocate resource"); | 77 | "Unable to allocate resource"); |
78 | } | 78 | } |
@@ -80,9 +80,10 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
80 | if (config->reading && *src != '/') { | 80 | if (config->reading && *src != '/') { |
81 | // src file is inside configuration dir | 81 | // src file is inside configuration dir |
82 | 82 | ||
83 | char *conf = strdup(config->current_config); | 83 | char *conf = strdup(config->current_config_path); |
84 | if(!conf) { | 84 | if (!conf) { |
85 | wlr_log(L_ERROR, "Failed to duplicate string"); | 85 | wlr_log(WLR_ERROR, "Failed to duplicate string"); |
86 | free(src); | ||
86 | return cmd_results_new(CMD_FAILURE, "output", | 87 | return cmd_results_new(CMD_FAILURE, "output", |
87 | "Unable to allocate resources"); | 88 | "Unable to allocate resources"); |
88 | } | 89 | } |
@@ -93,7 +94,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
93 | if (!src) { | 94 | if (!src) { |
94 | free(rel_path); | 95 | free(rel_path); |
95 | free(conf); | 96 | free(conf); |
96 | wlr_log(L_ERROR, "Unable to allocate memory"); | 97 | wlr_log(WLR_ERROR, "Unable to allocate memory"); |
97 | return cmd_results_new(CMD_FAILURE, "output", | 98 | return cmd_results_new(CMD_FAILURE, "output", |
98 | "Unable to allocate resources"); | 99 | "Unable to allocate resources"); |
99 | } | 100 | } |
diff --git a/sway/commands/output/mode.c b/sway/commands/output/mode.c index daec6d44..ef56ae9e 100644 --- a/sway/commands/output/mode.c +++ b/sway/commands/output/mode.c | |||
@@ -36,11 +36,11 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { | |||
36 | } | 36 | } |
37 | } else { | 37 | } else { |
38 | // Format is 1234 4321 | 38 | // Format is 1234 4321 |
39 | argc--; argv++; | ||
39 | if (!argc) { | 40 | if (!argc) { |
40 | return cmd_results_new(CMD_INVALID, "output", | 41 | return cmd_results_new(CMD_INVALID, "output", |
41 | "Missing mode argument (height)."); | 42 | "Missing mode argument (height)."); |
42 | } | 43 | } |
43 | argc--; argv++; | ||
44 | output->height = strtol(*argv, &end, 10); | 44 | output->height = strtol(*argv, &end, 10); |
45 | if (*end) { | 45 | if (*end) { |
46 | return cmd_results_new(CMD_INVALID, "output", | 46 | return cmd_results_new(CMD_INVALID, "output", |
diff --git a/sway/commands/output/position.c b/sway/commands/output/position.c index c2aeb281..449767b1 100644 --- a/sway/commands/output/position.c +++ b/sway/commands/output/position.c | |||
@@ -27,11 +27,11 @@ struct cmd_results *output_cmd_position(int argc, char **argv) { | |||
27 | } | 27 | } |
28 | } else { | 28 | } else { |
29 | // Format is 1234 4321 (legacy) | 29 | // Format is 1234 4321 (legacy) |
30 | argc--; argv++; | ||
30 | if (!argc) { | 31 | if (!argc) { |
31 | return cmd_results_new(CMD_INVALID, "output", | 32 | return cmd_results_new(CMD_INVALID, "output", |
32 | "Missing position argument (y)."); | 33 | "Missing position argument (y)."); |
33 | } | 34 | } |
34 | argc--; argv++; | ||
35 | config->handler_context.output_config->y = strtol(*argv, &end, 10); | 35 | config->handler_context.output_config->y = strtol(*argv, &end, 10); |
36 | if (*end) { | 36 | if (*end) { |
37 | return cmd_results_new(CMD_INVALID, "output", | 37 | return cmd_results_new(CMD_INVALID, "output", |
diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 9fc213c4..cea6a94b 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c | |||
@@ -7,11 +7,11 @@ struct cmd_results *cmd_reload(int argc, char **argv) { | |||
7 | if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { | 7 | if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { |
8 | return error; | 8 | return error; |
9 | } | 9 | } |
10 | if (!load_main_config(config->current_config, true)) { | 10 | if (!load_main_config(config->current_config_path, true)) { |
11 | return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); | 11 | return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); |
12 | } | 12 | } |
13 | 13 | ||
14 | load_swaybars(); | 14 | load_swaybars(); |
15 | arrange_and_commit(&root_container); | 15 | arrange_windows(&root_container); |
16 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 16 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
17 | } | 17 | } |
diff --git a/sway/commands/rename.c b/sway/commands/rename.c index 104a3392..a380ff9c 100644 --- a/sway/commands/rename.c +++ b/sway/commands/rename.c | |||
@@ -68,7 +68,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) { | |||
68 | "Workspace already exists"); | 68 | "Workspace already exists"); |
69 | } | 69 | } |
70 | 70 | ||
71 | wlr_log(L_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); | 71 | wlr_log(WLR_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); |
72 | free(workspace->name); | 72 | free(workspace->name); |
73 | workspace->name = new_name; | 73 | workspace->name = new_name; |
74 | 74 | ||
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 6357343e..e657864c 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <limits.h> | ||
2 | #include <math.h> | 3 | #include <math.h> |
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
@@ -7,6 +8,7 @@ | |||
7 | #include <wlr/util/log.h> | 8 | #include <wlr/util/log.h> |
8 | #include "sway/commands.h" | 9 | #include "sway/commands.h" |
9 | #include "sway/tree/arrange.h" | 10 | #include "sway/tree/arrange.h" |
11 | #include "sway/tree/view.h" | ||
10 | #include "log.h" | 12 | #include "log.h" |
11 | 13 | ||
12 | static const int MIN_SANE_W = 100, MIN_SANE_H = 60; | 14 | static const int MIN_SANE_W = 100, MIN_SANE_H = 60; |
@@ -21,9 +23,18 @@ enum resize_unit { | |||
21 | enum resize_axis { | 23 | enum resize_axis { |
22 | RESIZE_AXIS_HORIZONTAL, | 24 | RESIZE_AXIS_HORIZONTAL, |
23 | RESIZE_AXIS_VERTICAL, | 25 | RESIZE_AXIS_VERTICAL, |
26 | RESIZE_AXIS_UP, | ||
27 | RESIZE_AXIS_DOWN, | ||
28 | RESIZE_AXIS_LEFT, | ||
29 | RESIZE_AXIS_RIGHT, | ||
24 | RESIZE_AXIS_INVALID, | 30 | RESIZE_AXIS_INVALID, |
25 | }; | 31 | }; |
26 | 32 | ||
33 | struct resize_amount { | ||
34 | int amount; | ||
35 | enum resize_unit unit; | ||
36 | }; | ||
37 | |||
27 | static enum resize_unit parse_resize_unit(const char *unit) { | 38 | static enum resize_unit parse_resize_unit(const char *unit) { |
28 | if (strcasecmp(unit, "px") == 0) { | 39 | if (strcasecmp(unit, "px") == 0) { |
29 | return RESIZE_UNIT_PX; | 40 | return RESIZE_UNIT_PX; |
@@ -37,6 +48,69 @@ static enum resize_unit parse_resize_unit(const char *unit) { | |||
37 | return RESIZE_UNIT_INVALID; | 48 | return RESIZE_UNIT_INVALID; |
38 | } | 49 | } |
39 | 50 | ||
51 | // Parse arguments such as "10", "10px" or "10 px". | ||
52 | // Returns the number of arguments consumed. | ||
53 | static int parse_resize_amount(int argc, char **argv, | ||
54 | struct resize_amount *amount) { | ||
55 | char *err; | ||
56 | amount->amount = (int)strtol(argv[0], &err, 10); | ||
57 | if (*err) { | ||
58 | // e.g. 10px | ||
59 | amount->unit = parse_resize_unit(err); | ||
60 | return 1; | ||
61 | } | ||
62 | if (argc == 1) { | ||
63 | amount->unit = RESIZE_UNIT_DEFAULT; | ||
64 | return 1; | ||
65 | } | ||
66 | // Try the second argument | ||
67 | amount->unit = parse_resize_unit(argv[1]); | ||
68 | if (amount->unit == RESIZE_UNIT_INVALID) { | ||
69 | amount->unit = RESIZE_UNIT_DEFAULT; | ||
70 | return 1; | ||
71 | } | ||
72 | return 2; | ||
73 | } | ||
74 | |||
75 | static void calculate_constraints(int *min_width, int *max_width, | ||
76 | int *min_height, int *max_height) { | ||
77 | struct sway_container *con = config->handler_context.current_container; | ||
78 | |||
79 | if (config->floating_minimum_width == -1) { // no minimum | ||
80 | *min_width = 0; | ||
81 | } else if (config->floating_minimum_width == 0) { // automatic | ||
82 | *min_width = 75; | ||
83 | } else { | ||
84 | *min_width = config->floating_minimum_width; | ||
85 | } | ||
86 | |||
87 | if (config->floating_minimum_height == -1) { // no minimum | ||
88 | *min_height = 0; | ||
89 | } else if (config->floating_minimum_height == 0) { // automatic | ||
90 | *min_height = 50; | ||
91 | } else { | ||
92 | *min_height = config->floating_minimum_height; | ||
93 | } | ||
94 | |||
95 | if (config->floating_maximum_width == -1) { // no maximum | ||
96 | *max_width = INT_MAX; | ||
97 | } else if (config->floating_maximum_width == 0) { // automatic | ||
98 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | ||
99 | *max_width = ws->width; | ||
100 | } else { | ||
101 | *max_width = config->floating_maximum_width; | ||
102 | } | ||
103 | |||
104 | if (config->floating_maximum_height == -1) { // no maximum | ||
105 | *max_height = INT_MAX; | ||
106 | } else if (config->floating_maximum_height == 0) { // automatic | ||
107 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | ||
108 | *max_height = ws->height; | ||
109 | } else { | ||
110 | *max_height = config->floating_maximum_height; | ||
111 | } | ||
112 | } | ||
113 | |||
40 | static enum resize_axis parse_resize_axis(const char *axis) { | 114 | static enum resize_axis parse_resize_axis(const char *axis) { |
41 | if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { | 115 | if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { |
42 | return RESIZE_AXIS_HORIZONTAL; | 116 | return RESIZE_AXIS_HORIZONTAL; |
@@ -44,6 +118,18 @@ static enum resize_axis parse_resize_axis(const char *axis) { | |||
44 | if (strcasecmp(axis, "height") == 0 || strcasecmp(axis, "vertical") == 0) { | 118 | if (strcasecmp(axis, "height") == 0 || strcasecmp(axis, "vertical") == 0) { |
45 | return RESIZE_AXIS_VERTICAL; | 119 | return RESIZE_AXIS_VERTICAL; |
46 | } | 120 | } |
121 | if (strcasecmp(axis, "up") == 0) { | ||
122 | return RESIZE_AXIS_UP; | ||
123 | } | ||
124 | if (strcasecmp(axis, "down") == 0) { | ||
125 | return RESIZE_AXIS_DOWN; | ||
126 | } | ||
127 | if (strcasecmp(axis, "left") == 0) { | ||
128 | return RESIZE_AXIS_LEFT; | ||
129 | } | ||
130 | if (strcasecmp(axis, "right") == 0) { | ||
131 | return RESIZE_AXIS_RIGHT; | ||
132 | } | ||
47 | return RESIZE_AXIS_INVALID; | 133 | return RESIZE_AXIS_INVALID; |
48 | } | 134 | } |
49 | 135 | ||
@@ -95,7 +181,7 @@ static void resize_tiled(int amount, enum resize_axis axis) { | |||
95 | return; | 181 | return; |
96 | } | 182 | } |
97 | 183 | ||
98 | wlr_log(L_DEBUG, | 184 | wlr_log(WLR_DEBUG, |
99 | "Found the proper parent: %p. It has %d l conts, and %d r conts", | 185 | "Found the proper parent: %p. It has %d l conts, and %d r conts", |
100 | parent->parent, minor_weight, major_weight); | 186 | parent->parent, minor_weight, major_weight); |
101 | 187 | ||
@@ -182,105 +268,315 @@ static void resize_tiled(int amount, enum resize_axis axis) { | |||
182 | } | 268 | } |
183 | } | 269 | } |
184 | 270 | ||
185 | arrange_and_commit(parent->parent); | 271 | arrange_windows(parent->parent); |
186 | } | 272 | } |
187 | 273 | ||
188 | static void resize(int amount, enum resize_axis axis, enum resize_unit unit) { | 274 | /** |
189 | struct sway_container *current = config->handler_context.current_container; | 275 | * Implement `resize <grow|shrink>` for a floating container. |
190 | if (unit == RESIZE_UNIT_DEFAULT) { | 276 | */ |
191 | // Default for tiling; TODO floating should be px | 277 | static struct cmd_results *resize_adjust_floating(enum resize_axis axis, |
192 | unit = RESIZE_UNIT_PPT; | 278 | struct resize_amount *amount) { |
279 | struct sway_container *con = config->handler_context.current_container; | ||
280 | int grow_width = 0, grow_height = 0; | ||
281 | switch (axis) { | ||
282 | case RESIZE_AXIS_HORIZONTAL: | ||
283 | case RESIZE_AXIS_LEFT: | ||
284 | case RESIZE_AXIS_RIGHT: | ||
285 | grow_width = amount->amount; | ||
286 | break; | ||
287 | case RESIZE_AXIS_VERTICAL: | ||
288 | case RESIZE_AXIS_UP: | ||
289 | case RESIZE_AXIS_DOWN: | ||
290 | grow_height = amount->amount; | ||
291 | break; | ||
292 | case RESIZE_AXIS_INVALID: | ||
293 | return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction"); | ||
294 | } | ||
295 | // Make sure we're not adjusting beyond floating min/max size | ||
296 | int min_width, max_width, min_height, max_height; | ||
297 | calculate_constraints(&min_width, &max_width, &min_height, &max_height); | ||
298 | if (con->width + grow_width < min_width) { | ||
299 | grow_width = min_width - con->width; | ||
300 | } else if (con->width + grow_width > max_width) { | ||
301 | grow_width = max_width - con->width; | ||
193 | } | 302 | } |
303 | if (con->height + grow_height < min_height) { | ||
304 | grow_height = min_height - con->height; | ||
305 | } else if (con->height + grow_height > max_height) { | ||
306 | grow_height = max_height - con->height; | ||
307 | } | ||
308 | int grow_x = 0, grow_y = 0; | ||
309 | switch (axis) { | ||
310 | case RESIZE_AXIS_HORIZONTAL: | ||
311 | grow_x = -grow_width / 2; | ||
312 | break; | ||
313 | case RESIZE_AXIS_VERTICAL: | ||
314 | grow_y = -grow_height / 2; | ||
315 | break; | ||
316 | case RESIZE_AXIS_UP: | ||
317 | grow_y = -grow_height; | ||
318 | break; | ||
319 | case RESIZE_AXIS_LEFT: | ||
320 | grow_x = -grow_width; | ||
321 | break; | ||
322 | case RESIZE_AXIS_DOWN: | ||
323 | case RESIZE_AXIS_RIGHT: | ||
324 | break; | ||
325 | case RESIZE_AXIS_INVALID: | ||
326 | return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction"); | ||
327 | } | ||
328 | con->x += grow_x; | ||
329 | con->y += grow_y; | ||
330 | con->width += grow_width; | ||
331 | con->height += grow_height; | ||
332 | |||
333 | if (con->type == C_VIEW) { | ||
334 | struct sway_view *view = con->sway_view; | ||
335 | view->x += grow_x; | ||
336 | view->y += grow_y; | ||
337 | view->width += grow_width; | ||
338 | view->height += grow_height; | ||
339 | } | ||
340 | |||
341 | arrange_windows(con); | ||
342 | |||
343 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
344 | } | ||
194 | 345 | ||
195 | if (unit == RESIZE_UNIT_PPT) { | 346 | /** |
196 | float pct = amount / 100.0f; | 347 | * Implement `resize <grow|shrink>` for a tiled container. |
348 | */ | ||
349 | static struct cmd_results *resize_adjust_tiled(enum resize_axis axis, | ||
350 | struct resize_amount *amount) { | ||
351 | struct sway_container *current = config->handler_context.current_container; | ||
352 | |||
353 | if (amount->unit == RESIZE_UNIT_DEFAULT) { | ||
354 | amount->unit = RESIZE_UNIT_PPT; | ||
355 | } | ||
356 | if (amount->unit == RESIZE_UNIT_PPT) { | ||
357 | float pct = amount->amount / 100.0f; | ||
358 | // TODO: Make left/right/up/down resize in that direction? | ||
197 | switch (axis) { | 359 | switch (axis) { |
360 | case RESIZE_AXIS_LEFT: | ||
361 | case RESIZE_AXIS_RIGHT: | ||
198 | case RESIZE_AXIS_HORIZONTAL: | 362 | case RESIZE_AXIS_HORIZONTAL: |
199 | amount = (float)current->width * pct; | 363 | amount->amount = (float)current->width * pct; |
200 | break; | 364 | break; |
365 | case RESIZE_AXIS_UP: | ||
366 | case RESIZE_AXIS_DOWN: | ||
201 | case RESIZE_AXIS_VERTICAL: | 367 | case RESIZE_AXIS_VERTICAL: |
202 | amount = (float)current->height * pct; | 368 | amount->amount = (float)current->height * pct; |
203 | break; | 369 | break; |
204 | default: | 370 | case RESIZE_AXIS_INVALID: |
205 | sway_assert(0, "invalid resize axis"); | 371 | return cmd_results_new(CMD_INVALID, "resize", |
206 | return; | 372 | "Invalid resize axis/direction"); |
207 | } | 373 | } |
208 | } | 374 | } |
209 | 375 | ||
210 | return resize_tiled(amount, axis); | 376 | resize_tiled(amount->amount, axis); |
377 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
211 | } | 378 | } |
212 | 379 | ||
213 | struct cmd_results *cmd_resize(int argc, char **argv) { | 380 | /** |
214 | struct sway_container *current = config->handler_context.current_container; | 381 | * Implement `resize set` for a tiled container. |
215 | if (!current) { | 382 | */ |
216 | return cmd_results_new(CMD_INVALID, "resize", "Cannot resize nothing"); | 383 | static struct cmd_results *resize_set_tiled(struct sway_container *con, |
217 | } | 384 | struct resize_amount *width, struct resize_amount *height) { |
218 | if (current->type != C_VIEW && current->type != C_CONTAINER) { | 385 | return cmd_results_new(CMD_INVALID, "resize", |
219 | return cmd_results_new(CMD_INVALID, "resize", | 386 | "'resize set' is not implemented for tiled views"); |
220 | "Can only resize views/containers"); | 387 | } |
388 | |||
389 | /** | ||
390 | * Implement `resize set` for a floating container. | ||
391 | */ | ||
392 | static struct cmd_results *resize_set_floating(struct sway_container *con, | ||
393 | struct resize_amount *width, struct resize_amount *height) { | ||
394 | int min_width, max_width, min_height, max_height; | ||
395 | calculate_constraints(&min_width, &max_width, &min_height, &max_height); | ||
396 | width->amount = fmax(min_width, fmin(width->amount, max_width)); | ||
397 | height->amount = fmax(min_height, fmin(height->amount, max_height)); | ||
398 | int grow_width = width->amount - con->width; | ||
399 | int grow_height = height->amount - con->height; | ||
400 | con->x -= grow_width / 2; | ||
401 | con->y -= grow_height / 2; | ||
402 | con->width = width->amount; | ||
403 | con->height = height->amount; | ||
404 | |||
405 | if (con->type == C_VIEW) { | ||
406 | struct sway_view *view = con->sway_view; | ||
407 | view->x -= grow_width / 2; | ||
408 | view->y -= grow_height / 2; | ||
409 | view->width += grow_width; | ||
410 | view->height += grow_height; | ||
221 | } | 411 | } |
222 | 412 | ||
413 | arrange_windows(con); | ||
414 | |||
415 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
416 | } | ||
417 | |||
418 | /** | ||
419 | * resize set <args> | ||
420 | * | ||
421 | * args: <width> [px|ppt] <height> [px|ppt] | ||
422 | */ | ||
423 | static struct cmd_results *cmd_resize_set(int argc, char **argv) { | ||
223 | struct cmd_results *error; | 424 | struct cmd_results *error; |
224 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { | 425 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { |
225 | return error; | 426 | return error; |
226 | } | 427 | } |
227 | 428 | const char *usage = "Expected 'resize set <width> <height>'"; | |
228 | if (strcasecmp(argv[0], "set") == 0) { | 429 | |
229 | // TODO | 430 | // Width |
230 | //return cmd_resize_set(argc - 1, &argv[1]); | 431 | struct resize_amount width; |
231 | return cmd_results_new(CMD_INVALID, "resize", "resize set unimplemented"); | 432 | int num_consumed_args = parse_resize_amount(argc, argv, &width); |
433 | argc -= num_consumed_args; | ||
434 | argv += num_consumed_args; | ||
435 | if (width.unit == RESIZE_UNIT_INVALID) { | ||
436 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
437 | } | ||
438 | if (!argc) { | ||
439 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
232 | } | 440 | } |
233 | 441 | ||
234 | // TODO: resize grow|shrink left|right|up|down | 442 | // Height |
443 | struct resize_amount height; | ||
444 | num_consumed_args = parse_resize_amount(argc, argv, &height); | ||
445 | argc -= num_consumed_args; | ||
446 | argv += num_consumed_args; | ||
447 | if (height.unit == RESIZE_UNIT_INVALID) { | ||
448 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
449 | } | ||
235 | 450 | ||
236 | const char *usage = "Expected 'resize <shrink|grow> " | 451 | // If 0, don't resize that dimension |
237 | "<width|height> [<amount>] [px|ppt]'"; | 452 | struct sway_container *con = config->handler_context.current_container; |
453 | if (width.amount <= 0) { | ||
454 | width.amount = con->width; | ||
455 | } | ||
456 | if (height.amount <= 0) { | ||
457 | height.amount = con->height; | ||
458 | } | ||
238 | 459 | ||
239 | int multiplier = 0; | 460 | if (container_is_floating(con)) { |
240 | if (strcasecmp(*argv, "grow") == 0) { | 461 | return resize_set_floating(con, &width, &height); |
241 | multiplier = 1; | ||
242 | } else if (strcasecmp(*argv, "shrink") == 0) { | ||
243 | multiplier = -1; | ||
244 | } else { | ||
245 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
246 | } | 462 | } |
247 | --argc; ++argv; | 463 | return resize_set_tiled(con, &width, &height); |
464 | } | ||
248 | 465 | ||
466 | /** | ||
467 | * resize <grow|shrink> <args> | ||
468 | * | ||
469 | * args: <direction> | ||
470 | * args: <direction> <amount> <unit> | ||
471 | * args: <direction> <amount> <unit> or <amount> <other_unit> | ||
472 | */ | ||
473 | static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | ||
474 | int multiplier) { | ||
475 | const char *usage = "Expected 'resize grow|shrink <direction> " | ||
476 | "[<amount> px|ppt [or <amount> px|ppt]]'"; | ||
249 | enum resize_axis axis = parse_resize_axis(*argv); | 477 | enum resize_axis axis = parse_resize_axis(*argv); |
250 | if (axis == RESIZE_AXIS_INVALID) { | 478 | if (axis == RESIZE_AXIS_INVALID) { |
251 | return cmd_results_new(CMD_INVALID, "resize", usage); | 479 | return cmd_results_new(CMD_INVALID, "resize", usage); |
252 | } | 480 | } |
253 | --argc; ++argv; | 481 | --argc; ++argv; |
254 | 482 | ||
255 | int amount = 10; // Default amount | 483 | // First amount |
256 | enum resize_unit unit = RESIZE_UNIT_DEFAULT; | 484 | struct resize_amount first_amount; |
257 | |||
258 | if (argc) { | 485 | if (argc) { |
259 | char *err; | 486 | int num_consumed_args = parse_resize_amount(argc, argv, &first_amount); |
260 | amount = (int)strtol(*argv, &err, 10); | 487 | argc -= num_consumed_args; |
261 | if (*err) { | 488 | argv += num_consumed_args; |
262 | // e.g. `resize grow width 10px` | 489 | if (first_amount.unit == RESIZE_UNIT_INVALID) { |
263 | unit = parse_resize_unit(err); | 490 | return cmd_results_new(CMD_INVALID, "resize", usage); |
264 | if (unit == RESIZE_UNIT_INVALID) { | ||
265 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
266 | } | ||
267 | } | 491 | } |
268 | --argc; ++argv; | 492 | } else { |
493 | first_amount.amount = 10; | ||
494 | first_amount.unit = RESIZE_UNIT_DEFAULT; | ||
269 | } | 495 | } |
270 | 496 | ||
497 | // "or" | ||
271 | if (argc) { | 498 | if (argc) { |
272 | unit = parse_resize_unit(*argv); | 499 | if (strcmp(*argv, "or") != 0) { |
273 | if (unit == RESIZE_UNIT_INVALID) { | ||
274 | return cmd_results_new(CMD_INVALID, "resize", usage); | 500 | return cmd_results_new(CMD_INVALID, "resize", usage); |
275 | } | 501 | } |
276 | --argc; ++argv; | 502 | --argc; ++argv; |
277 | } | 503 | } |
278 | 504 | ||
505 | // Second amount | ||
506 | struct resize_amount second_amount; | ||
279 | if (argc) { | 507 | if (argc) { |
280 | // Provied too many args, the bastard | 508 | int num_consumed_args = parse_resize_amount(argc, argv, &second_amount); |
281 | return cmd_results_new(CMD_INVALID, "resize", usage); | 509 | argc -= num_consumed_args; |
510 | argv += num_consumed_args; | ||
511 | if (second_amount.unit == RESIZE_UNIT_INVALID) { | ||
512 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
513 | } | ||
514 | } else { | ||
515 | second_amount.unit = RESIZE_UNIT_INVALID; | ||
282 | } | 516 | } |
283 | 517 | ||
284 | resize(amount * multiplier, axis, unit); | 518 | first_amount.amount *= multiplier; |
285 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 519 | second_amount.amount *= multiplier; |
520 | |||
521 | struct sway_container *con = config->handler_context.current_container; | ||
522 | if (container_is_floating(con)) { | ||
523 | // Floating containers can only resize in px. Choose an amount which | ||
524 | // uses px, with fallback to an amount that specified no unit. | ||
525 | if (first_amount.unit == RESIZE_UNIT_PX) { | ||
526 | return resize_adjust_floating(axis, &first_amount); | ||
527 | } else if (second_amount.unit == RESIZE_UNIT_PX) { | ||
528 | return resize_adjust_floating(axis, &second_amount); | ||
529 | } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
530 | return resize_adjust_floating(axis, &first_amount); | ||
531 | } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
532 | return resize_adjust_floating(axis, &second_amount); | ||
533 | } else { | ||
534 | return cmd_results_new(CMD_INVALID, "resize", | ||
535 | "Floating containers cannot use ppt measurements"); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | // For tiling, prefer ppt -> default -> px | ||
540 | if (first_amount.unit == RESIZE_UNIT_PPT) { | ||
541 | return resize_adjust_tiled(axis, &first_amount); | ||
542 | } else if (second_amount.unit == RESIZE_UNIT_PPT) { | ||
543 | return resize_adjust_tiled(axis, &second_amount); | ||
544 | } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
545 | return resize_adjust_tiled(axis, &first_amount); | ||
546 | } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
547 | return resize_adjust_tiled(axis, &second_amount); | ||
548 | } else { | ||
549 | return resize_adjust_tiled(axis, &first_amount); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | struct cmd_results *cmd_resize(int argc, char **argv) { | ||
554 | struct sway_container *current = config->handler_context.current_container; | ||
555 | if (!current) { | ||
556 | return cmd_results_new(CMD_INVALID, "resize", "Cannot resize nothing"); | ||
557 | } | ||
558 | if (current->type != C_VIEW && current->type != C_CONTAINER) { | ||
559 | return cmd_results_new(CMD_INVALID, "resize", | ||
560 | "Can only resize views/containers"); | ||
561 | } | ||
562 | |||
563 | struct cmd_results *error; | ||
564 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { | ||
565 | return error; | ||
566 | } | ||
567 | |||
568 | if (strcasecmp(argv[0], "set") == 0) { | ||
569 | return cmd_resize_set(argc - 1, &argv[1]); | ||
570 | } | ||
571 | if (strcasecmp(argv[0], "grow") == 0) { | ||
572 | return cmd_resize_adjust(argc - 1, &argv[1], 1); | ||
573 | } | ||
574 | if (strcasecmp(argv[0], "shrink") == 0) { | ||
575 | return cmd_resize_adjust(argc - 1, &argv[1], -1); | ||
576 | } | ||
577 | |||
578 | const char *usage = "Expected 'resize <shrink|grow> " | ||
579 | "<width|height|up|down|left|right> [<amount>] [px|ppt]'"; | ||
580 | |||
581 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
286 | } | 582 | } |
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c new file mode 100644 index 00000000..ccc07c87 --- /dev/null +++ b/sway/commands/scratchpad.c | |||
@@ -0,0 +1,36 @@ | |||
1 | #include "log.h" | ||
2 | #include "sway/commands.h" | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/scratchpad.h" | ||
5 | #include "sway/tree/container.h" | ||
6 | |||
7 | struct cmd_results *cmd_scratchpad(int argc, char **argv) { | ||
8 | struct cmd_results *error = NULL; | ||
9 | if ((error = checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1))) { | ||
10 | return error; | ||
11 | } | ||
12 | if (strcmp(argv[0], "show") != 0) { | ||
13 | return cmd_results_new(CMD_INVALID, "scratchpad", | ||
14 | "Expected 'scratchpad show'"); | ||
15 | } | ||
16 | if (!root_container.sway_root->scratchpad->length) { | ||
17 | return cmd_results_new(CMD_INVALID, "scratchpad", | ||
18 | "Scratchpad is empty"); | ||
19 | } | ||
20 | |||
21 | if (config->handler_context.using_criteria) { | ||
22 | // If using criteria, this command is executed for every container which | ||
23 | // matches the criteria. If this container isn't in the scratchpad, | ||
24 | // we'll just silently return a success. | ||
25 | struct sway_container *con = config->handler_context.current_container; | ||
26 | wlr_log(WLR_INFO, "cmd_scratchpad(%s)", con->name); | ||
27 | if (!con->scratchpad) { | ||
28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
29 | } | ||
30 | scratchpad_toggle_container(con); | ||
31 | } else { | ||
32 | scratchpad_toggle_auto(); | ||
33 | } | ||
34 | |||
35 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
36 | } | ||
diff --git a/sway/commands/set.c b/sway/commands/set.c index 84e9b792..ea388d3b 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c | |||
@@ -32,7 +32,7 @@ struct cmd_results *cmd_set(int argc, char **argv) { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | if (argv[0][0] != '$') { | 34 | if (argv[0][0] != '$') { |
35 | wlr_log(L_INFO, "Warning: variable '%s' doesn't start with $", argv[0]); | 35 | wlr_log(WLR_INFO, "Warning: variable '%s' doesn't start with $", argv[0]); |
36 | 36 | ||
37 | size_t size = snprintf(NULL, 0, "$%s", argv[0]); | 37 | size_t size = snprintf(NULL, 0, "$%s", argv[0]); |
38 | tmp = malloc(size + 1); | 38 | tmp = malloc(size + 1); |
diff --git a/sway/commands/smart_gaps.c b/sway/commands/smart_gaps.c index f687e78e..7d27e571 100644 --- a/sway/commands/smart_gaps.c +++ b/sway/commands/smart_gaps.c | |||
@@ -23,7 +23,7 @@ struct cmd_results *cmd_smart_gaps(int argc, char **argv) { | |||
23 | "Expected 'smart_gaps <on|off>' "); | 23 | "Expected 'smart_gaps <on|off>' "); |
24 | } | 24 | } |
25 | 25 | ||
26 | arrange_and_commit(&root_container); | 26 | arrange_windows(&root_container); |
27 | 27 | ||
28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
29 | } | 29 | } |
diff --git a/sway/commands/split.c b/sway/commands/split.c index c40f4d9f..313799da 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c | |||
@@ -16,7 +16,7 @@ static struct cmd_results *do_split(int layout) { | |||
16 | } | 16 | } |
17 | struct sway_container *parent = container_split(con, layout); | 17 | struct sway_container *parent = container_split(con, layout); |
18 | container_create_notify(parent); | 18 | container_create_notify(parent); |
19 | arrange_and_commit(parent->parent); | 19 | arrange_windows(parent->parent); |
20 | 20 | ||
21 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 21 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
22 | } | 22 | } |
diff --git a/sway/commands/swap.c b/sway/commands/swap.c index e052058f..2fc88308 100644 --- a/sway/commands/swap.c +++ b/sway/commands/swap.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #include <strings.h> | 1 | #include <strings.h> |
2 | #include <wlr/util/log.h> | 2 | #include <wlr/util/log.h> |
3 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
4 | #include "sway/desktop/transaction.h" | ||
5 | #include "sway/tree/arrange.h" | 4 | #include "sway/tree/arrange.h" |
6 | #include "sway/tree/layout.h" | 5 | #include "sway/tree/layout.h" |
7 | #include "sway/tree/view.h" | 6 | #include "sway/tree/view.h" |
@@ -79,14 +78,10 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
79 | 78 | ||
80 | container_swap(current, other); | 79 | container_swap(current, other); |
81 | 80 | ||
82 | struct sway_transaction *txn = transaction_create(); | 81 | arrange_windows(current->parent); |
83 | arrange_windows(current->parent, txn); | ||
84 | |||
85 | if (other->parent != current->parent) { | 82 | if (other->parent != current->parent) { |
86 | arrange_windows(other->parent, txn); | 83 | arrange_windows(other->parent); |
87 | } | 84 | } |
88 | 85 | ||
89 | transaction_commit(txn); | ||
90 | |||
91 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 86 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
92 | } | 87 | } |
diff --git a/sway/commands/swaybg_command.c b/sway/commands/swaybg_command.c index 770d4821..36f7fdcd 100644 --- a/sway/commands/swaybg_command.c +++ b/sway/commands/swaybg_command.c | |||
@@ -13,7 +13,7 @@ struct cmd_results *cmd_swaybg_command(int argc, char **argv) { | |||
13 | free(config->swaybg_command); | 13 | free(config->swaybg_command); |
14 | } | 14 | } |
15 | config->swaybg_command = join_args(argv, argc); | 15 | config->swaybg_command = join_args(argv, argc); |
16 | wlr_log(L_DEBUG, "Using custom swaybg command: %s", | 16 | wlr_log(WLR_DEBUG, "Using custom swaybg command: %s", |
17 | config->swaybg_command); | 17 | config->swaybg_command); |
18 | 18 | ||
19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 19 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/urgent.c b/sway/commands/urgent.c new file mode 100644 index 00000000..d199858a --- /dev/null +++ b/sway/commands/urgent.c | |||
@@ -0,0 +1,36 @@ | |||
1 | #include "log.h" | ||
2 | #include "sway/commands.h" | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/tree/arrange.h" | ||
5 | #include "sway/tree/container.h" | ||
6 | #include "sway/tree/view.h" | ||
7 | #include "sway/tree/layout.h" | ||
8 | |||
9 | struct cmd_results *cmd_urgent(int argc, char **argv) { | ||
10 | struct cmd_results *error = NULL; | ||
11 | if ((error = checkarg(argc, "urgent", EXPECTED_EQUAL_TO, 1))) { | ||
12 | return error; | ||
13 | } | ||
14 | struct sway_container *container = | ||
15 | config->handler_context.current_container; | ||
16 | if (container->type != C_VIEW) { | ||
17 | return cmd_results_new(CMD_INVALID, "urgent", | ||
18 | "Only views can be urgent"); | ||
19 | } | ||
20 | struct sway_view *view = container->sway_view; | ||
21 | |||
22 | if (strcmp(argv[0], "enable") == 0) { | ||
23 | view_set_urgent(view, true); | ||
24 | } else if (strcmp(argv[0], "disable") == 0) { | ||
25 | view_set_urgent(view, false); | ||
26 | } else if (strcmp(argv[0], "allow") == 0) { | ||
27 | view->allow_request_urgent = true; | ||
28 | } else if (strcmp(argv[0], "deny") == 0) { | ||
29 | view->allow_request_urgent = false; | ||
30 | } else { | ||
31 | return cmd_results_new(CMD_INVALID, "urgent", | ||
32 | "Expected 'urgent <enable|disable|allow|deny>'"); | ||
33 | } | ||
34 | |||
35 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
36 | } | ||
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index d15be571..e8b37182 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -51,7 +51,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
51 | free(old); // workspaces can only be assigned to a single output | 51 | free(old); // workspaces can only be assigned to a single output |
52 | list_del(config->workspace_outputs, i); | 52 | list_del(config->workspace_outputs, i); |
53 | } | 53 | } |
54 | wlr_log(L_DEBUG, "Assigning workspace %s to output %s", wso->workspace, wso->output); | 54 | wlr_log(WLR_DEBUG, "Assigning workspace %s to output %s", wso->workspace, wso->output); |
55 | list_add(config->workspace_outputs, wso); | 55 | list_add(config->workspace_outputs, wso); |
56 | } else { | 56 | } else { |
57 | if (config->reading || !config->active) { | 57 | if (config->reading || !config->active) { |