aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Anders <a@anrd.net>2020-01-26 10:27:52 +0100
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2020-02-04 19:52:21 -0500
commit4e46bdf73dc2e9f98ca14263f42dde664f7d2aba (patch)
tree57ccf6bb1989b050fb86b260e3bef0dbcec7d838
parentChange wording (diff)
downloadsway-4e46bdf73dc2e9f98ca14263f42dde664f7d2aba.tar.gz
sway-4e46bdf73dc2e9f98ca14263f42dde664f7d2aba.tar.zst
sway-4e46bdf73dc2e9f98ca14263f42dde664f7d2aba.zip
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.
-rw-r--r--include/sway/criteria.h4
-rw-r--r--sway/commands.c16
-rw-r--r--sway/criteria.c61
3 files changed, 49 insertions, 32 deletions
diff --git a/include/sway/criteria.h b/include/sway/criteria.h
index 1ee69a38..beb76d5f 100644
--- a/include/sway/criteria.h
+++ b/include/sway/criteria.h
@@ -73,8 +73,8 @@ struct criteria *criteria_parse(char *raw, char **error);
73list_t *criteria_for_view(struct sway_view *view, enum criteria_type types); 73list_t *criteria_for_view(struct sway_view *view, enum criteria_type types);
74 74
75/** 75/**
76 * Compile a list of views matching the given criteria. 76 * Compile a list of containers matching the given criteria.
77 */ 77 */
78list_t *criteria_get_views(struct criteria *criteria); 78list_t *criteria_get_containers(struct criteria *criteria);
79 79
80#endif 80#endif
diff --git a/sway/commands.c b/sway/commands.c
index 751dbe9c..6a56ff5a 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -201,7 +201,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
201 struct sway_container *con) { 201 struct sway_container *con) {
202 char *cmd; 202 char *cmd;
203 char matched_delim = ';'; 203 char matched_delim = ';';
204 list_t *views = NULL; 204 list_t *containers = NULL;
205 205
206 if (seat == NULL) { 206 if (seat == NULL) {
207 // passing a NULL seat means we just pick the default seat 207 // 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,
235 free(error); 235 free(error);
236 goto cleanup; 236 goto cleanup;
237 } 237 }
238 list_free(views); 238 list_free(containers);
239 views = criteria_get_views(criteria); 239 containers = criteria_get_containers(criteria);
240 head += strlen(criteria->raw); 240 head += strlen(criteria->raw);
241 criteria_destroy(criteria); 241 criteria_destroy(criteria);
242 config->handler_context.using_criteria = true; 242 config->handler_context.using_criteria = true;
@@ -289,14 +289,14 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
289 free_argv(argc, argv); 289 free_argv(argc, argv);
290 goto cleanup; 290 goto cleanup;
291 } 291 }
292 } else if (views->length == 0) { 292 } else if (containers->length == 0) {
293 list_add(res_list, 293 list_add(res_list,
294 cmd_results_new(CMD_FAILURE, "No matching node.")); 294 cmd_results_new(CMD_FAILURE, "No matching node."));
295 } else { 295 } else {
296 struct cmd_results *fail_res = NULL; 296 struct cmd_results *fail_res = NULL;
297 for (int i = 0; i < views->length; ++i) { 297 for (int i = 0; i < containers->length; ++i) {
298 struct sway_view *view = views->items[i]; 298 struct sway_container *container = containers->items[i];
299 set_config_node(&view->container->node); 299 set_config_node(&container->node);
300 struct cmd_results *res = handler->handle(argc-1, argv+1); 300 struct cmd_results *res = handler->handle(argc-1, argv+1);
301 if (res->status == CMD_SUCCESS) { 301 if (res->status == CMD_SUCCESS) {
302 free_cmd_results(res); 302 free_cmd_results(res);
@@ -320,7 +320,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
320 } while(head); 320 } while(head);
321cleanup: 321cleanup:
322 free(exec); 322 free(exec);
323 list_free(views); 323 list_free(containers);
324 return res_list; 324 return res_list;
325} 325}
326 326
diff --git a/sway/criteria.c b/sway/criteria.c
index eec625af..2c8e1644 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -144,6 +144,35 @@ static void find_urgent_iterator(struct sway_container *con, void *data) {
144 list_add(urgent_views, con->view); 144 list_add(urgent_views, con->view);
145} 145}
146 146
147static bool has_container_criteria(struct criteria *criteria) {
148 return criteria->con_mark || criteria->con_id;
149}
150
151static bool criteria_matches_container(struct criteria *criteria,
152 struct sway_container *container) {
153 if (criteria->con_mark) {
154 bool exists = false;
155 struct sway_container *con = container;
156 for (int i = 0; i < con->marks->length; ++i) {
157 if (regex_cmp(con->marks->items[i], criteria->con_mark->regex) == 0) {
158 exists = true;
159 break;
160 }
161 }
162 if (!exists) {
163 return false;
164 }
165 }
166
167 if (criteria->con_id) { // Internal ID
168 if (container->node.id != criteria->con_id) {
169 return false;
170 }
171 }
172
173 return true;
174}
175
147static bool criteria_matches_view(struct criteria *criteria, 176static bool criteria_matches_view(struct criteria *criteria,
148 struct sway_view *view) { 177 struct sway_view *view) {
149 struct sway_seat *seat = input_manager_current_seat(); 178 struct sway_seat *seat = input_manager_current_seat();
@@ -210,24 +239,8 @@ static bool criteria_matches_view(struct criteria *criteria,
210 } 239 }
211 } 240 }
212 241
213 if (criteria->con_mark) { 242 if (!criteria_matches_container(criteria, view->container)) {
214 bool exists = false; 243 return false;
215 struct sway_container *con = view->container;
216 for (int i = 0; i < con->marks->length; ++i) {
217 if (regex_cmp(con->marks->items[i], criteria->con_mark->regex) == 0) {
218 exists = true;
219 break;
220 }
221 }
222 if (!exists) {
223 return false;
224 }
225 }
226
227 if (criteria->con_id) { // Internal ID
228 if (!view->container || view->container->node.id != criteria->con_id) {
229 return false;
230 }
231 } 244 }
232 245
233#if HAVE_XWAYLAND 246#if HAVE_XWAYLAND
@@ -377,23 +390,27 @@ struct match_data {
377 list_t *matches; 390 list_t *matches;
378}; 391};
379 392
380static void criteria_get_views_iterator(struct sway_container *container, 393static void criteria_get_containers_iterator(struct sway_container *container,
381 void *data) { 394 void *data) {
382 struct match_data *match_data = data; 395 struct match_data *match_data = data;
383 if (container->view) { 396 if (container->view) {
384 if (criteria_matches_view(match_data->criteria, container->view)) { 397 if (criteria_matches_view(match_data->criteria, container->view)) {
385 list_add(match_data->matches, container->view); 398 list_add(match_data->matches, container);
399 }
400 } else if (has_container_criteria(match_data->criteria)) {
401 if (criteria_matches_container(match_data->criteria, container)) {
402 list_add(match_data->matches, container);
386 } 403 }
387 } 404 }
388} 405}
389 406
390list_t *criteria_get_views(struct criteria *criteria) { 407list_t *criteria_get_containers(struct criteria *criteria) {
391 list_t *matches = create_list(); 408 list_t *matches = create_list();
392 struct match_data data = { 409 struct match_data data = {
393 .criteria = criteria, 410 .criteria = criteria,
394 .matches = matches, 411 .matches = matches,
395 }; 412 };
396 root_for_each_container(criteria_get_views_iterator, &data); 413 root_for_each_container(criteria_get_containers_iterator, &data);
397 return matches; 414 return matches;
398} 415}
399 416