diff options
Diffstat (limited to 'sway/criteria.c')
-rw-r--r-- | sway/criteria.c | 116 |
1 files changed, 61 insertions, 55 deletions
diff --git a/sway/criteria.c b/sway/criteria.c index 13176fa1..acc70d1b 100644 --- a/sway/criteria.c +++ b/sway/criteria.c | |||
@@ -18,15 +18,15 @@ bool criteria_is_empty(struct criteria *criteria) { | |||
18 | return !criteria->title | 18 | return !criteria->title |
19 | && !criteria->shell | 19 | && !criteria->shell |
20 | && !criteria->app_id | 20 | && !criteria->app_id |
21 | && !criteria->class | ||
22 | && !criteria->instance | ||
23 | && !criteria->con_mark | 21 | && !criteria->con_mark |
24 | && !criteria->con_id | 22 | && !criteria->con_id |
25 | #ifdef HAVE_XWAYLAND | 23 | #ifdef HAVE_XWAYLAND |
24 | && !criteria->class | ||
26 | && !criteria->id | 25 | && !criteria->id |
27 | #endif | 26 | && !criteria->instance |
28 | && !criteria->window_role | 27 | && !criteria->window_role |
29 | && criteria->window_type == ATOM_LAST | 28 | && criteria->window_type == ATOM_LAST |
29 | #endif | ||
30 | && !criteria->floating | 30 | && !criteria->floating |
31 | && !criteria->tiling | 31 | && !criteria->tiling |
32 | && !criteria->urgent | 32 | && !criteria->urgent |
@@ -37,10 +37,12 @@ void criteria_destroy(struct criteria *criteria) { | |||
37 | pcre_free(criteria->title); | 37 | pcre_free(criteria->title); |
38 | pcre_free(criteria->shell); | 38 | pcre_free(criteria->shell); |
39 | pcre_free(criteria->app_id); | 39 | pcre_free(criteria->app_id); |
40 | #ifdef HAVE_XWAYLAND | ||
40 | pcre_free(criteria->class); | 41 | pcre_free(criteria->class); |
41 | pcre_free(criteria->instance); | 42 | pcre_free(criteria->instance); |
42 | pcre_free(criteria->con_mark); | ||
43 | pcre_free(criteria->window_role); | 43 | pcre_free(criteria->window_role); |
44 | #endif | ||
45 | pcre_free(criteria->con_mark); | ||
44 | free(criteria->workspace); | 46 | free(criteria->workspace); |
45 | free(criteria->cmdlist); | 47 | free(criteria->cmdlist); |
46 | free(criteria->raw); | 48 | free(criteria->raw); |
@@ -51,8 +53,8 @@ static int regex_cmp(const char *item, const pcre *regex) { | |||
51 | return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); | 53 | return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); |
52 | } | 54 | } |
53 | 55 | ||
54 | static bool view_has_window_type(struct sway_view *view, enum atom_name name) { | ||
55 | #ifdef HAVE_XWAYLAND | 56 | #ifdef HAVE_XWAYLAND |
57 | static bool view_has_window_type(struct sway_view *view, enum atom_name name) { | ||
56 | if (view->type != SWAY_VIEW_XWAYLAND) { | 58 | if (view->type != SWAY_VIEW_XWAYLAND) { |
57 | return false; | 59 | return false; |
58 | } | 60 | } |
@@ -64,9 +66,9 @@ static bool view_has_window_type(struct sway_view *view, enum atom_name name) { | |||
64 | return true; | 66 | return true; |
65 | } | 67 | } |
66 | } | 68 | } |
67 | #endif | ||
68 | return false; | 69 | return false; |
69 | } | 70 | } |
71 | #endif | ||
70 | 72 | ||
71 | static int cmp_urgent(const void *_a, const void *_b) { | 73 | static int cmp_urgent(const void *_a, const void *_b) { |
72 | struct sway_view *a = *(void **)_a; | 74 | struct sway_view *a = *(void **)_a; |
@@ -115,21 +117,7 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
115 | return false; | 117 | return false; |
116 | } | 118 | } |
117 | } | 119 | } |
118 | 120 | ||
119 | if (criteria->class) { | ||
120 | const char *class = view_get_class(view); | ||
121 | if (!class || regex_cmp(class, criteria->class) != 0) { | ||
122 | return false; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | if (criteria->instance) { | ||
127 | const char *instance = view_get_instance(view); | ||
128 | if (!instance || regex_cmp(instance, criteria->instance) != 0) { | ||
129 | return false; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | if (criteria->con_mark) { | 121 | if (criteria->con_mark) { |
134 | bool exists = false; | 122 | bool exists = false; |
135 | for (int i = 0; i < view->marks->length; ++i) { | 123 | for (int i = 0; i < view->marks->length; ++i) { |
@@ -156,7 +144,20 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
156 | return false; | 144 | return false; |
157 | } | 145 | } |
158 | } | 146 | } |
159 | #endif | 147 | |
148 | if (criteria->class) { | ||
149 | const char *class = view_get_class(view); | ||
150 | if (!class || regex_cmp(class, criteria->class) != 0) { | ||
151 | return false; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (criteria->instance) { | ||
156 | const char *instance = view_get_instance(view); | ||
157 | if (!instance || regex_cmp(instance, criteria->instance) != 0) { | ||
158 | return false; | ||
159 | } | ||
160 | } | ||
160 | 161 | ||
161 | if (criteria->window_role) { | 162 | if (criteria->window_role) { |
162 | // TODO | 163 | // TODO |
@@ -167,6 +168,7 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
167 | return false; | 168 | return false; |
168 | } | 169 | } |
169 | } | 170 | } |
171 | #endif | ||
170 | 172 | ||
171 | if (criteria->floating) { | 173 | if (criteria->floating) { |
172 | if (!container_is_floating(view->swayc)) { | 174 | if (!container_is_floating(view->swayc)) { |
@@ -271,6 +273,7 @@ static bool generate_regex(pcre **regex, char *value) { | |||
271 | return true; | 273 | return true; |
272 | } | 274 | } |
273 | 275 | ||
276 | #ifdef HAVE_XWAYLAND | ||
274 | static enum atom_name parse_window_type(const char *type) { | 277 | static enum atom_name parse_window_type(const char *type) { |
275 | if (strcasecmp(type, "normal") == 0) { | 278 | if (strcasecmp(type, "normal") == 0) { |
276 | return NET_WM_WINDOW_TYPE_NORMAL; | 279 | return NET_WM_WINDOW_TYPE_NORMAL; |
@@ -285,23 +288,24 @@ static enum atom_name parse_window_type(const char *type) { | |||
285 | } | 288 | } |
286 | return ATOM_LAST; // ie. invalid | 289 | return ATOM_LAST; // ie. invalid |
287 | } | 290 | } |
291 | #endif | ||
288 | 292 | ||
289 | enum criteria_token { | 293 | enum criteria_token { |
290 | T_APP_ID, | 294 | T_APP_ID, |
291 | T_CLASS, | ||
292 | T_CON_ID, | 295 | T_CON_ID, |
293 | T_CON_MARK, | 296 | T_CON_MARK, |
294 | T_FLOATING, | 297 | T_FLOATING, |
295 | #ifdef HAVE_XWAYLAND | 298 | #ifdef HAVE_XWAYLAND |
299 | T_CLASS, | ||
296 | T_ID, | 300 | T_ID, |
297 | #endif | ||
298 | T_INSTANCE, | 301 | T_INSTANCE, |
302 | T_WINDOW_ROLE, | ||
303 | T_WINDOW_TYPE, | ||
304 | #endif | ||
299 | T_SHELL, | 305 | T_SHELL, |
300 | T_TILING, | 306 | T_TILING, |
301 | T_TITLE, | 307 | T_TITLE, |
302 | T_URGENT, | 308 | T_URGENT, |
303 | T_WINDOW_ROLE, | ||
304 | T_WINDOW_TYPE, | ||
305 | T_WORKSPACE, | 309 | T_WORKSPACE, |
306 | 310 | ||
307 | T_INVALID, | 311 | T_INVALID, |
@@ -310,28 +314,28 @@ enum criteria_token { | |||
310 | static enum criteria_token token_from_name(char *name) { | 314 | static enum criteria_token token_from_name(char *name) { |
311 | if (strcmp(name, "app_id") == 0) { | 315 | if (strcmp(name, "app_id") == 0) { |
312 | return T_APP_ID; | 316 | return T_APP_ID; |
313 | } else if (strcmp(name, "class") == 0) { | ||
314 | return T_CLASS; | ||
315 | } else if (strcmp(name, "con_id") == 0) { | 317 | } else if (strcmp(name, "con_id") == 0) { |
316 | return T_CON_ID; | 318 | return T_CON_ID; |
317 | } else if (strcmp(name, "con_mark") == 0) { | 319 | } else if (strcmp(name, "con_mark") == 0) { |
318 | return T_CON_MARK; | 320 | return T_CON_MARK; |
319 | #ifdef HAVE_XWAYLAND | 321 | #ifdef HAVE_XWAYLAND |
322 | } else if (strcmp(name, "class") == 0) { | ||
323 | return T_CLASS; | ||
320 | } else if (strcmp(name, "id") == 0) { | 324 | } else if (strcmp(name, "id") == 0) { |
321 | return T_ID; | 325 | return T_ID; |
322 | #endif | ||
323 | } else if (strcmp(name, "instance") == 0) { | 326 | } else if (strcmp(name, "instance") == 0) { |
324 | return T_INSTANCE; | 327 | return T_INSTANCE; |
328 | } else if (strcmp(name, "window_role") == 0) { | ||
329 | return T_WINDOW_ROLE; | ||
330 | } else if (strcmp(name, "window_type") == 0) { | ||
331 | return T_WINDOW_TYPE; | ||
332 | #endif | ||
325 | } else if (strcmp(name, "shell") == 0) { | 333 | } else if (strcmp(name, "shell") == 0) { |
326 | return T_SHELL; | 334 | return T_SHELL; |
327 | } else if (strcmp(name, "title") == 0) { | 335 | } else if (strcmp(name, "title") == 0) { |
328 | return T_TITLE; | 336 | return T_TITLE; |
329 | } else if (strcmp(name, "urgent") == 0) { | 337 | } else if (strcmp(name, "urgent") == 0) { |
330 | return T_URGENT; | 338 | return T_URGENT; |
331 | } else if (strcmp(name, "window_role") == 0) { | ||
332 | return T_WINDOW_ROLE; | ||
333 | } else if (strcmp(name, "window_type") == 0) { | ||
334 | return T_WINDOW_TYPE; | ||
335 | } else if (strcmp(name, "workspace") == 0) { | 339 | } else if (strcmp(name, "workspace") == 0) { |
336 | return T_WORKSPACE; | 340 | return T_WORKSPACE; |
337 | } | 341 | } |
@@ -360,21 +364,12 @@ static char *get_focused_prop(enum criteria_token token) { | |||
360 | case T_APP_ID: | 364 | case T_APP_ID: |
361 | value = view_get_app_id(view); | 365 | value = view_get_app_id(view); |
362 | break; | 366 | break; |
363 | case T_CLASS: | ||
364 | value = view_get_class(view); | ||
365 | break; | ||
366 | case T_INSTANCE: | ||
367 | value = view_get_instance(view); | ||
368 | break; | ||
369 | case T_SHELL: | 367 | case T_SHELL: |
370 | value = view_get_shell(view); | 368 | value = view_get_shell(view); |
371 | break; | 369 | break; |
372 | case T_TITLE: | 370 | case T_TITLE: |
373 | value = view_get_class(view); | 371 | value = view_get_class(view); |
374 | break; | 372 | break; |
375 | case T_WINDOW_ROLE: | ||
376 | value = view_get_class(view); | ||
377 | break; | ||
378 | case T_WORKSPACE: | 373 | case T_WORKSPACE: |
379 | { | 374 | { |
380 | struct sway_container *ws = container_parent(focus, C_WORKSPACE); | 375 | struct sway_container *ws = container_parent(focus, C_WORKSPACE); |
@@ -396,11 +391,20 @@ static char *get_focused_prop(enum criteria_token token) { | |||
396 | case T_CON_MARK: // These do not support __focused__ | 391 | case T_CON_MARK: // These do not support __focused__ |
397 | case T_FLOATING: | 392 | case T_FLOATING: |
398 | #ifdef HAVE_XWAYLAND | 393 | #ifdef HAVE_XWAYLAND |
394 | case T_CLASS: | ||
395 | value = view_get_class(view); | ||
396 | break; | ||
399 | case T_ID: | 397 | case T_ID: |
398 | case T_INSTANCE: | ||
399 | value = view_get_instance(view); | ||
400 | break; | ||
401 | case T_WINDOW_ROLE: | ||
402 | value = view_get_class(view); | ||
403 | break; | ||
404 | case T_WINDOW_TYPE: | ||
400 | #endif | 405 | #endif |
401 | case T_TILING: | 406 | case T_TILING: |
402 | case T_URGENT: | 407 | case T_URGENT: |
403 | case T_WINDOW_TYPE: | ||
404 | case T_INVALID: | 408 | case T_INVALID: |
405 | break; | 409 | break; |
406 | } | 410 | } |
@@ -447,12 +451,6 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { | |||
447 | case T_APP_ID: | 451 | case T_APP_ID: |
448 | generate_regex(&criteria->app_id, effective_value); | 452 | generate_regex(&criteria->app_id, effective_value); |
449 | break; | 453 | break; |
450 | case T_CLASS: | ||
451 | generate_regex(&criteria->class, effective_value); | ||
452 | break; | ||
453 | case T_INSTANCE: | ||
454 | generate_regex(&criteria->instance, effective_value); | ||
455 | break; | ||
456 | case T_CON_ID: | 454 | case T_CON_ID: |
457 | criteria->con_id = strtoul(effective_value, &endptr, 10); | 455 | criteria->con_id = strtoul(effective_value, &endptr, 10); |
458 | if (*endptr != 0) { | 456 | if (*endptr != 0) { |
@@ -462,19 +460,25 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { | |||
462 | case T_CON_MARK: | 460 | case T_CON_MARK: |
463 | generate_regex(&criteria->con_mark, effective_value); | 461 | generate_regex(&criteria->con_mark, effective_value); |
464 | break; | 462 | break; |
465 | case T_WINDOW_ROLE: | ||
466 | generate_regex(&criteria->window_role, effective_value); | ||
467 | break; | ||
468 | case T_WINDOW_TYPE: | ||
469 | criteria->window_type = parse_window_type(effective_value); | ||
470 | break; | ||
471 | #ifdef HAVE_XWAYLAND | 463 | #ifdef HAVE_XWAYLAND |
464 | case T_CLASS: | ||
465 | generate_regex(&criteria->class, effective_value); | ||
466 | break; | ||
472 | case T_ID: | 467 | case T_ID: |
473 | criteria->id = strtoul(effective_value, &endptr, 10); | 468 | criteria->id = strtoul(effective_value, &endptr, 10); |
474 | if (*endptr != 0) { | 469 | if (*endptr != 0) { |
475 | error = strdup("The value for 'id' should be numeric"); | 470 | error = strdup("The value for 'id' should be numeric"); |
476 | } | 471 | } |
477 | break; | 472 | break; |
473 | case T_INSTANCE: | ||
474 | generate_regex(&criteria->instance, effective_value); | ||
475 | break; | ||
476 | case T_WINDOW_ROLE: | ||
477 | generate_regex(&criteria->window_role, effective_value); | ||
478 | break; | ||
479 | case T_WINDOW_TYPE: | ||
480 | criteria->window_type = parse_window_type(effective_value); | ||
481 | break; | ||
478 | #endif | 482 | #endif |
479 | case T_FLOATING: | 483 | case T_FLOATING: |
480 | criteria->floating = true; | 484 | criteria->floating = true; |
@@ -559,7 +563,9 @@ struct criteria *criteria_parse(char *raw, char **error_arg) { | |||
559 | ++head; | 563 | ++head; |
560 | 564 | ||
561 | struct criteria *criteria = calloc(1, sizeof(struct criteria)); | 565 | struct criteria *criteria = calloc(1, sizeof(struct criteria)); |
566 | #ifdef HAVE_XWAYLAND | ||
562 | criteria->window_type = ATOM_LAST; // default value | 567 | criteria->window_type = ATOM_LAST; // default value |
568 | #endif | ||
563 | char *name = NULL, *value = NULL; | 569 | char *name = NULL, *value = NULL; |
564 | bool in_quotes = false; | 570 | bool in_quotes = false; |
565 | 571 | ||