mirror of
https://github.com/swaywm/sway.git
synced 2024-11-29 11:21:28 +00:00
criteria: match containers without view
Closes #4929 Replaces criteria_get_views with criteria_get_containers which can return containers without views when the criteria only contains container properties.
This commit is contained in:
parent
3f0225eea3
commit
4e46bdf73d
|
@ -73,8 +73,8 @@ struct criteria *criteria_parse(char *raw, char **error);
|
||||||
list_t *criteria_for_view(struct sway_view *view, enum criteria_type types);
|
list_t *criteria_for_view(struct sway_view *view, enum criteria_type types);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile a list of views matching the given criteria.
|
* Compile a list of containers matching the given criteria.
|
||||||
*/
|
*/
|
||||||
list_t *criteria_get_views(struct criteria *criteria);
|
list_t *criteria_get_containers(struct criteria *criteria);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -201,7 +201,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
|
||||||
struct sway_container *con) {
|
struct sway_container *con) {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char matched_delim = ';';
|
char matched_delim = ';';
|
||||||
list_t *views = NULL;
|
list_t *containers = NULL;
|
||||||
|
|
||||||
if (seat == NULL) {
|
if (seat == NULL) {
|
||||||
// passing a NULL seat means we just pick the default seat
|
// passing a NULL seat means we just pick the default seat
|
||||||
|
@ -235,8 +235,8 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
|
||||||
free(error);
|
free(error);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
list_free(views);
|
list_free(containers);
|
||||||
views = criteria_get_views(criteria);
|
containers = criteria_get_containers(criteria);
|
||||||
head += strlen(criteria->raw);
|
head += strlen(criteria->raw);
|
||||||
criteria_destroy(criteria);
|
criteria_destroy(criteria);
|
||||||
config->handler_context.using_criteria = true;
|
config->handler_context.using_criteria = true;
|
||||||
|
@ -289,14 +289,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
|
||||||
free_argv(argc, argv);
|
free_argv(argc, argv);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else if (views->length == 0) {
|
} else if (containers->length == 0) {
|
||||||
list_add(res_list,
|
list_add(res_list,
|
||||||
cmd_results_new(CMD_FAILURE, "No matching node."));
|
cmd_results_new(CMD_FAILURE, "No matching node."));
|
||||||
} else {
|
} else {
|
||||||
struct cmd_results *fail_res = NULL;
|
struct cmd_results *fail_res = NULL;
|
||||||
for (int i = 0; i < views->length; ++i) {
|
for (int i = 0; i < containers->length; ++i) {
|
||||||
struct sway_view *view = views->items[i];
|
struct sway_container *container = containers->items[i];
|
||||||
set_config_node(&view->container->node);
|
set_config_node(&container->node);
|
||||||
struct cmd_results *res = handler->handle(argc-1, argv+1);
|
struct cmd_results *res = handler->handle(argc-1, argv+1);
|
||||||
if (res->status == CMD_SUCCESS) {
|
if (res->status == CMD_SUCCESS) {
|
||||||
free_cmd_results(res);
|
free_cmd_results(res);
|
||||||
|
@ -320,7 +320,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
|
||||||
} while(head);
|
} while(head);
|
||||||
cleanup:
|
cleanup:
|
||||||
free(exec);
|
free(exec);
|
||||||
list_free(views);
|
list_free(containers);
|
||||||
return res_list;
|
return res_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,35 @@ static void find_urgent_iterator(struct sway_container *con, void *data) {
|
||||||
list_add(urgent_views, con->view);
|
list_add(urgent_views, con->view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool has_container_criteria(struct criteria *criteria) {
|
||||||
|
return criteria->con_mark || criteria->con_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool criteria_matches_container(struct criteria *criteria,
|
||||||
|
struct sway_container *container) {
|
||||||
|
if (criteria->con_mark) {
|
||||||
|
bool exists = false;
|
||||||
|
struct sway_container *con = container;
|
||||||
|
for (int i = 0; i < con->marks->length; ++i) {
|
||||||
|
if (regex_cmp(con->marks->items[i], criteria->con_mark->regex) == 0) {
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exists) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (criteria->con_id) { // Internal ID
|
||||||
|
if (container->node.id != criteria->con_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool criteria_matches_view(struct criteria *criteria,
|
static bool criteria_matches_view(struct criteria *criteria,
|
||||||
struct sway_view *view) {
|
struct sway_view *view) {
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
|
@ -210,25 +239,9 @@ static bool criteria_matches_view(struct criteria *criteria,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria->con_mark) {
|
if (!criteria_matches_container(criteria, view->container)) {
|
||||||
bool exists = false;
|
|
||||||
struct sway_container *con = view->container;
|
|
||||||
for (int i = 0; i < con->marks->length; ++i) {
|
|
||||||
if (regex_cmp(con->marks->items[i], criteria->con_mark->regex) == 0) {
|
|
||||||
exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!exists) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (criteria->con_id) { // Internal ID
|
|
||||||
if (!view->container || view->container->node.id != criteria->con_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
if (criteria->id) { // X11 window ID
|
if (criteria->id) { // X11 window ID
|
||||||
|
@ -377,23 +390,27 @@ struct match_data {
|
||||||
list_t *matches;
|
list_t *matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void criteria_get_views_iterator(struct sway_container *container,
|
static void criteria_get_containers_iterator(struct sway_container *container,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct match_data *match_data = data;
|
struct match_data *match_data = data;
|
||||||
if (container->view) {
|
if (container->view) {
|
||||||
if (criteria_matches_view(match_data->criteria, container->view)) {
|
if (criteria_matches_view(match_data->criteria, container->view)) {
|
||||||
list_add(match_data->matches, container->view);
|
list_add(match_data->matches, container);
|
||||||
|
}
|
||||||
|
} else if (has_container_criteria(match_data->criteria)) {
|
||||||
|
if (criteria_matches_container(match_data->criteria, container)) {
|
||||||
|
list_add(match_data->matches, container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_t *criteria_get_views(struct criteria *criteria) {
|
list_t *criteria_get_containers(struct criteria *criteria) {
|
||||||
list_t *matches = create_list();
|
list_t *matches = create_list();
|
||||||
struct match_data data = {
|
struct match_data data = {
|
||||||
.criteria = criteria,
|
.criteria = criteria,
|
||||||
.matches = matches,
|
.matches = matches,
|
||||||
};
|
};
|
||||||
root_for_each_container(criteria_get_views_iterator, &data);
|
root_for_each_container(criteria_get_containers_iterator, &data);
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue