diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-01-06 13:16:54 -0500 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2019-01-09 11:29:04 -0500 |
commit | eefa6b1ad3f7e6fcbcf52595a833ae28364c18ea (patch) | |
tree | b65eda998dbfc67d338253516441ad227c38cb1e | |
parent | Add helpers for improved mouse button parsing (diff) | |
download | sway-eefa6b1ad3f7e6fcbcf52595a833ae28364c18ea.tar.gz sway-eefa6b1ad3f7e6fcbcf52595a833ae28364c18ea.tar.zst sway-eefa6b1ad3f7e6fcbcf52595a833ae28364c18ea.zip |
bind{code,sym}: utilize mouse button helpers
This modifies `bindcode` and `bindsym` to use `get_mouse_bindcode` and
`get_mouse_bindsym`, respectively, to parse mouse buttons. Additionally,
the `BINDING_MOUSE` type has been split into `BINDING_MOUSECODE` and
`BINDING_MOUSESYM` to match keys and allow for mouse bindcodes to be
used. Between the two commands, all button syms and codes should be
supported, including x11 axis buttons.
-rw-r--r-- | include/sway/config.h | 3 | ||||
-rw-r--r-- | sway/commands/bind.c | 126 | ||||
-rw-r--r-- | sway/ipc-server.c | 8 | ||||
-rw-r--r-- | sway/sway.5.scd | 2 |
4 files changed, 84 insertions, 55 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index ebf16e6a..29c21afe 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -27,7 +27,8 @@ struct sway_variable { | |||
27 | enum binding_input_type { | 27 | enum binding_input_type { |
28 | BINDING_KEYCODE, | 28 | BINDING_KEYCODE, |
29 | BINDING_KEYSYM, | 29 | BINDING_KEYSYM, |
30 | BINDING_MOUSE, | 30 | BINDING_MOUSECODE, |
31 | BINDING_MOUSESYM, | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | enum binding_flags { | 34 | enum binding_flags { |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 4fceaf8c..be47d412 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -85,69 +85,91 @@ static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) { | |||
85 | */ | 85 | */ |
86 | static struct cmd_results *identify_key(const char* name, bool first_key, | 86 | static struct cmd_results *identify_key(const char* name, bool first_key, |
87 | uint32_t* key_val, enum binding_input_type* type) { | 87 | uint32_t* key_val, enum binding_input_type* type) { |
88 | if (*type == BINDING_KEYCODE) { | 88 | if (*type == BINDING_MOUSECODE) { |
89 | // check for keycode | 89 | // check for mouse bindcodes |
90 | xkb_keycode_t keycode = strtol(name, NULL, 10); | 90 | char *message = NULL; |
91 | if (!xkb_keycode_is_legal_ext(keycode)) { | 91 | uint32_t button = get_mouse_bindcode(name, &message); |
92 | return cmd_results_new(CMD_INVALID, "bindcode", | 92 | if (!button) { |
93 | "Invalid keycode '%s'", name); | 93 | if (message) { |
94 | struct cmd_results *error = | ||
95 | cmd_results_new(CMD_INVALID, "bindcode", message); | ||
96 | free(message); | ||
97 | return error; | ||
98 | } else { | ||
99 | return cmd_results_new(CMD_INVALID, "bindcode", | ||
100 | "Unknown button code %s", name); | ||
101 | } | ||
94 | } | 102 | } |
95 | *key_val = keycode; | 103 | *key_val = button; |
96 | } else { | 104 | } else if (*type == BINDING_MOUSESYM) { |
97 | // check for keysym | 105 | // check for mouse bindsyms (x11 buttons or event names) |
98 | xkb_keysym_t keysym = xkb_keysym_from_name(name, | 106 | char *message = NULL; |
99 | XKB_KEYSYM_CASE_INSENSITIVE); | 107 | uint32_t button = get_mouse_bindsym(name, &message); |
100 | 108 | if (!button) { | |
101 | // Check for mouse binding | 109 | if (message) { |
102 | uint32_t button = 0; | 110 | struct cmd_results *error = |
103 | if (strncasecmp(name, "button", strlen("button")) == 0) { | 111 | cmd_results_new(CMD_INVALID, "bindsym", message); |
104 | // Map to x11 mouse buttons | 112 | free(message); |
105 | button = name[strlen("button")] - '0'; | 113 | return error; |
106 | if (button < 1 || button > 9 || strlen(name) > strlen("button0")) { | 114 | } else if (!button) { |
107 | return cmd_results_new(CMD_INVALID, "bindsym", | 115 | return cmd_results_new(CMD_INVALID, "bindsym", |
108 | "Only buttons 1-9 are supported. For other mouse " | 116 | "Unknown button %s", name); |
109 | "buttons, use the name of the event code."); | ||
110 | } | 117 | } |
111 | uint32_t buttons[] = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, | 118 | } |
112 | SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT, | 119 | *key_val = button; |
113 | SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA}; | 120 | } else if (*type == BINDING_KEYCODE) { |
114 | button = buttons[button - 1]; | 121 | // check for keycode. If it is the first key, allow mouse bindcodes |
115 | } else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) { | 122 | if (first_key) { |
116 | // Get event code | 123 | char *message = NULL; |
117 | int code = libevdev_event_code_from_name(EV_KEY, name); | 124 | uint32_t button = get_mouse_bindcode(name, &message); |
118 | if (code == -1) { | 125 | free(message); |
119 | return cmd_results_new(CMD_INVALID, "bindsym", | 126 | if (button) { |
120 | "Invalid event code name %s", name); | 127 | *type = BINDING_MOUSECODE; |
128 | *key_val = button; | ||
129 | return NULL; | ||
121 | } | 130 | } |
122 | button = code; | ||
123 | } | 131 | } |
124 | 132 | ||
125 | if (*type == BINDING_KEYSYM) { | 133 | xkb_keycode_t keycode = strtol(name, NULL, 10); |
126 | if (button) { | 134 | if (!xkb_keycode_is_legal_ext(keycode)) { |
127 | if (first_key) { | 135 | if (first_key) { |
128 | *type = BINDING_MOUSE; | 136 | return cmd_results_new(CMD_INVALID, "bindcode", |
129 | *key_val = button; | 137 | "Invalid keycode or button code '%s'", name); |
130 | } else { | ||
131 | return cmd_results_new(CMD_INVALID, "bindsym", | ||
132 | "Mixed button '%s' into key sequence", name); | ||
133 | } | ||
134 | } else if (keysym) { | ||
135 | *key_val = keysym; | ||
136 | } else { | 138 | } else { |
137 | return cmd_results_new(CMD_INVALID, "bindsym", | 139 | return cmd_results_new(CMD_INVALID, "bindcode", |
138 | "Unknown key '%s'", name); | 140 | "Invalid keycode '%s'", name); |
139 | } | 141 | } |
140 | } else { | 142 | } |
141 | if (button) { | 143 | *key_val = keycode; |
144 | } else { | ||
145 | // check for keysym. If it is the first key, allow mouse bindsyms | ||
146 | if (first_key) { | ||
147 | char *message = NULL; | ||
148 | uint32_t button = get_mouse_bindsym(name, &message); | ||
149 | if (message) { | ||
150 | struct cmd_results *error = | ||
151 | cmd_results_new(CMD_INVALID, "bindsym", message); | ||
152 | free(message); | ||
153 | return error; | ||
154 | } else if (button) { | ||
155 | *type = BINDING_MOUSESYM; | ||
142 | *key_val = button; | 156 | *key_val = button; |
143 | } else if (keysym) { | 157 | return NULL; |
158 | } | ||
159 | } | ||
160 | |||
161 | xkb_keysym_t keysym = xkb_keysym_from_name(name, | ||
162 | XKB_KEYSYM_CASE_INSENSITIVE); | ||
163 | if (!keysym) { | ||
164 | if (first_key) { | ||
144 | return cmd_results_new(CMD_INVALID, "bindsym", | 165 | return cmd_results_new(CMD_INVALID, "bindsym", |
145 | "Mixed keysym '%s' into button sequence", name); | 166 | "Unknown key or button '%s'", name); |
146 | } else { | 167 | } else { |
147 | return cmd_results_new(CMD_INVALID, "bindsym", | 168 | return cmd_results_new(CMD_INVALID, "bindsym", |
148 | "Unknown button '%s'", name); | 169 | "Unknown key '%s'", name); |
149 | } | 170 | } |
150 | } | 171 | } |
172 | *key_val = keysym; | ||
151 | } | 173 | } |
152 | return NULL; | 174 | return NULL; |
153 | } | 175 | } |
@@ -201,7 +223,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
201 | } | 223 | } |
202 | if (binding->flags & (BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR) | 224 | if (binding->flags & (BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR) |
203 | || exclude_titlebar) { | 225 | || exclude_titlebar) { |
204 | binding->type = BINDING_MOUSE; | 226 | binding->type = binding->type == BINDING_KEYCODE ? |
227 | BINDING_MOUSECODE : BINDING_MOUSESYM; | ||
205 | } | 228 | } |
206 | 229 | ||
207 | if (argc < 2) { | 230 | if (argc < 2) { |
@@ -249,7 +272,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
249 | // that this is one | 272 | // that this is one |
250 | if (exclude_titlebar) { | 273 | if (exclude_titlebar) { |
251 | binding->flags &= ~BINDING_TITLEBAR; | 274 | binding->flags &= ~BINDING_TITLEBAR; |
252 | } else if (binding->type == BINDING_MOUSE) { | 275 | } else if (binding->type == BINDING_MOUSECODE |
276 | || binding->type == BINDING_MOUSESYM) { | ||
253 | binding->flags |= BINDING_TITLEBAR; | 277 | binding->flags |= BINDING_TITLEBAR; |
254 | } | 278 | } |
255 | 279 | ||
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 456db866..ff1bc89f 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -445,8 +445,12 @@ void ipc_event_binding(struct sway_binding *binding) { | |||
445 | json_object_object_add(json_binding, "input_code", json_object_new_int(input_code)); | 445 | json_object_object_add(json_binding, "input_code", json_object_new_int(input_code)); |
446 | json_object_object_add(json_binding, "symbols", symbols); | 446 | json_object_object_add(json_binding, "symbols", symbols); |
447 | json_object_object_add(json_binding, "symbol", symbol); | 447 | json_object_object_add(json_binding, "symbol", symbol); |
448 | json_object_object_add(json_binding, "input_type", binding->type == BINDING_MOUSE ? | 448 | |
449 | json_object_new_string("mouse") : json_object_new_string("keyboard")); | 449 | bool mouse = binding->type == BINDING_MOUSECODE || |
450 | binding->type == BINDING_MOUSESYM; | ||
451 | json_object_object_add(json_binding, "input_type", mouse | ||
452 | ? json_object_new_string("mouse") | ||
453 | : json_object_new_string("keyboard")); | ||
450 | 454 | ||
451 | json_object *json = json_object_new_object(); | 455 | json_object *json = json_object_new_object(); |
452 | json_object_object_add(json, "change", json_object_new_string("run")); | 456 | json_object_object_add(json, "change", json_object_new_string("run")); |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 3757a097..3398ad58 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -302,7 +302,7 @@ runtime. | |||
302 | ``` | 302 | ``` |
303 | 303 | ||
304 | *bindcode* [--release|--locked] [--input-device=<device>] [--no-warn] <code> <command> | 304 | *bindcode* [--release|--locked] [--input-device=<device>] [--no-warn] <code> <command> |
305 | is also available for binding with key codes instead of key names. | 305 | is also available for binding with key/button codes instead of key/button names. |
306 | 306 | ||
307 | *client.<class>* <border> <background> <text> <indicator> <child\_border> | 307 | *client.<class>* <border> <background> <text> <indicator> <child\_border> |
308 | Configures the color of window borders and title bars. All 5 colors are | 308 | Configures the color of window borders and title bars. All 5 colors are |