diff options
Diffstat (limited to 'sway/commands')
-rw-r--r-- | sway/commands/bind.c | 168 | ||||
-rw-r--r-- | sway/commands/focus_follows_mouse.c | 4 | ||||
-rw-r--r-- | sway/commands/focus_wrapping.c | 12 | ||||
-rw-r--r-- | sway/commands/force_focus_wrapping.c | 8 | ||||
-rw-r--r-- | sway/commands/fullscreen.c | 14 | ||||
-rw-r--r-- | sway/commands/input/drag_lock.c | 9 | ||||
-rw-r--r-- | sway/commands/input/dwt.c | 9 | ||||
-rw-r--r-- | sway/commands/input/left_handed.c | 11 | ||||
-rw-r--r-- | sway/commands/input/middle_emulation.c | 9 | ||||
-rw-r--r-- | sway/commands/input/natural_scroll.c | 11 | ||||
-rw-r--r-- | sway/commands/input/tap.c | 9 | ||||
-rw-r--r-- | sway/commands/output/dpms.c | 8 | ||||
-rw-r--r-- | sway/commands/show_marks.c | 10 | ||||
-rw-r--r-- | sway/commands/urgent.c | 10 |
14 files changed, 160 insertions, 132 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 83e9e432..133fd089 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -34,11 +34,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 +72,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 +148,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 +194,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"); + "Unable to allocate binding key"); } - - if (bindcode) { - *key = (uint32_t)keycode; - } else { - *key = (uint32_t)keysym; - } - + *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 +267,19 @@ 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); + config->handler_context.seat = seat; + struct cmd_results *results = execute_command(binding->command, NULL); + if (results->status != CMD_SUCCESS) { + wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", + binding->command, results->error); + } + free_cmd_results(results); +} 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..b423fd23 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; @@ -18,17 +19,10 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { "Only views can fullscreen"); } struct sway_view *view = container->sway_view; - bool wants_fullscreen; + bool wants_fullscreen = !view->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) { + wants_fullscreen = parse_boolean(argv[0], view->is_fullscreen); } view_set_fullscreen(view, wants_fullscreen); 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/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/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/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); |