aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-05-30 13:20:02 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-06-02 08:07:44 -0400
commit7c810dc344c28d1876c5ee158cb0806289d0f813 (patch)
treedbe756bceca42ea6f9a6cf5e5771037417bb64c3 /sway/commands.c
parentMerge pull request #2080 from frsfnrrg/keyboard-remodeling (diff)
downloadsway-7c810dc344c28d1876c5ee158cb0806289d0f813.tar.gz
sway-7c810dc344c28d1876c5ee158cb0806289d0f813.tar.zst
sway-7c810dc344c28d1876c5ee158cb0806289d0f813.zip
Make command block implementation generic
Diffstat (limited to 'sway/commands.c')
-rw-r--r--sway/commands.c153
1 files changed, 48 insertions, 105 deletions
diff --git a/sway/commands.c b/sway/commands.c
index e9762bef..825fda8f 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -16,11 +16,6 @@
16#include "stringop.h" 16#include "stringop.h"
17#include "log.h" 17#include "log.h"
18 18
19struct cmd_handler {
20 char *command;
21 sway_cmd *handle;
22};
23
24// Returns error object, or NULL if check succeeds. 19// Returns error object, or NULL if check succeeds.
25struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) { 20struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) {
26 struct cmd_results *error = NULL; 21 struct cmd_results *error = NULL;
@@ -122,47 +117,6 @@ static struct cmd_handler handlers[] = {
122 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, 117 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
123}; 118};
124 119
125static struct cmd_handler bar_handlers[] = {
126 { "activate_button", bar_cmd_activate_button },
127 { "binding_mode_indicator", bar_cmd_binding_mode_indicator },
128 { "bindsym", bar_cmd_bindsym },
129 { "colors", bar_cmd_colors },
130 { "context_button", bar_cmd_context_button },
131 { "font", bar_cmd_font },
132 { "height", bar_cmd_height },
133 { "hidden_state", bar_cmd_hidden_state },
134 { "icon_theme", bar_cmd_icon_theme },
135 { "id", bar_cmd_id },
136 { "mode", bar_cmd_mode },
137 { "modifier", bar_cmd_modifier },
138 { "output", bar_cmd_output },
139 { "pango_markup", bar_cmd_pango_markup },
140 { "position", bar_cmd_position },
141 { "secondary_button", bar_cmd_secondary_button },
142 { "separator_symbol", bar_cmd_separator_symbol },
143 { "status_command", bar_cmd_status_command },
144 { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers },
145 { "swaybar_command", bar_cmd_swaybar_command },
146 { "tray_output", bar_cmd_tray_output },
147 { "tray_padding", bar_cmd_tray_padding },
148 { "workspace_buttons", bar_cmd_workspace_buttons },
149 { "wrap_scroll", bar_cmd_wrap_scroll },
150};
151
152static struct cmd_handler bar_colors_handlers[] = {
153 { "active_workspace", bar_colors_cmd_active_workspace },
154 { "background", bar_colors_cmd_background },
155 { "binding_mode", bar_colors_cmd_binding_mode },
156 { "focused_background", bar_colors_cmd_focused_background },
157 { "focused_separator", bar_colors_cmd_focused_separator },
158 { "focused_statusline", bar_colors_cmd_focused_statusline },
159 { "focused_workspace", bar_colors_cmd_focused_workspace },
160 { "inactive_workspace", bar_colors_cmd_inactive_workspace },
161 { "separator", bar_colors_cmd_separator },
162 { "statusline", bar_colors_cmd_statusline },
163 { "urgent_workspace", bar_colors_cmd_urgent_workspace },
164};
165
166/* Config-time only commands. Keep alphabetized */ 120/* Config-time only commands. Keep alphabetized */
167static struct cmd_handler config_handlers[] = { 121static struct cmd_handler config_handlers[] = {
168 { "default_orientation", cmd_default_orientation }, 122 { "default_orientation", cmd_default_orientation },
@@ -202,62 +156,14 @@ static int handler_compare(const void *_a, const void *_b) {
202 return strcasecmp(a->command, b->command); 156 return strcasecmp(a->command, b->command);
203} 157}
204 158
205// must be in order for the bsearch 159struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers,
206static struct cmd_handler input_handlers[] = { 160 int handlers_size) {
207 { "accel_profile", input_cmd_accel_profile },
208 { "click_method", input_cmd_click_method },
209 { "drag_lock", input_cmd_drag_lock },
210 { "dwt", input_cmd_dwt },
211 { "events", input_cmd_events },
212 { "left_handed", input_cmd_left_handed },
213 { "map_from_region", input_cmd_map_from_region },
214 { "map_to_output", input_cmd_map_to_output },
215 { "middle_emulation", input_cmd_middle_emulation },
216 { "natural_scroll", input_cmd_natural_scroll },
217 { "pointer_accel", input_cmd_pointer_accel },
218 { "repeat_delay", input_cmd_repeat_delay },
219 { "repeat_rate", input_cmd_repeat_rate },
220 { "scroll_method", input_cmd_scroll_method },
221 { "tap", input_cmd_tap },
222 { "xkb_layout", input_cmd_xkb_layout },
223 { "xkb_model", input_cmd_xkb_model },
224 { "xkb_options", input_cmd_xkb_options },
225 { "xkb_rules", input_cmd_xkb_rules },
226 { "xkb_variant", input_cmd_xkb_variant },
227};
228
229// must be in order for the bsearch
230static struct cmd_handler seat_handlers[] = {
231 { "attach", seat_cmd_attach },
232 { "cursor", seat_cmd_cursor },
233 { "fallback", seat_cmd_fallback },
234};
235
236static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
237 struct cmd_handler d = { .command=line }; 161 struct cmd_handler d = { .command=line };
238 struct cmd_handler *res = NULL; 162 struct cmd_handler *res = NULL;
239 wlr_log(L_DEBUG, "find_handler(%s) %d", line, block == CMD_BLOCK_SEAT); 163 wlr_log(L_DEBUG, "find_handler(%s)", line);
240 164
241 bool config_loading = config->reading || !config->active; 165 bool config_loading = config->reading || !config->active;
242 166
243 if (block == CMD_BLOCK_BAR) {
244 return bsearch(&d, bar_handlers,
245 sizeof(bar_handlers) / sizeof(struct cmd_handler),
246 sizeof(struct cmd_handler), handler_compare);
247 } else if (block == CMD_BLOCK_BAR_COLORS) {
248 return bsearch(&d, bar_colors_handlers,
249 sizeof(bar_colors_handlers) / sizeof(struct cmd_handler),
250 sizeof(struct cmd_handler), handler_compare);
251 } else if (block == CMD_BLOCK_INPUT) {
252 return bsearch(&d, input_handlers,
253 sizeof(input_handlers) / sizeof(struct cmd_handler),
254 sizeof(struct cmd_handler), handler_compare);
255 } else if (block == CMD_BLOCK_SEAT) {
256 return bsearch(&d, seat_handlers,
257 sizeof(seat_handlers) / sizeof(struct cmd_handler),
258 sizeof(struct cmd_handler), handler_compare);
259 }
260
261 if (!config_loading) { 167 if (!config_loading) {
262 res = bsearch(&d, command_handlers, 168 res = bsearch(&d, command_handlers,
263 sizeof(command_handlers) / sizeof(struct cmd_handler), 169 sizeof(command_handlers) / sizeof(struct cmd_handler),
@@ -278,8 +184,13 @@ static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
278 } 184 }
279 } 185 }
280 186
281 res = bsearch(&d, handlers, 187 if (!cmd_handlers) {
282 sizeof(handlers) / sizeof(struct cmd_handler), 188 cmd_handlers = handlers;
189 handlers_size = sizeof(handlers);
190 }
191
192 res = bsearch(&d, cmd_handlers,
193 handlers_size / sizeof(struct cmd_handler),
283 sizeof(struct cmd_handler), handler_compare); 194 sizeof(struct cmd_handler), handler_compare);
284 195
285 return res; 196 return res;
@@ -349,7 +260,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
349 } 260 }
350 } 261 }
351 } 262 }
352 struct cmd_handler *handler = find_handler(argv[0], CMD_BLOCK_END); 263 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
353 if (!handler) { 264 if (!handler) {
354 if (results) { 265 if (results) {
355 free_cmd_results(results); 266 free_cmd_results(results);
@@ -413,7 +324,7 @@ cleanup:
413// be chained together) 324// be chained together)
414// 4) execute_command handles all state internally while config_command has 325// 4) execute_command handles all state internally while config_command has
415// some state handled outside (notably the block mode, in read_config) 326// some state handled outside (notably the block mode, in read_config)
416struct cmd_results *config_command(char *exec, enum cmd_status block) { 327struct cmd_results *config_command(char *exec) {
417 struct cmd_results *results = NULL; 328 struct cmd_results *results = NULL;
418 int argc; 329 int argc;
419 char **argv = split_args(exec, &argc); 330 char **argv = split_args(exec, &argc);
@@ -422,13 +333,21 @@ struct cmd_results *config_command(char *exec, enum cmd_status block) {
422 goto cleanup; 333 goto cleanup;
423 } 334 }
424 335
425 wlr_log(L_INFO, "handling config command '%s'", exec); 336 // Start block
337 if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) {
338 char *block = join_args(argv, argc - 1);
339 results = cmd_results_new(CMD_BLOCK, block, NULL);
340 free(block);
341 goto cleanup;
342 }
343
426 // Endblock 344 // Endblock
427 if (**argv == '}') { 345 if (strcmp(argv[argc - 1], "}") == 0) {
428 results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); 346 results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
429 goto cleanup; 347 goto cleanup;
430 } 348 }
431 struct cmd_handler *handler = find_handler(argv[0], block); 349 wlr_log(L_INFO, "handling config command '%s'", exec);
350 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
432 if (!handler) { 351 if (!handler) {
433 char *input = argv[0] ? argv[0] : "(empty)"; 352 char *input = argv[0] ? argv[0] : "(empty)";
434 results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); 353 results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
@@ -457,6 +376,30 @@ cleanup:
457 return results; 376 return results;
458} 377}
459 378
379struct cmd_results *subcommand(char **argv, int argc,
380 struct cmd_handler *handlers, int handlers_size) {
381 char *command = join_args(argv, argc);
382 wlr_log(L_DEBUG, "Subcommand: %s", command);
383 free(command);
384
385 struct cmd_handler *handler = find_handler(argv[0], handlers,
386 handlers_size);
387 if (!handler) {
388 char *input = argv[0] ? argv[0] : "(empty)";
389 return cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
390 }
391 // Strip quotes for first argument.
392 // TODO This part needs to be handled much better
393 if (argc > 1 && (*argv[1] == '\"' || *argv[1] == '\'')) {
394 strip_quotes(argv[1]);
395 }
396 if (handler->handle) {
397 return handler->handle(argc - 1, argv + 1);
398 }
399 return cmd_results_new(CMD_INVALID, argv[0],
400 "This command is shimmed, but unimplemented");
401}
402
460struct cmd_results *config_commands_command(char *exec) { 403struct cmd_results *config_commands_command(char *exec) {
461 struct cmd_results *results = NULL; 404 struct cmd_results *results = NULL;
462 int argc; 405 int argc;
@@ -474,7 +417,7 @@ struct cmd_results *config_commands_command(char *exec) {
474 goto cleanup; 417 goto cleanup;
475 } 418 }
476 419
477 struct cmd_handler *handler = find_handler(cmd, CMD_BLOCK_END); 420 struct cmd_handler *handler = find_handler(cmd, NULL, 0);
478 if (!handler && strcmp(cmd, "*") != 0) { 421 if (!handler && strcmp(cmd, "*") != 0) {
479 char *input = cmd ? cmd : "(empty)"; 422 char *input = cmd ? cmd : "(empty)";
480 results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); 423 results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");