diff options
author | Anders <a@anrd.net> | 2020-01-26 10:27:52 +0100 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2020-02-04 19:52:21 -0500 |
commit | 4e46bdf73dc2e9f98ca14263f42dde664f7d2aba (patch) | |
tree | 57ccf6bb1989b050fb86b260e3bef0dbcec7d838 | |
parent | Change wording (diff) | |
download | sway-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.h | 4 | ||||
-rw-r--r-- | sway/commands.c | 16 | ||||
-rw-r--r-- | sway/criteria.c | 61 |
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); | |||
73 | list_t *criteria_for_view(struct sway_view *view, enum criteria_type types); | 73 | list_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 | */ |
78 | list_t *criteria_get_views(struct criteria *criteria); | 78 | list_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); |
321 | cleanup: | 321 | cleanup: |
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 | ||
147 | static bool has_container_criteria(struct criteria *criteria) { | ||
148 | return criteria->con_mark || criteria->con_id; | ||
149 | } | ||
150 | |||
151 | static 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 | |||
147 | static bool criteria_matches_view(struct criteria *criteria, | 176 | static 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 | ||
380 | static void criteria_get_views_iterator(struct sway_container *container, | 393 | static 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 | ||
390 | list_t *criteria_get_views(struct criteria *criteria) { | 407 | list_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 | ||