diff --git a/include/sway/criteria.h b/include/sway/criteria.h index fad278e02..c70299419 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h @@ -84,8 +84,9 @@ struct criteria *criteria_parse(char *raw, char **error); list_t *criteria_for_view(struct sway_view *view, enum criteria_type types); /** - * Compile a list of containers matching the given criteria. + * Compile a list of nodes matching the given criteria. + * Returns a list of struct sway_node *. */ -list_t *criteria_get_containers(struct criteria *criteria); +list_t *criteria_get_nodes(struct criteria *criteria); #endif diff --git a/sway/commands.c b/sway/commands.c index c2c12ee65..f767927ad 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -206,7 +206,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, struct sway_container *con) { char *cmd; char matched_delim = ';'; - list_t *containers = NULL; + list_t *nodes = NULL; bool using_criteria = false; if (seat == NULL) { @@ -241,8 +241,8 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, free(error); goto cleanup; } - list_free(containers); - containers = criteria_get_containers(criteria); + list_free(nodes); + nodes = criteria_get_nodes(criteria); head += strlen(criteria->raw); criteria_destroy(criteria); using_criteria = true; @@ -298,14 +298,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, free_argv(argc, argv); goto cleanup; } - } else if (containers->length == 0) { + } else if (nodes->length == 0) { list_add(res_list, cmd_results_new(CMD_FAILURE, "No matching node.")); } else { struct cmd_results *fail_res = NULL; - for (int i = 0; i < containers->length; ++i) { - struct sway_container *container = containers->items[i]; - set_config_node(&container->node, true); + for (int i = 0; i < nodes->length; ++i) { + struct sway_node *node = nodes->items[i]; + set_config_node(node, true); struct cmd_results *res = handler->handle(argc-1, argv+1); if (res->status == CMD_SUCCESS) { free_cmd_results(res); @@ -329,7 +329,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat, } while(head); cleanup: free(exec); - list_free(containers); + list_free(nodes); return res_list; } diff --git a/sway/criteria.c b/sway/criteria.c index e200d4c8f..8c6bd7249 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -493,27 +493,41 @@ struct match_data { list_t *matches; }; -static void criteria_get_containers_iterator(struct sway_container *container, +static void criteria_get_nodes_container_iterator(struct sway_container *container, void *data) { struct match_data *match_data = data; if (container->view) { if (criteria_matches_view(match_data->criteria, container->view)) { - list_add(match_data->matches, container); + list_add(match_data->matches, &container->node); } } else if (has_container_criteria(match_data->criteria)) { if (criteria_matches_container(match_data->criteria, container)) { - list_add(match_data->matches, container); + list_add(match_data->matches, &container->node); } } } -list_t *criteria_get_containers(struct criteria *criteria) { +static void criteria_get_nodes_workspace_iterator(struct sway_workspace *workspace, + void *data) { + struct match_data *match_data = data; + // Workspaces only support con_id matching (not con_mark, since they don't have marks) + if (match_data->criteria->con_id && + workspace->node.id == match_data->criteria->con_id) { + list_add(match_data->matches, &workspace->node); + } +} + +list_t *criteria_get_nodes(struct criteria *criteria) { list_t *matches = create_list(); struct match_data data = { .criteria = criteria, .matches = matches, }; - root_for_each_container(criteria_get_containers_iterator, &data); + root_for_each_container(criteria_get_nodes_container_iterator, &data); + // Also check workspaces for con_id matching + if (criteria->con_id && !criteria->con_mark) { + root_for_each_workspace(criteria_get_nodes_workspace_iterator, &data); + } return matches; }