aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/bind.c
diff options
context:
space:
mode:
authorLibravatar frsfnrrg <frsfnrrg@users.noreply.github.com>2018-05-31 15:16:01 -0400
committerLibravatar frsfnrrg <frsfnrrg@users.noreply.github.com>2018-06-01 18:52:36 -0400
commitd77681ea3d84f1f02164f3cb0a29a42616afd23b (patch)
tree13a7f5fdecce79bf822b6b86745b3b4601cf3c97 /sway/commands/bind.c
parentMerge pull request #2027 from RyanDwyer/implement-floating (diff)
downloadsway-d77681ea3d84f1f02164f3cb0a29a42616afd23b.tar.gz
sway-d77681ea3d84f1f02164f3cb0a29a42616afd23b.tar.zst
sway-d77681ea3d84f1f02164f3cb0a29a42616afd23b.zip
Share common code between bindsym and bindcode commands
Diffstat (limited to 'sway/commands/bind.c')
-rw-r--r--sway/commands/bind.c170
1 files changed, 60 insertions, 110 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index c6b3368a..f3bf72ad 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -69,15 +69,17 @@ bool binding_key_compare(struct sway_binding *binding_a,
69 return true; 69 return true;
70} 70}
71 71
72struct cmd_results *cmd_bindsym(int argc, char **argv) { 72static struct cmd_results * cmd_bindsym_or_bindcode(int argc, char **argv, bool bindcode) {
73 const char* bindtype = bindcode ? "bindcode" : "bindsym";
74
73 struct cmd_results *error = NULL; 75 struct cmd_results *error = NULL;
74 if ((error = checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1))) { 76 if ((error = checkarg(argc, bindtype, EXPECTED_MORE_THAN, 1))) {
75 return error; 77 return error;
76 } 78 }
77 79
78 struct sway_binding *binding = calloc(1, sizeof(struct sway_binding)); 80 struct sway_binding *binding = calloc(1, sizeof(struct sway_binding));
79 if (!binding) { 81 if (!binding) {
80 return cmd_results_new(CMD_FAILURE, "bindsym", 82 return cmd_results_new(CMD_FAILURE, bindtype,
81 "Unable to allocate binding"); 83 "Unable to allocate binding");
82 } 84 }
83 binding->keys = create_list(); 85 binding->keys = create_list();
@@ -100,9 +102,9 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) {
100 } 102 }
101 if (argc < 2) { 103 if (argc < 2) {
102 free_sway_binding(binding); 104 free_sway_binding(binding);
103 return cmd_results_new(CMD_FAILURE, "bindsym", 105 return cmd_results_new(CMD_FAILURE, bindtype,
104 "Invalid bindsym command " 106 "Invalid %s command "
105 "(expected at least 2 non-option arguments, got %d)", argc); 107 "(expected at least 2 non-option arguments, got %d)", bindtype, argc);
106 } 108 }
107 109
108 binding->command = join_args(argv + 1, argc - 1); 110 binding->command = join_args(argv + 1, argc - 1);
@@ -115,124 +117,63 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) {
115 binding->modifiers |= mod; 117 binding->modifiers |= mod;
116 continue; 118 continue;
117 } 119 }
118 // Check for xkb key
119 xkb_keysym_t sym = xkb_keysym_from_name(split->items[i],
120 XKB_KEYSYM_CASE_INSENSITIVE);
121 120
122 // Check for mouse binding 121 xkb_keycode_t keycode;
123 if (strncasecmp(split->items[i], "button", strlen("button")) == 0 && 122 xkb_keysym_t keysym;
124 strlen(split->items[i]) == strlen("button0")) { 123 if (bindcode) {
125 sym = ((char *)split->items[i])[strlen("button")] - '1' + BTN_LEFT; 124 // parse keycode
126 } 125 keycode = (int)strtol(split->items[i], NULL, 10);
127 if (!sym) { 126 if (!xkb_keycode_is_legal_ext(keycode)) {
128 struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym", 127 error =
129 "Unknown key '%s'", (char *)split->items[i]); 128 cmd_results_new(CMD_INVALID, "bindcode",
130 free_sway_binding(binding); 129 "Invalid keycode '%s'", (char *)split->items[i]);
131 free_flat_list(split); 130 free_sway_binding(binding);
132 return ret; 131 list_free(split);
132 return error;
133 }
134 } else {
135 // Check for xkb key
136 keysym = xkb_keysym_from_name(split->items[i],
137 XKB_KEYSYM_CASE_INSENSITIVE);
138
139 // Check for mouse binding
140 if (strncasecmp(split->items[i], "button", strlen("button")) == 0 &&
141 strlen(split->items[i]) == strlen("button0")) {
142 keysym = ((char *)split->items[i])[strlen("button")] - '1' + BTN_LEFT;
143 }
144 if (!keysym) {
145 struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym",
146 "Unknown key '%s'", (char *)split->items[i]);
147 free_sway_binding(binding);
148 free_flat_list(split);
149 return ret;
150 }
133 } 151 }
134 xkb_keysym_t *key = calloc(1, sizeof(xkb_keysym_t)); 152 uint32_t *key = calloc(1, sizeof(xkb_keysym_t));
135 if (!key) { 153 if (!key) {
136 free_sway_binding(binding); 154 free_sway_binding(binding);
137 free_flat_list(split); 155 free_flat_list(split);
138 return cmd_results_new(CMD_FAILURE, "bindsym", 156 return cmd_results_new(CMD_FAILURE, bindtype,
139 "Unable to allocate binding"); 157 "Unable to allocate binding");
140 } 158 }
141 *key = sym;
142 list_add(binding->keys, key);
143 }
144 free_flat_list(split);
145 binding->order = binding_order++;
146
147 list_t *mode_bindings = config->current_mode->keysym_bindings;
148
149 // overwrite the binding if it already exists
150 bool overwritten = false;
151 for (int i = 0; i < mode_bindings->length; ++i) {
152 struct sway_binding *config_binding = mode_bindings->items[i];
153 if (binding_key_compare(binding, config_binding)) {
154 wlr_log(L_DEBUG, "overwriting old binding with command '%s'",
155 config_binding->command);
156 free_sway_binding(config_binding);
157 mode_bindings->items[i] = binding;
158 overwritten = true;
159 }
160 }
161
162 if (!overwritten) {
163 list_add(mode_bindings, binding);
164 }
165
166 wlr_log(L_DEBUG, "bindsym - Bound %s to command %s",
167 argv[0], binding->command);
168 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
169}
170
171struct cmd_results *cmd_bindcode(int argc, char **argv) {
172 struct cmd_results *error = NULL;
173 if ((error = checkarg(argc, "bindcode", EXPECTED_MORE_THAN, 1))) {
174 return error;
175 }
176
177 struct sway_binding *binding = calloc(1, sizeof(struct sway_binding));
178 if (!binding) {
179 return cmd_results_new(CMD_FAILURE, "bindsym",
180 "Unable to allocate binding");
181 }
182 binding->keys = create_list();
183 binding->modifiers = 0;
184 binding->release = false;
185 binding->locked = false;
186 binding->bindcode = true;
187 159
188 // Handle --release and --locked 160 if (bindcode) {
189 while (argc > 0) { 161 *key = (uint32_t) (keycode - 8);
190 if (strcmp("--release", argv[0]) == 0) {
191 binding->release = true;
192 } else if (strcmp("--locked", argv[0]) == 0) {
193 binding->locked = true;
194 } else { 162 } else {
195 break; 163 *key = (uint32_t) keysym;
196 } 164 }
197 argv++;
198 argc--;
199 }
200 if (argc < 2) {
201 free_sway_binding(binding);
202 return cmd_results_new(CMD_FAILURE, "bindcode",
203 "Invalid bindcode command "
204 "(expected at least 2 non-option arguments, got %d)", argc);
205 }
206 165
207 binding->command = join_args(argv + 1, argc - 1);
208
209 list_t *split = split_string(argv[0], "+");
210 for (int i = 0; i < split->length; ++i) {
211 // Check for a modifier key
212 uint32_t mod;
213 if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
214 binding->modifiers |= mod;
215 continue;
216 }
217 // parse keycode
218 xkb_keycode_t keycode = (int)strtol(split->items[i], NULL, 10);
219 if (!xkb_keycode_is_legal_ext(keycode)) {
220 error =
221 cmd_results_new(CMD_INVALID, "bindcode",
222 "Invalid keycode '%s'", (char *)split->items[i]);
223 free_sway_binding(binding);
224 list_free(split);
225 return error;
226 }
227 xkb_keycode_t *key = calloc(1, sizeof(xkb_keycode_t));
228 *key = keycode - 8;
229 list_add(binding->keys, key); 166 list_add(binding->keys, key);
230 } 167 }
231 free_flat_list(split); 168 free_flat_list(split);
232
233 binding->order = binding_order++; 169 binding->order = binding_order++;
234 170
235 list_t *mode_bindings = config->current_mode->keycode_bindings; 171 list_t *mode_bindings;
172 if (bindcode) {
173 mode_bindings = config->current_mode->keycode_bindings;
174 } else {
175 mode_bindings = config->current_mode->keysym_bindings;
176 }
236 177
237 // overwrite the binding if it already exists 178 // overwrite the binding if it already exists
238 bool overwritten = false; 179 bool overwritten = false;
@@ -251,7 +192,16 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) {
251 list_add(mode_bindings, binding); 192 list_add(mode_bindings, binding);
252 } 193 }
253 194
254 wlr_log(L_DEBUG, "bindcode - Bound %s to command %s", 195 wlr_log(L_DEBUG, "%s - Bound %s to command %s",
255 argv[0], binding->command); 196 bindtype, argv[0], binding->command);
256 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 197 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
198
199}
200
201struct cmd_results *cmd_bindsym(int argc, char **argv) {
202 return cmd_bindsym_or_bindcode(argc, argv, false);
203}
204
205struct cmd_results *cmd_bindcode(int argc, char **argv) {
206 return cmd_bindsym_or_bindcode(argc, argv, true);
257} 207}