diff options
Diffstat (limited to 'sway/commands/bar/bind.c')
-rw-r--r-- | sway/commands/bar/bind.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/sway/commands/bar/bind.c b/sway/commands/bar/bind.c new file mode 100644 index 00000000..a4c65ec4 --- /dev/null +++ b/sway/commands/bar/bind.c @@ -0,0 +1,106 @@ +#include <libevdev/libevdev.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/input/cursor.h" +#include "list.h" +#include "log.h" +#include "stringop.h" + +static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code) { + const char *command = code ? "bar bindcode" : "bar bindsym"; + struct cmd_results *error = NULL; + if ((error = checkarg(argc, command, EXPECTED_AT_LEAST, 2))) { + return error; + } + if (!config->current_bar) { + return cmd_results_new(CMD_FAILURE, command, "No bar defined."); + } + + struct bar_binding *binding = calloc(1, sizeof(struct bar_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, command, + "Unable to allocate bar binding"); + } + + binding->release = false; + if (strcmp("--release", argv[0]) == 0) { + binding->release = true; + argv++; + argc--; + } + + char *message = NULL; + if (code) { + binding->button = get_mouse_bindcode(argv[0], &message); + } else { + binding->button = get_mouse_bindsym(argv[0], &message); + } + if (message) { + free_bar_binding(binding); + error = cmd_results_new(CMD_INVALID, command, message); + free(message); + return error; + } else if (!binding->button) { + free_bar_binding(binding); + return cmd_results_new(CMD_INVALID, command, + "Unknown button %s", argv[0]); + } + + const char *name = libevdev_event_code_get_name(EV_KEY, binding->button); + if (!name) { + switch (binding->button) { + case SWAY_SCROLL_UP: + name = "SWAY_SCROLL_UP"; + break; + case SWAY_SCROLL_DOWN: + name = "SWAY_SCROLL_DOWN"; + break; + case SWAY_SCROLL_LEFT: + name = "SWAY_SCROLL_LEFT"; + break; + case SWAY_SCROLL_RIGHT: + name = "SWAY_SCROLL_RIGHT"; + break; + default: + // Unreachable + break; + } + } + + binding->command = join_args(argv + 1, argc - 1); + + list_t *bindings = config->current_bar->bindings; + bool overwritten = false; + for (int i = 0; i < bindings->length; i++) { + struct bar_binding *other = bindings->items[i]; + if (other->button == binding->button && + other->release == binding->release) { + overwritten = true; + bindings->items[i] = binding; + free_bar_binding(other); + wlr_log(WLR_DEBUG, "[bar %s] Updated binding for %u (%s)%s", + config->current_bar->id, binding->button, name, + binding->release ? " - release" : ""); + break; + } + } + if (!overwritten) { + list_add(bindings, binding); + wlr_log(WLR_DEBUG, "[bar %s] Added binding for %u (%s)%s", + config->current_bar->id, binding->button, name, + binding->release ? " - release" : ""); + } + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + +struct cmd_results *bar_cmd_bindcode(int argc, char **argv) { + return bar_cmd_bind(argc, argv, true); +} + +struct cmd_results *bar_cmd_bindsym(int argc, char **argv) { + return bar_cmd_bind(argc, argv, false); +} |