aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands.c')
-rw-r--r--sway/commands.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/sway/commands.c b/sway/commands.c
index fe1e98b5..b09a04c7 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -42,7 +42,7 @@ struct cmd_results *checkarg(int argc, const char *name, enum expected_args type
42} 42}
43 43
44/* Keep alphabetized */ 44/* Keep alphabetized */
45static struct cmd_handler handlers[] = { 45static const struct cmd_handler handlers[] = {
46 { "assign", cmd_assign }, 46 { "assign", cmd_assign },
47 { "bar", cmd_bar }, 47 { "bar", cmd_bar },
48 { "bindcode", cmd_bindcode }, 48 { "bindcode", cmd_bindcode },
@@ -98,7 +98,7 @@ static struct cmd_handler handlers[] = {
98}; 98};
99 99
100/* Config-time only commands. Keep alphabetized */ 100/* Config-time only commands. Keep alphabetized */
101static struct cmd_handler config_handlers[] = { 101static const struct cmd_handler config_handlers[] = {
102 { "default_orientation", cmd_default_orientation }, 102 { "default_orientation", cmd_default_orientation },
103 { "include", cmd_include }, 103 { "include", cmd_include },
104 { "swaybg_command", cmd_swaybg_command }, 104 { "swaybg_command", cmd_swaybg_command },
@@ -108,7 +108,7 @@ static struct cmd_handler config_handlers[] = {
108}; 108};
109 109
110/* Runtime-only commands. Keep alphabetized */ 110/* Runtime-only commands. Keep alphabetized */
111static struct cmd_handler command_handlers[] = { 111static const struct cmd_handler command_handlers[] = {
112 { "border", cmd_border }, 112 { "border", cmd_border },
113 { "create_output", cmd_create_output }, 113 { "create_output", cmd_create_output },
114 { "exit", cmd_exit }, 114 { "exit", cmd_exit },
@@ -144,22 +144,22 @@ static int handler_compare(const void *_a, const void *_b) {
144 return strcasecmp(a->command, b->command); 144 return strcasecmp(a->command, b->command);
145} 145}
146 146
147struct cmd_handler *find_handler(char *line, struct cmd_handler *handlers, 147const struct cmd_handler *find_handler(char *line,
148 size_t handlers_size) { 148 const struct cmd_handler *handlers, size_t handlers_size) {
149 if (!handlers || !handlers_size) { 149 if (!handlers || !handlers_size) {
150 return NULL; 150 return NULL;
151 } 151 }
152 struct cmd_handler query = { .command = line }; 152 const struct cmd_handler query = { .command = line };
153 return bsearch(&query, handlers, 153 return bsearch(&query, handlers,
154 handlers_size / sizeof(struct cmd_handler), 154 handlers_size / sizeof(struct cmd_handler),
155 sizeof(struct cmd_handler), handler_compare); 155 sizeof(struct cmd_handler), handler_compare);
156} 156}
157 157
158static struct cmd_handler *find_handler_ex(char *line, 158static const struct cmd_handler *find_handler_ex(char *line,
159 struct cmd_handler *config_handlers, size_t config_handlers_size, 159 const struct cmd_handler *config_handlers, size_t config_handlers_size,
160 struct cmd_handler *command_handlers, size_t command_handlers_size, 160 const struct cmd_handler *command_handlers, size_t command_handlers_size,
161 struct cmd_handler *handlers, size_t handlers_size) { 161 const struct cmd_handler *handlers, size_t handlers_size) {
162 struct cmd_handler *handler = NULL; 162 const struct cmd_handler *handler = NULL;
163 if (config->reading) { 163 if (config->reading) {
164 handler = find_handler(line, config_handlers, config_handlers_size); 164 handler = find_handler(line, config_handlers, config_handlers_size);
165 } else if (config->active) { 165 } else if (config->active) {
@@ -168,16 +168,17 @@ static struct cmd_handler *find_handler_ex(char *line,
168 return handler ? handler : find_handler(line, handlers, handlers_size); 168 return handler ? handler : find_handler(line, handlers, handlers_size);
169} 169}
170 170
171static struct cmd_handler *find_core_handler(char *line) { 171static const struct cmd_handler *find_core_handler(char *line) {
172 return find_handler_ex(line, config_handlers, sizeof(config_handlers), 172 return find_handler_ex(line, config_handlers, sizeof(config_handlers),
173 command_handlers, sizeof(command_handlers), 173 command_handlers, sizeof(command_handlers),
174 handlers, sizeof(handlers)); 174 handlers, sizeof(handlers));
175} 175}
176 176
177static void set_config_node(struct sway_node *node) { 177static void set_config_node(struct sway_node *node, bool node_overridden) {
178 config->handler_context.node = node; 178 config->handler_context.node = node;
179 config->handler_context.container = NULL; 179 config->handler_context.container = NULL;
180 config->handler_context.workspace = NULL; 180 config->handler_context.workspace = NULL;
181 config->handler_context.node_overridden = node_overridden;
181 182
182 if (node == NULL) { 183 if (node == NULL) {
183 return; 184 return;
@@ -186,7 +187,7 @@ static void set_config_node(struct sway_node *node) {
186 switch (node->type) { 187 switch (node->type) {
187 case N_CONTAINER: 188 case N_CONTAINER:
188 config->handler_context.container = node->sway_container; 189 config->handler_context.container = node->sway_container;
189 config->handler_context.workspace = node->sway_container->workspace; 190 config->handler_context.workspace = node->sway_container->pending.workspace;
190 break; 191 break;
191 case N_WORKSPACE: 192 case N_WORKSPACE:
192 config->handler_context.workspace = node->sway_workspace; 193 config->handler_context.workspace = node->sway_workspace;
@@ -202,6 +203,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
202 char *cmd; 203 char *cmd;
203 char matched_delim = ';'; 204 char matched_delim = ';';
204 list_t *containers = NULL; 205 list_t *containers = NULL;
206 bool using_criteria = false;
205 207
206 if (seat == NULL) { 208 if (seat == NULL) {
207 // passing a NULL seat means we just pick the default seat 209 // passing a NULL seat means we just pick the default seat
@@ -225,7 +227,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
225 for (; isspace(*head); ++head) {} 227 for (; isspace(*head); ++head) {}
226 // Extract criteria (valid for this command list only). 228 // Extract criteria (valid for this command list only).
227 if (matched_delim == ';') { 229 if (matched_delim == ';') {
228 config->handler_context.using_criteria = false; 230 using_criteria = false;
229 if (*head == '[') { 231 if (*head == '[') {
230 char *error = NULL; 232 char *error = NULL;
231 struct criteria *criteria = criteria_parse(head, &error); 233 struct criteria *criteria = criteria_parse(head, &error);
@@ -239,7 +241,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
239 containers = criteria_get_containers(criteria); 241 containers = criteria_get_containers(criteria);
240 head += strlen(criteria->raw); 242 head += strlen(criteria->raw);
241 criteria_destroy(criteria); 243 criteria_destroy(criteria);
242 config->handler_context.using_criteria = true; 244 using_criteria = true;
243 // Skip leading whitespace 245 // Skip leading whitespace
244 for (; isspace(*head); ++head) {} 246 for (; isspace(*head); ++head) {}
245 } 247 }
@@ -265,7 +267,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
265 } 267 }
266 } 268 }
267 } 269 }
268 struct cmd_handler *handler = find_core_handler(argv[0]); 270 const struct cmd_handler *handler = find_core_handler(argv[0]);
269 if (!handler) { 271 if (!handler) {
270 list_add(res_list, cmd_results_new(CMD_INVALID, 272 list_add(res_list, cmd_results_new(CMD_INVALID,
271 "Unknown/invalid command '%s'", argv[0])); 273 "Unknown/invalid command '%s'", argv[0]));
@@ -278,11 +280,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
278 argv[i] = do_var_replacement(argv[i]); 280 argv[i] = do_var_replacement(argv[i]);
279 } 281 }
280 282
281 if (!config->handler_context.using_criteria) { 283
282 // The container or workspace which this command will run on. 284 if (!using_criteria) {
283 struct sway_node *node = con ? &con->node : 285 if (con) {
284 seat_get_focus_inactive(seat, &root->node); 286 set_config_node(&con->node, true);
285 set_config_node(node); 287 } else {
288 set_config_node(seat_get_focus_inactive(seat, &root->node),
289 false);
290 }
286 struct cmd_results *res = handler->handle(argc-1, argv+1); 291 struct cmd_results *res = handler->handle(argc-1, argv+1);
287 list_add(res_list, res); 292 list_add(res_list, res);
288 if (res->status == CMD_INVALID) { 293 if (res->status == CMD_INVALID) {
@@ -296,7 +301,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
296 struct cmd_results *fail_res = NULL; 301 struct cmd_results *fail_res = NULL;
297 for (int i = 0; i < containers->length; ++i) { 302 for (int i = 0; i < containers->length; ++i) {
298 struct sway_container *container = containers->items[i]; 303 struct sway_container *container = containers->items[i];
299 set_config_node(&container->node); 304 set_config_node(&container->node, true);
300 struct cmd_results *res = handler->handle(argc-1, argv+1); 305 struct cmd_results *res = handler->handle(argc-1, argv+1);
301 if (res->status == CMD_SUCCESS) { 306 if (res->status == CMD_SUCCESS) {
302 free_cmd_results(res); 307 free_cmd_results(res);
@@ -370,7 +375,7 @@ struct cmd_results *config_command(char *exec, char **new_block) {
370 375
371 // Determine the command handler 376 // Determine the command handler
372 sway_log(SWAY_INFO, "Config command: %s", exec); 377 sway_log(SWAY_INFO, "Config command: %s", exec);
373 struct cmd_handler *handler = find_core_handler(argv[0]); 378 const struct cmd_handler *handler = find_core_handler(argv[0]);
374 if (!handler || !handler->handle) { 379 if (!handler || !handler->handle) {
375 const char *error = handler 380 const char *error = handler
376 ? "Command '%s' is shimmed, but unimplemented" 381 ? "Command '%s' is shimmed, but unimplemented"
@@ -418,12 +423,12 @@ cleanup:
418} 423}
419 424
420struct cmd_results *config_subcommand(char **argv, int argc, 425struct cmd_results *config_subcommand(char **argv, int argc,
421 struct cmd_handler *handlers, size_t handlers_size) { 426 const struct cmd_handler *handlers, size_t handlers_size) {
422 char *command = join_args(argv, argc); 427 char *command = join_args(argv, argc);
423 sway_log(SWAY_DEBUG, "Subcommand: %s", command); 428 sway_log(SWAY_DEBUG, "Subcommand: %s", command);
424 free(command); 429 free(command);
425 430
426 struct cmd_handler *handler = find_handler(argv[0], handlers, 431 const struct cmd_handler *handler = find_handler(argv[0], handlers,
427 handlers_size); 432 handlers_size);
428 if (!handler) { 433 if (!handler) {
429 return cmd_results_new(CMD_INVALID, 434 return cmd_results_new(CMD_INVALID,
@@ -453,7 +458,7 @@ struct cmd_results *config_commands_command(char *exec) {
453 goto cleanup; 458 goto cleanup;
454 } 459 }
455 460
456 struct cmd_handler *handler = find_handler(cmd, NULL, 0); 461 const struct cmd_handler *handler = find_handler(cmd, NULL, 0);
457 if (!handler && strcmp(cmd, "*") != 0) { 462 if (!handler && strcmp(cmd, "*") != 0) {
458 results = cmd_results_new(CMD_INVALID, 463 results = cmd_results_new(CMD_INVALID,
459 "Unknown/invalid command '%s'", cmd); 464 "Unknown/invalid command '%s'", cmd);