aboutsummaryrefslogtreecommitdiff
path: root/sway/commands
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands')
-rw-r--r--sway/commands/bind.c218
-rw-r--r--sway/commands/exec_always.c6
-rw-r--r--sway/commands/floating.c21
-rw-r--r--sway/commands/floating_modifier.c30
-rw-r--r--sway/commands/focus.c25
-rw-r--r--sway/commands/focus_follows_mouse.c4
-rw-r--r--sway/commands/focus_wrapping.c12
-rw-r--r--sway/commands/force_focus_wrapping.c8
-rw-r--r--sway/commands/fullscreen.c28
-rw-r--r--sway/commands/input.c21
-rw-r--r--sway/commands/input/drag_lock.c9
-rw-r--r--sway/commands/input/dwt.c9
-rw-r--r--sway/commands/input/left_handed.c11
-rw-r--r--sway/commands/input/middle_emulation.c9
-rw-r--r--sway/commands/input/natural_scroll.c11
-rw-r--r--sway/commands/input/tap.c9
-rw-r--r--sway/commands/input/xkb_capslock.c33
-rw-r--r--sway/commands/input/xkb_numlock.c33
-rw-r--r--sway/commands/mark.c2
-rw-r--r--sway/commands/mode.c1
-rw-r--r--sway/commands/move.c43
-rw-r--r--sway/commands/output/dpms.c8
-rw-r--r--sway/commands/reload.c29
-rw-r--r--sway/commands/scratchpad.c44
-rw-r--r--sway/commands/show_marks.c10
-rw-r--r--sway/commands/split.c4
-rw-r--r--sway/commands/swap.c7
-rw-r--r--sway/commands/urgent.c10
28 files changed, 494 insertions, 161 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index 83e9e432..8270b958 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -1,3 +1,4 @@
+#define _XOPEN_SOURCE 500
#ifdef __linux__
#include <linux/input-event-codes.h>
#elif __FreeBSD__
@@ -5,9 +6,11 @@
#endif
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-names.h>
+#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
@@ -27,6 +30,33 @@ void free_sway_binding(struct sway_binding *binding) {
free(binding);
}
+static struct sway_binding *sway_binding_dup(struct sway_binding *sb) {
+ struct sway_binding *new_sb = calloc(1, sizeof(struct sway_binding));
+ if (!new_sb) {
+ return NULL;
+ }
+
+ new_sb->type = sb->type;
+ new_sb->order = sb->order;
+ new_sb->flags = sb->flags;
+ new_sb->modifiers = sb->modifiers;
+ new_sb->command = strdup(sb->command);
+
+ new_sb->keys = create_list();
+ int i;
+ for (i = 0; i < sb->keys->length; ++i) {
+ xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
+ if (!key) {
+ free_sway_binding(new_sb);
+ return NULL;
+ }
+ *key = *(xkb_keysym_t *)sb->keys->items[i];
+ list_add(new_sb->keys, key);
+ }
+
+ return new_sb;
+}
+
/**
* Returns true if the bindings have the same key and modifier combinations.
* Note that keyboard layout is not considered, so the bindings might actually
@@ -34,11 +64,14 @@ void free_sway_binding(struct sway_binding *binding) {
*/
static bool binding_key_compare(struct sway_binding *binding_a,
struct sway_binding *binding_b) {
- if (binding_a->release != binding_b->release) {
+ if (binding_a->type != binding_b->type) {
return false;
}
- if (binding_a->bindcode != binding_b->bindcode) {
+ uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER
+ | BINDING_CONTENTS | BINDING_TITLEBAR;
+ if ((binding_a->flags & conflict_generating_flags) !=
+ (binding_b->flags & conflict_generating_flags)) {
return false;
}
@@ -69,6 +102,66 @@ static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) {
return (key_a < key_b) ? -1 : ((key_a > key_b) ? 1 : 0);
}
+
+/**
+ * From a keycode, bindcode, or bindsym name and the most likely binding type,
+ * identify the appropriate numeric value corresponding to the key. Return NULL
+ * and set *key_val if successful, otherwise return a specific error. Change
+ * the value of *type if the initial type guess was incorrect and if this
+ * was the first identified key.
+ */
+static struct cmd_results *identify_key(const char* name, bool first_key,
+ uint32_t* key_val, enum binding_input_type* type) {
+ if (*type == BINDING_KEYCODE) {
+ // check for keycode
+ xkb_keycode_t keycode = strtol(name, NULL, 10);
+ if (!xkb_keycode_is_legal_ext(keycode)) {
+ return cmd_results_new(CMD_INVALID, "bindcode",
+ "Invalid keycode '%s'", name);
+ }
+ *key_val = keycode;
+ } else {
+ // check for keysym
+ xkb_keysym_t keysym = xkb_keysym_from_name(name,
+ XKB_KEYSYM_CASE_INSENSITIVE);
+
+ // Check for mouse binding
+ uint32_t button = 0;
+ if (strncasecmp(name, "button", strlen("button")) == 0 &&
+ strlen(name) == strlen("button0")) {
+ button = name[strlen("button")] - '1' + BTN_LEFT;
+ }
+
+ if (*type == BINDING_KEYSYM) {
+ if (button) {
+ if (first_key) {
+ *type = BINDING_MOUSE;
+ *key_val = button;
+ } else {
+ return cmd_results_new(CMD_INVALID, "bindsym",
+ "Mixed button '%s' into key sequence", name);
+ }
+ } else if (keysym) {
+ *key_val = keysym;
+ } else {
+ return cmd_results_new(CMD_INVALID, "bindsym",
+ "Unknown key '%s'", name);
+ }
+ } else {
+ if (button) {
+ *key_val = button;
+ } else if (keysym) {
+ return cmd_results_new(CMD_INVALID, "bindsym",
+ "Mixed keysym '%s' into button sequence", name);
+ } else {
+ return cmd_results_new(CMD_INVALID, "bindsym",
+ "Unknown button '%s'", name);
+ }
+ }
+ }
+ return NULL;
+}
+
static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
bool bindcode) {
const char *bindtype = bindcode ? "bindcode" : "bindsym";
@@ -85,22 +178,34 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
}
binding->keys = create_list();
binding->modifiers = 0;
- binding->release = false;
- binding->locked = false;
- binding->bindcode = bindcode;
+ binding->flags = 0;
+ binding->type = bindcode ? BINDING_KEYCODE : BINDING_KEYSYM;
+
+ bool exclude_titlebar = false;
// Handle --release and --locked
while (argc > 0) {
if (strcmp("--release", argv[0]) == 0) {
- binding->release = true;
+ binding->flags |= BINDING_RELEASE;
} else if (strcmp("--locked", argv[0]) == 0) {
- binding->locked = true;
+ binding->flags |= BINDING_LOCKED;
+ } else if (strcmp("--whole-window", argv[0]) == 0) {
+ binding->flags |= BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR;
+ } else if (strcmp("--border", argv[0]) == 0) {
+ binding->flags |= BINDING_BORDER;
+ } else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
+ exclude_titlebar = true;
} else {
break;
}
argv++;
argc--;
}
+ if (binding->flags & (BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR)
+ || exclude_titlebar) {
+ binding->type = BINDING_MOUSE;
+ }
+
if (argc < 2) {
free_sway_binding(binding);
return cmd_results_new(CMD_FAILURE, bindtype,
@@ -119,64 +224,47 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
continue;
}
- xkb_keycode_t keycode;
- xkb_keysym_t keysym;
- if (bindcode) {
- // parse keycode
- keycode = (int)strtol(split->items[i], NULL, 10);
- if (!xkb_keycode_is_legal_ext(keycode)) {
- error =
- cmd_results_new(CMD_INVALID, "bindcode",
- "Invalid keycode '%s'", (char *)split->items[i]);
- free_sway_binding(binding);
- list_free(split);
- return error;
- }
- } else {
- // Check for xkb key
- keysym = xkb_keysym_from_name(split->items[i],
- XKB_KEYSYM_CASE_INSENSITIVE);
-
- // Check for mouse binding
- if (strncasecmp(split->items[i], "button", strlen("button")) == 0 &&
- strlen(split->items[i]) == strlen("button0")) {
- keysym = ((char *)split->items[i])[strlen("button")] - '1' + BTN_LEFT;
- }
- if (!keysym) {
- struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym",
- "Unknown key '%s'", (char *)split->items[i]);
- free_sway_binding(binding);
- free_flat_list(split);
- return ret;
- }
+ // Identify the key and possibly change binding->type
+ uint32_t key_val = 0;
+ error = identify_key(split->items[i], binding->keys->length == 0,
+ &key_val, &binding->type);
+ if (error) {
+ free_sway_binding(binding);
+ list_free(split);
+ return error;
}
+
uint32_t *key = calloc(1, sizeof(uint32_t));
if (!key) {
free_sway_binding(binding);
free_flat_list(split);
return cmd_results_new(CMD_FAILURE, bindtype,
- "Unable to allocate binding");
- }
-
- if (bindcode) {
- *key = (uint32_t)keycode;
- } else {
- *key = (uint32_t)keysym;
+ "Unable to allocate binding key");
}
-
+ *key = key_val;
list_add(binding->keys, key);
}
free_flat_list(split);
binding->order = binding_order++;
+ // refine region of interest for mouse binding once we are certain
+ // that this is one
+ if (exclude_titlebar) {
+ binding->flags &= ~BINDING_TITLEBAR;
+ } else if (binding->type == BINDING_MOUSE) {
+ binding->flags |= BINDING_TITLEBAR;
+ }
+
// sort ascending
list_qsort(binding->keys, key_qsort_cmp);
list_t *mode_bindings;
- if (bindcode) {
+ if (binding->type == BINDING_KEYCODE) {
mode_bindings = config->current_mode->keycode_bindings;
- } else {
+ } else if (binding->type == BINDING_KEYSYM) {
mode_bindings = config->current_mode->keysym_bindings;
+ } else {
+ mode_bindings = config->current_mode->mouse_bindings;
}
// overwrite the binding if it already exists
@@ -209,3 +297,39 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) {
struct cmd_results *cmd_bindcode(int argc, char **argv) {
return cmd_bindsym_or_bindcode(argc, argv, true);
}
+
+
+/**
+ * Execute the command associated to a binding
+ */
+void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
+ wlr_log(WLR_DEBUG, "running command for binding: %s",
+ binding->command);
+
+ struct sway_binding *binding_copy = binding;
+ bool reload = false;
+ // if this is a reload command we need to make a duplicate of the
+ // binding since it will be gone after the reload has completed.
+ if (strcasecmp(binding->command, "reload") == 0) {
+ reload = true;
+ binding_copy = sway_binding_dup(binding);
+ if (!binding_copy) {
+ wlr_log(WLR_ERROR, "Failed to duplicate binding during reload");
+ return;
+ }
+ }
+
+ config->handler_context.seat = seat;
+ struct cmd_results *results = execute_command(binding->command, NULL);
+ if (results->status == CMD_SUCCESS) {
+ ipc_event_binding(binding_copy);
+ } else {
+ wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
+ binding->command, results->error);
+ }
+
+ if (reload) { // free the binding if we made a copy
+ free_sway_binding(binding_copy);
+ }
+ free_cmd_results(results);
+}
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index c7727857..c730cb8b 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <signal.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/container.h"
@@ -47,6 +48,9 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
if ((pid = fork()) == 0) {
// Fork child process again
setsid();
+ sigset_t set;
+ sigemptyset(&set);
+ sigprocmask(SIG_SETMASK, &set, NULL);
close(fd[0]);
if ((child = fork()) == 0) {
close(fd[1]);
@@ -74,7 +78,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
waitpid(pid, NULL, 0);
if (child > 0) {
wlr_log(WLR_DEBUG, "Child process created with pid %d", child);
- // TODO: add PID to active workspace
+ workspace_record_pid(child);
} else {
return cmd_results_new(CMD_FAILURE, "exec_always",
"Second fork() failed");
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index 6ab56c3b..31de5ec3 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -17,9 +17,24 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
}
struct sway_container *container =
config->handler_context.current_container;
- if (container->type != C_VIEW) {
- // TODO: This doesn't strictly speaking have to be true
- return cmd_results_new(CMD_INVALID, "float", "Only views can float");
+ if (container->type == C_WORKSPACE && container->children->length == 0) {
+ return cmd_results_new(CMD_INVALID, "floating",
+ "Can't float an empty workspace");
+ }
+ if (container->type == C_WORKSPACE) {
+ // Wrap the workspace's children in a container so we can float it
+ struct sway_container *workspace = container;
+ container = container_wrap_children(container);
+ workspace->layout = L_HORIZ;
+ seat_set_focus(config->handler_context.seat, container);
+ }
+
+ // If the container is in a floating split container,
+ // operate on the split container instead of the child.
+ if (container_is_floating_or_child(container)) {
+ while (container->parent->layout != L_FLOATING) {
+ container = container->parent;
+ }
}
bool wants_floating;
diff --git a/sway/commands/floating_modifier.c b/sway/commands/floating_modifier.c
new file mode 100644
index 00000000..f5d2b3fe
--- /dev/null
+++ b/sway/commands/floating_modifier.c
@@ -0,0 +1,30 @@
+#include "strings.h"
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "util.h"
+
+struct cmd_results *cmd_floating_modifier(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+
+ uint32_t mod = get_modifier_mask_by_name(argv[0]);
+ if (!mod) {
+ return cmd_results_new(CMD_INVALID, "floating_modifier",
+ "Invalid modifier");
+ }
+
+ if (argc == 1 || strcasecmp(argv[1], "normal") == 0) {
+ config->floating_mod_inverse = false;
+ } else if (strcasecmp(argv[1], "inverse") == 0) {
+ config->floating_mod_inverse = true;
+ } else {
+ return cmd_results_new(CMD_INVALID, "floating_modifier",
+ "Usage: floating_modifier <mod> [inverse|normal]");
+ }
+
+ config->floating_mod = mod;
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 9cd8bfae..76d3f1dc 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -35,14 +35,25 @@ static struct cmd_results *focus_mode(struct sway_container *con,
struct sway_seat *seat, bool floating) {
struct sway_container *ws = con->type == C_WORKSPACE ?
con : container_parent(con, C_WORKSPACE);
- struct sway_container *new_focus = ws;
- if (floating) {
- new_focus = ws->sway_workspace->floating;
- if (new_focus->children->length == 0) {
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+
+ // If the container is in a floating split container,
+ // operate on the split container instead of the child.
+ if (container_is_floating_or_child(con)) {
+ while (con->parent->layout != L_FLOATING) {
+ con = con->parent;
}
}
- seat_set_focus(seat, seat_get_active_child(seat, new_focus));
+
+ struct sway_container *new_focus = NULL;
+ if (floating) {
+ new_focus = seat_get_focus_inactive(seat, ws->sway_workspace->floating);
+ } else {
+ new_focus = seat_get_focus_inactive_tiling(seat, ws);
+ }
+ if (!new_focus) {
+ new_focus = ws;
+ }
+ seat_set_focus(seat, new_focus);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
@@ -97,7 +108,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
} else if (strcmp(argv[0], "tiling") == 0) {
return focus_mode(con, seat, false);
} else if (strcmp(argv[0], "mode_toggle") == 0) {
- return focus_mode(con, seat, !container_is_floating(con));
+ return focus_mode(con, seat, !container_is_floating_or_child(con));
}
if (strcmp(argv[0], "output") == 0) {
diff --git a/sway/commands/focus_follows_mouse.c b/sway/commands/focus_follows_mouse.c
index 661e7852..0b0e334c 100644
--- a/sway/commands/focus_follows_mouse.c
+++ b/sway/commands/focus_follows_mouse.c
@@ -1,12 +1,14 @@
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
+#include "util.h"
struct cmd_results *cmd_focus_follows_mouse(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1))) {
return error;
}
- config->focus_follows_mouse = !strcasecmp(argv[0], "yes");
+ config->focus_follows_mouse =
+ parse_boolean(argv[0], config->focus_follows_mouse);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/commands/focus_wrapping.c b/sway/commands/focus_wrapping.c
index 0a9e0bf2..562ee4f9 100644
--- a/sway/commands/focus_wrapping.c
+++ b/sway/commands/focus_wrapping.c
@@ -1,6 +1,7 @@
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "util.h"
struct cmd_results *cmd_focus_wrapping(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -8,15 +9,12 @@ struct cmd_results *cmd_focus_wrapping(int argc, char **argv) {
return error;
}
- if (strcasecmp(argv[0], "no") == 0) {
- config->focus_wrapping = WRAP_NO;
- } else if (strcasecmp(argv[0], "yes") == 0) {
- config->focus_wrapping = WRAP_YES;
- } else if (strcasecmp(argv[0], "force") == 0) {
+ if (strcasecmp(argv[0], "force") == 0) {
config->focus_wrapping = WRAP_FORCE;
+ } else if (parse_boolean(argv[0], config->focus_wrapping == WRAP_YES)) {
+ config->focus_wrapping = WRAP_YES;
} else {
- return cmd_results_new(CMD_INVALID, "focus_wrapping",
- "Expected 'focus_wrapping yes|no|force'");
+ config->focus_wrapping = WRAP_NO;
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/force_focus_wrapping.c b/sway/commands/force_focus_wrapping.c
index bc1d067f..0892d9e9 100644
--- a/sway/commands/force_focus_wrapping.c
+++ b/sway/commands/force_focus_wrapping.c
@@ -1,6 +1,7 @@
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "util.h"
struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) {
struct cmd_results *error =
@@ -9,13 +10,10 @@ struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) {
return error;
}
- if (strcasecmp(argv[0], "no") == 0) {
- config->focus_wrapping = WRAP_YES;
- } else if (strcasecmp(argv[0], "yes") == 0) {
+ if (parse_boolean(argv[0], config->focus_wrapping == WRAP_FORCE)) {
config->focus_wrapping = WRAP_FORCE;
} else {
- return cmd_results_new(CMD_INVALID, "force_focus_wrapping",
- "Expected 'force_focus_wrapping yes|no'");
+ config->focus_wrapping = WRAP_YES;
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index 0b5beaa2..5ad06e40 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -5,6 +5,7 @@
#include "sway/tree/container.h"
#include "sway/tree/view.h"
#include "sway/tree/layout.h"
+#include "util.h"
struct cmd_results *cmd_fullscreen(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -13,25 +14,24 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
}
struct sway_container *container =
config->handler_context.current_container;
- if (container->type != C_VIEW) {
+ if (container->type == C_WORKSPACE && container->children->length == 0) {
return cmd_results_new(CMD_INVALID, "fullscreen",
- "Only views can fullscreen");
+ "Can't fullscreen an empty workspace");
}
- struct sway_view *view = container->sway_view;
- bool wants_fullscreen;
+ if (container->type == C_WORKSPACE) {
+ // Wrap the workspace's children in a container so we can fullscreen it
+ struct sway_container *workspace = container;
+ container = container_wrap_children(container);
+ workspace->layout = L_HORIZ;
+ seat_set_focus(config->handler_context.seat, container);
+ }
+ bool enable = !container->is_fullscreen;
- if (argc == 0 || strcmp(argv[0], "toggle") == 0) {
- wants_fullscreen = !view->is_fullscreen;
- } else if (strcmp(argv[0], "enable") == 0) {
- wants_fullscreen = true;
- } else if (strcmp(argv[0], "disable") == 0) {
- wants_fullscreen = false;
- } else {
- return cmd_results_new(CMD_INVALID, "fullscreen",
- "Expected 'fullscreen' or 'fullscreen <enable|disable|toggle>'");
+ if (argc) {
+ enable = parse_boolean(argv[0], container->is_fullscreen);
}
- view_set_fullscreen(view, wants_fullscreen);
+ container_set_fullscreen(container, enable);
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
arrange_windows(workspace->parent);
diff --git a/sway/commands/input.c b/sway/commands/input.c
index 5b203ea0..84888fbb 100644
--- a/sway/commands/input.c
+++ b/sway/commands/input.c
@@ -31,6 +31,12 @@ static struct cmd_handler input_handlers[] = {
{ "xkb_variant", input_cmd_xkb_variant },
};
+// must be in order for the bsearch
+static struct cmd_handler input_config_handlers[] = {
+ { "xkb_capslock", input_cmd_xkb_capslock },
+ { "xkb_numlock", input_cmd_xkb_numlock },
+};
+
struct cmd_results *cmd_input(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "input", EXPECTED_AT_LEAST, 2))) {
@@ -44,8 +50,21 @@ struct cmd_results *cmd_input(int argc, char **argv) {
return cmd_results_new(CMD_FAILURE, NULL, "Couldn't allocate config");
}
- struct cmd_results *res = config_subcommand(argv + 1, argc - 1,
+ struct cmd_results *res;
+
+ if (find_handler(argv[1], input_config_handlers,
+ sizeof(input_config_handlers))) {
+ if (config->reading) {
+ res = config_subcommand(argv + 1, argc - 1,
+ input_config_handlers, sizeof(input_config_handlers));
+ } else {
+ res = cmd_results_new(CMD_FAILURE, "input",
+ "Can only be used in config file.");
+ }
+ } else {
+ res = config_subcommand(argv + 1, argc - 1,
input_handlers, sizeof(input_handlers));
+ }
free_input_config(config->handler_context.input_config);
config->handler_context.input_config = NULL;
diff --git a/sway/commands/input/drag_lock.c b/sway/commands/input/drag_lock.c
index 9e32816f..f9ddeef2 100644
--- a/sway/commands/input/drag_lock.c
+++ b/sway/commands/input/drag_lock.c
@@ -3,6 +3,7 @@
#include "sway/config.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "util.h"
struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -18,14 +19,10 @@ struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
+ if (parse_boolean(argv[0], true)) {
new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
} else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "drag_lock",
- "Expected 'drag_lock <enabled|disabled>'");
+ new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
}
apply_input_config(new_config);
diff --git a/sway/commands/input/dwt.c b/sway/commands/input/dwt.c
index 73937507..15134268 100644
--- a/sway/commands/input/dwt.c
+++ b/sway/commands/input/dwt.c
@@ -3,6 +3,7 @@
#include "sway/config.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "util.h"
struct cmd_results *input_cmd_dwt(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -17,14 +18,10 @@ struct cmd_results *input_cmd_dwt(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
+ if (parse_boolean(argv[0], true)) {
new_config->dwt = LIBINPUT_CONFIG_DWT_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
} else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "dwt",
- "Expected 'dwt <enabled|disabled>'");
+ new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
}
apply_input_config(new_config);
diff --git a/sway/commands/input/left_handed.c b/sway/commands/input/left_handed.c
index 769ce98c..e770043a 100644
--- a/sway/commands/input/left_handed.c
+++ b/sway/commands/input/left_handed.c
@@ -3,6 +3,7 @@
#include "sway/config.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "util.h"
struct cmd_results *input_cmd_left_handed(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -18,15 +19,7 @@ struct cmd_results *input_cmd_left_handed(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->left_handed = 1;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->left_handed = 0;
- } else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "left_handed",
- "Expected 'left_handed <enabled|disabled>'");
- }
+ new_config->left_handed = parse_boolean(argv[0], true);
apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/input/middle_emulation.c b/sway/commands/input/middle_emulation.c
index 7ca01629..414d4d2b 100644
--- a/sway/commands/input/middle_emulation.c
+++ b/sway/commands/input/middle_emulation.c
@@ -3,6 +3,7 @@
#include "sway/config.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "util.h"
struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -18,15 +19,11 @@ struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
+ if (parse_boolean(argv[0], true)) {
new_config->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
+ } else {
new_config->middle_emulation =
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
- } else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "middle_emulation",
- "Expected 'middle_emulation <enabled|disabled>'");
}
apply_input_config(new_config);
diff --git a/sway/commands/input/natural_scroll.c b/sway/commands/input/natural_scroll.c
index 55236790..77c3ff00 100644
--- a/sway/commands/input/natural_scroll.c
+++ b/sway/commands/input/natural_scroll.c
@@ -3,6 +3,7 @@
#include "sway/config.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h"
+#include "util.h"
struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -18,15 +19,7 @@ struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->natural_scroll = 1;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->natural_scroll = 0;
- } else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "natural_scroll",
- "Expected 'natural_scroll <enabled|disabled>'");
- }
+ new_config->natural_scroll = parse_boolean(argv[0], true);
apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/input/tap.c b/sway/commands/input/tap.c
index a8d1a10c..ac3b8237 100644
--- a/sway/commands/input/tap.c
+++ b/sway/commands/input/tap.c
@@ -4,6 +4,7 @@
#include "sway/commands.h"
#include "sway/input/input-manager.h"
#include "log.h"
+#include "util.h"
struct cmd_results *input_cmd_tap(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -18,14 +19,10 @@ struct cmd_results *input_cmd_tap(int argc, char **argv) {
struct input_config *new_config =
new_input_config(current_input_config->identifier);
- if (strcasecmp(argv[0], "enabled") == 0) {
+ if (parse_boolean(argv[0], true)) {
new_config->tap = LIBINPUT_CONFIG_TAP_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED;
} else {
- free_input_config(new_config);
- return cmd_results_new(CMD_INVALID, "tap",
- "Expected 'tap <enabled|disabled>'");
+ new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED;
}
wlr_log(WLR_DEBUG, "apply-tap for device: %s",
diff --git a/sway/commands/input/xkb_capslock.c b/sway/commands/input/xkb_capslock.c
new file mode 100644
index 00000000..5442c463
--- /dev/null
+++ b/sway/commands/input/xkb_capslock.c
@@ -0,0 +1,33 @@
+#include <string.h>
+#include <strings.h>
+#include "sway/config.h"
+#include "sway/commands.h"
+#include "sway/input/input-manager.h"
+
+struct cmd_results *input_cmd_xkb_capslock(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "xkb_capslock", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+ struct input_config *current_input_config =
+ config->handler_context.input_config;
+ if (!current_input_config) {
+ return cmd_results_new(CMD_FAILURE, "xkb_capslock",
+ "No input device defined.");
+ }
+ struct input_config *new_config =
+ new_input_config(current_input_config->identifier);
+
+ if (strcasecmp(argv[0], "enabled") == 0) {
+ new_config->xkb_capslock = 1;
+ } else if (strcasecmp(argv[0], "disabled") == 0) {
+ new_config->xkb_capslock = 0;
+ } else {
+ free_input_config(new_config);
+ return cmd_results_new(CMD_INVALID, "xkb_capslock",
+ "Expected 'xkb_capslock <enabled|disabled>'");
+ }
+
+ apply_input_config(new_config);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/input/xkb_numlock.c b/sway/commands/input/xkb_numlock.c
new file mode 100644
index 00000000..39675366
--- /dev/null
+++ b/sway/commands/input/xkb_numlock.c
@@ -0,0 +1,33 @@
+#include <string.h>
+#include <strings.h>
+#include "sway/config.h"
+#include "sway/commands.h"
+#include "sway/input/input-manager.h"
+
+struct cmd_results *input_cmd_xkb_numlock(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "xkb_numlock", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+ struct input_config *current_input_config =
+ config->handler_context.input_config;
+ if (!current_input_config) {
+ return cmd_results_new(CMD_FAILURE, "xkb_numlock",
+ "No input device defined.");
+ }
+ struct input_config *new_config =
+ new_input_config(current_input_config->identifier);
+
+ if (strcasecmp(argv[0], "enabled") == 0) {
+ new_config->xkb_numlock = 1;
+ } else if (strcasecmp(argv[0], "disabled") == 0) {
+ new_config->xkb_numlock = 0;
+ } else {
+ free_input_config(new_config);
+ return cmd_results_new(CMD_INVALID, "xkb_numlock",
+ "Expected 'xkb_numlock <enabled|disabled>'");
+ }
+
+ apply_input_config(new_config);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/mark.c b/sway/commands/mark.c
index 5a897e69..9ea8c301 100644
--- a/sway/commands/mark.c
+++ b/sway/commands/mark.c
@@ -58,7 +58,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
view_find_and_unmark(mark);
if (!toggle || !had_mark) {
- list_add(view->marks, strdup(mark));
+ view_add_mark(view, mark);
}
free(mark);
diff --git a/sway/commands/mode.c b/sway/commands/mode.c
index b460fcb5..637ca45e 100644
--- a/sway/commands/mode.c
+++ b/sway/commands/mode.c
@@ -56,6 +56,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
mode->name = strdup(mode_name);
mode->keysym_bindings = create_list();
mode->keycode_bindings = create_list();
+ mode->mouse_bindings = create_list();
mode->pango = pango;
list_add(config->modes, mode);
}
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 6ec050a8..702b42d9 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -9,6 +9,7 @@
#include "sway/input/cursor.h"
#include "sway/input/seat.h"
#include "sway/output.h"
+#include "sway/scratchpad.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/layout.h"
@@ -58,8 +59,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
&& strcasecmp(argv[2], "workspace") == 0) {
// move container to workspace x
if (current->type == C_WORKSPACE) {
- // TODO: Wrap children in a container and move that
- return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
+ current = container_wrap_children(current);
} else if (current->type != C_CONTAINER && current->type != C_VIEW) {
return cmd_results_new(CMD_FAILURE, "move",
"Can only move containers and views.");
@@ -97,7 +97,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
container_move_to(current, destination);
struct sway_container *focus = seat_get_focus_inactive(
config->handler_context.seat, old_parent);
- seat_set_focus(config->handler_context.seat, focus);
+ seat_set_focus_warp(config->handler_context.seat, focus, true, false);
container_reap_empty(old_parent);
container_reap_empty(destination->parent);
@@ -134,7 +134,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
struct sway_container *old_parent = current->parent;
struct sway_container *old_ws = container_parent(current, C_WORKSPACE);
container_move_to(current, focus);
- seat_set_focus(config->handler_context.seat, old_parent);
+ seat_set_focus_warp(config->handler_context.seat, old_parent, true, false);
container_reap_empty(old_parent);
container_reap_empty(focus->parent);
@@ -195,7 +195,7 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
"Cannot move workspaces in a direction");
}
if (container_is_floating(container)) {
- if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
+ if (container->is_fullscreen) {
return cmd_results_new(CMD_FAILURE, "move",
"Cannot move fullscreen floating container");
}
@@ -296,6 +296,34 @@ static struct cmd_results *move_to_position(struct sway_container *container,
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
+static struct cmd_results *move_to_scratchpad(struct sway_container *con) {
+ if (con->type == C_WORKSPACE && con->children->length == 0) {
+ return cmd_results_new(CMD_INVALID, "move",
+ "Can't move an empty workspace to the scratchpad");
+ }
+ if (con->type == C_WORKSPACE) {
+ // Wrap the workspace's children in a container
+ struct sway_container *workspace = con;
+ con = container_wrap_children(con);
+ workspace->layout = L_HORIZ;
+ }
+
+ // If the container is in a floating split container,
+ // operate on the split container instead of the child.
+ if (container_is_floating_or_child(con)) {
+ while (con->parent->layout != L_FLOATING) {
+ con = con->parent;
+ }
+ }
+
+ if (con->scratchpad) {
+ return cmd_results_new(CMD_INVALID, "move",
+ "Container is already in the scratchpad");
+ }
+ scratchpad_add_container(con);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
struct cmd_results *cmd_move(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
@@ -317,10 +345,9 @@ struct cmd_results *cmd_move(int argc, char **argv) {
} else if (strcasecmp(argv[0], "workspace") == 0) {
return cmd_move_workspace(current, argc, argv);
} else if (strcasecmp(argv[0], "scratchpad") == 0
- || (strcasecmp(argv[0], "to") == 0
+ || (strcasecmp(argv[0], "to") == 0 && argc == 2
&& strcasecmp(argv[1], "scratchpad") == 0)) {
- // TODO: scratchpad
- return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
+ return move_to_scratchpad(current);
} else if (strcasecmp(argv[0], "position") == 0) {
return move_to_position(current, argc, argv);
} else if (strcasecmp(argv[0], "absolute") == 0) {
diff --git a/sway/commands/output/dpms.c b/sway/commands/output/dpms.c
index 0959ea6b..3492061e 100644
--- a/sway/commands/output/dpms.c
+++ b/sway/commands/output/dpms.c
@@ -1,5 +1,6 @@
#include "sway/commands.h"
#include "sway/config.h"
+#include "util.h"
struct cmd_results *output_cmd_dpms(int argc, char **argv) {
if (!config->handler_context.output_config) {
@@ -9,13 +10,10 @@ struct cmd_results *output_cmd_dpms(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, "output", "Missing dpms argument.");
}
- if (strcmp(*argv, "on") == 0) {
+ if (parse_boolean(argv[0], true)) {
config->handler_context.output_config->dpms_state = DPMS_ON;
- } else if (strcmp(*argv, "off") == 0) {
- config->handler_context.output_config->dpms_state = DPMS_OFF;
} else {
- return cmd_results_new(CMD_INVALID, "output",
- "Invalid dpms state, valid states are on/off.");
+ config->handler_context.output_config->dpms_state = DPMS_OFF;
}
config->handler_context.leftovers.argc = argc - 1;
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index cea6a94b..5c1b19b4 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -1,17 +1,46 @@
+#define _XOPEN_SOURCE 500
+#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "sway/ipc-server.h"
#include "sway/tree/arrange.h"
+#include "list.h"
struct cmd_results *cmd_reload(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
return error;
}
+
+ // store bar ids to check against new bars for barconfig_update events
+ list_t *bar_ids = create_list();
+ for (int i = 0; i < config->bars->length; ++i) {
+ struct bar_config *bar = config->bars->items[i];
+ list_add(bar_ids, strdup(bar->id));
+ }
+
if (!load_main_config(config->current_config_path, true)) {
return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
}
+ ipc_event_workspace(NULL, NULL, "reload");
load_swaybars();
+
+ for (int i = 0; i < config->bars->length; ++i) {
+ struct bar_config *bar = config->bars->items[i];
+ for (int j = 0; j < bar_ids->length; ++j) {
+ if (strcmp(bar->id, bar_ids->items[j]) == 0) {
+ ipc_event_barconfig_update(bar);
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < bar_ids->length; ++i) {
+ free(bar_ids->items[i]);
+ }
+ list_free(bar_ids);
+
arrange_windows(&root_container);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c
new file mode 100644
index 00000000..01a91d65
--- /dev/null
+++ b/sway/commands/scratchpad.c
@@ -0,0 +1,44 @@
+#include "log.h"
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/scratchpad.h"
+#include "sway/tree/container.h"
+
+struct cmd_results *cmd_scratchpad(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+ if (strcmp(argv[0], "show") != 0) {
+ return cmd_results_new(CMD_INVALID, "scratchpad",
+ "Expected 'scratchpad show'");
+ }
+ if (!root_container.sway_root->scratchpad->length) {
+ return cmd_results_new(CMD_INVALID, "scratchpad",
+ "Scratchpad is empty");
+ }
+
+ if (config->handler_context.using_criteria) {
+ struct sway_container *con = config->handler_context.current_container;
+
+ // If the container is in a floating split container,
+ // operate on the split container instead of the child.
+ if (container_is_floating_or_child(con)) {
+ while (con->parent->layout != L_FLOATING) {
+ con = con->parent;
+ }
+ }
+
+ // If using criteria, this command is executed for every container which
+ // matches the criteria. If this container isn't in the scratchpad,
+ // we'll just silently return a success.
+ if (!con->scratchpad) {
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+ }
+ scratchpad_toggle_container(con);
+ } else {
+ scratchpad_toggle_auto();
+ }
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c
index c7fdc538..434a0e27 100644
--- a/sway/commands/show_marks.c
+++ b/sway/commands/show_marks.c
@@ -7,6 +7,7 @@
#include "list.h"
#include "log.h"
#include "stringop.h"
+#include "util.h"
static void rebuild_marks_iterator(struct sway_container *con, void *data) {
if (con->type == C_VIEW) {
@@ -20,14 +21,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) {
return error;
}
- if (strcmp(*argv, "yes") == 0) {
- config->show_marks = true;
- } else if (strcmp(*argv, "no") == 0) {
- config->show_marks = false;
- } else {
- return cmd_results_new(CMD_INVALID, "show_marks",
- "Expected 'show_marks <yes|no>'");
- }
+ config->show_marks = parse_boolean(argv[0], config->show_marks);
if (config->show_marks) {
container_for_each_descendant_dfs(&root_container,
diff --git a/sway/commands/split.c b/sway/commands/split.c
index 313799da..a8eddf54 100644
--- a/sway/commands/split.c
+++ b/sway/commands/split.c
@@ -10,10 +10,6 @@
static struct cmd_results *do_split(int layout) {
struct sway_container *con = config->handler_context.current_container;
- if (container_is_floating(con)) {
- return cmd_results_new(CMD_FAILURE, "split",
- "Can't split a floating view");
- }
struct sway_container *parent = container_split(con, layout);
container_create_notify(parent);
arrange_windows(parent->parent);
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index 2fc88308..4e3a9cce 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -1,5 +1,6 @@
#include <strings.h>
#include <wlr/util/log.h>
+#include "config.h"
#include "sway/commands.h"
#include "sway/tree/arrange.h"
#include "sway/tree/layout.h"
@@ -14,10 +15,14 @@ static bool test_con_id(struct sway_container *container, void *con_id) {
}
static bool test_id(struct sway_container *container, void *id) {
+#ifdef HAVE_XWAYLAND
xcb_window_t *wid = id;
return (container->type == C_VIEW
&& container->sway_view->type == SWAY_VIEW_XWAYLAND
&& container->sway_view->wlr_xwayland_surface->window_id == *wid);
+#else
+ return false;
+#endif
}
static bool test_mark(struct sway_container *container, void *mark) {
@@ -43,8 +48,10 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
char *value = join_args(argv + 3, argc - 3);
if (strcasecmp(argv[2], "id") == 0) {
+#ifdef HAVE_XWAYLAND
xcb_window_t id = strtol(value, NULL, 0);
other = container_find(&root_container, test_id, (void *)&id);
+#endif
} else if (strcasecmp(argv[2], "con_id") == 0) {
size_t con_id = atoi(value);
other = container_find(&root_container, test_con_id, (void *)con_id);
diff --git a/sway/commands/urgent.c b/sway/commands/urgent.c
index d199858a..51c497c4 100644
--- a/sway/commands/urgent.c
+++ b/sway/commands/urgent.c
@@ -5,6 +5,7 @@
#include "sway/tree/container.h"
#include "sway/tree/view.h"
#include "sway/tree/layout.h"
+#include "util.h"
struct cmd_results *cmd_urgent(int argc, char **argv) {
struct cmd_results *error = NULL;
@@ -19,17 +20,12 @@ struct cmd_results *cmd_urgent(int argc, char **argv) {
}
struct sway_view *view = container->sway_view;
- if (strcmp(argv[0], "enable") == 0) {
- view_set_urgent(view, true);
- } else if (strcmp(argv[0], "disable") == 0) {
- view_set_urgent(view, false);
- } else if (strcmp(argv[0], "allow") == 0) {
+ if (strcmp(argv[0], "allow") == 0) {
view->allow_request_urgent = true;
} else if (strcmp(argv[0], "deny") == 0) {
view->allow_request_urgent = false;
} else {
- return cmd_results_new(CMD_INVALID, "urgent",
- "Expected 'urgent <enable|disable|allow|deny>'");
+ view_set_urgent(view, parse_boolean(argv[0], view_is_urgent(view)));
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);