diff options
-rw-r--r-- | common/stringop.c | 14 | ||||
-rw-r--r-- | include/stringop.h | 2 | ||||
-rw-r--r-- | include/sway/criteria.h | 2 | ||||
-rw-r--r-- | include/sway/xwayland.h | 1 | ||||
-rw-r--r-- | sway/commands.c | 2 | ||||
-rw-r--r-- | sway/commands/bind.c | 2 | ||||
-rw-r--r-- | sway/commands/border.c | 6 | ||||
-rw-r--r-- | sway/criteria.c | 45 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 3 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 1 | ||||
-rw-r--r-- | sway/input/seat.c | 2 |
11 files changed, 66 insertions, 14 deletions
diff --git a/common/stringop.c b/common/stringop.c index d9ae9925..d2c91c24 100644 --- a/common/stringop.c +++ b/common/stringop.c | |||
@@ -401,3 +401,17 @@ char *argsep(char **stringp, const char *delim) { | |||
401 | found: | 401 | found: |
402 | return start; | 402 | return start; |
403 | } | 403 | } |
404 | |||
405 | const char *strcasestr(const char *haystack, const char *needle) { | ||
406 | size_t needle_len = strlen(needle); | ||
407 | const char *pos = haystack; | ||
408 | const char *end = pos + strlen(haystack) - needle_len; | ||
409 | |||
410 | while (pos <= end) { | ||
411 | if (strncasecmp(pos, needle, needle_len) == 0) { | ||
412 | return pos; | ||
413 | } | ||
414 | ++pos; | ||
415 | } | ||
416 | return NULL; | ||
417 | } | ||
diff --git a/include/stringop.h b/include/stringop.h index e7f58011..01bbdaa9 100644 --- a/include/stringop.h +++ b/include/stringop.h | |||
@@ -46,4 +46,6 @@ char *cmdsep(char **stringp, const char *delim); | |||
46 | // Split string into 2 by delim, handle quotes | 46 | // Split string into 2 by delim, handle quotes |
47 | char *argsep(char **stringp, const char *delim); | 47 | char *argsep(char **stringp, const char *delim); |
48 | 48 | ||
49 | const char *strcasestr(const char *haystack, const char *needle); | ||
50 | |||
49 | #endif | 51 | #endif |
diff --git a/include/sway/criteria.h b/include/sway/criteria.h index 7a1e547b..af12ffd7 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h | |||
@@ -31,7 +31,7 @@ struct criteria { | |||
31 | uint32_t id; // X11 window ID | 31 | uint32_t id; // X11 window ID |
32 | #endif | 32 | #endif |
33 | pcre *window_role; | 33 | pcre *window_role; |
34 | uint32_t window_type; | 34 | enum atom_name window_type; |
35 | bool floating; | 35 | bool floating; |
36 | bool tiling; | 36 | bool tiling; |
37 | char urgent; // 'l' for latest or 'o' for oldest | 37 | char urgent; // 'l' for latest or 'o' for oldest |
diff --git a/include/sway/xwayland.h b/include/sway/xwayland.h index 78d1053b..121edad3 100644 --- a/include/sway/xwayland.h +++ b/include/sway/xwayland.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <xcb/xproto.h> | 5 | #include <xcb/xproto.h> |
6 | 6 | ||
7 | enum atom_name { | 7 | enum atom_name { |
8 | NET_WM_WINDOW_TYPE_NORMAL, | ||
8 | NET_WM_WINDOW_TYPE_DIALOG, | 9 | NET_WM_WINDOW_TYPE_DIALOG, |
9 | NET_WM_WINDOW_TYPE_UTILITY, | 10 | NET_WM_WINDOW_TYPE_UTILITY, |
10 | NET_WM_WINDOW_TYPE_TOOLBAR, | 11 | NET_WM_WINDOW_TYPE_TOOLBAR, |
diff --git a/sway/commands.c b/sway/commands.c index d9c54adc..13f5983e 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -118,6 +118,8 @@ static struct cmd_handler handlers[] = { | |||
118 | { "input", cmd_input }, | 118 | { "input", cmd_input }, |
119 | { "mode", cmd_mode }, | 119 | { "mode", cmd_mode }, |
120 | { "mouse_warping", cmd_mouse_warping }, | 120 | { "mouse_warping", cmd_mouse_warping }, |
121 | { "new_float", cmd_default_floating_border }, | ||
122 | { "new_window", cmd_default_border }, | ||
121 | { "no_focus", cmd_no_focus }, | 123 | { "no_focus", cmd_no_focus }, |
122 | { "output", cmd_output }, | 124 | { "output", cmd_output }, |
123 | { "seat", cmd_seat }, | 125 | { "seat", cmd_seat }, |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 8270b958..b134c92f 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -310,7 +310,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) | |||
310 | bool reload = false; | 310 | bool reload = false; |
311 | // if this is a reload command we need to make a duplicate of the | 311 | // if this is a reload command we need to make a duplicate of the |
312 | // binding since it will be gone after the reload has completed. | 312 | // binding since it will be gone after the reload has completed. |
313 | if (strcasecmp(binding->command, "reload") == 0) { | 313 | if (strcasestr(binding->command, "reload")) { |
314 | reload = true; | 314 | reload = true; |
315 | binding_copy = sway_binding_dup(binding); | 315 | binding_copy = sway_binding_dup(binding); |
316 | if (!binding_copy) { | 316 | if (!binding_copy) { |
diff --git a/sway/commands/border.c b/sway/commands/border.c index 9c19e20a..9502c877 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c | |||
@@ -27,9 +27,6 @@ struct cmd_results *cmd_border(int argc, char **argv) { | |||
27 | view->border = B_NORMAL; | 27 | view->border = B_NORMAL; |
28 | } else if (strcmp(argv[0], "pixel") == 0) { | 28 | } else if (strcmp(argv[0], "pixel") == 0) { |
29 | view->border = B_PIXEL; | 29 | view->border = B_PIXEL; |
30 | if (argc == 2) { | ||
31 | view->border_thickness = atoi(argv[1]); | ||
32 | } | ||
33 | } else if (strcmp(argv[0], "toggle") == 0) { | 30 | } else if (strcmp(argv[0], "toggle") == 0) { |
34 | view->border = (view->border + 1) % 3; | 31 | view->border = (view->border + 1) % 3; |
35 | } else { | 32 | } else { |
@@ -37,6 +34,9 @@ struct cmd_results *cmd_border(int argc, char **argv) { | |||
37 | "Expected 'border <none|normal|pixel|toggle>' " | 34 | "Expected 'border <none|normal|pixel|toggle>' " |
38 | "or 'border pixel <px>'"); | 35 | "or 'border pixel <px>'"); |
39 | } | 36 | } |
37 | if (argc == 2) { | ||
38 | view->border_thickness = atoi(argv[1]); | ||
39 | } | ||
40 | 40 | ||
41 | if (container_is_floating(view->swayc)) { | 41 | if (container_is_floating(view->swayc)) { |
42 | container_set_geometry_from_floating_view(view->swayc); | 42 | container_set_geometry_from_floating_view(view->swayc); |
diff --git a/sway/criteria.c b/sway/criteria.c index 5452c4ee..13176fa1 100644 --- a/sway/criteria.c +++ b/sway/criteria.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include <strings.h> | ||
5 | #include <pcre.h> | 6 | #include <pcre.h> |
6 | #include "sway/criteria.h" | 7 | #include "sway/criteria.h" |
7 | #include "sway/tree/container.h" | 8 | #include "sway/tree/container.h" |
@@ -25,7 +26,7 @@ bool criteria_is_empty(struct criteria *criteria) { | |||
25 | && !criteria->id | 26 | && !criteria->id |
26 | #endif | 27 | #endif |
27 | && !criteria->window_role | 28 | && !criteria->window_role |
28 | && !criteria->window_type | 29 | && criteria->window_type == ATOM_LAST |
29 | && !criteria->floating | 30 | && !criteria->floating |
30 | && !criteria->tiling | 31 | && !criteria->tiling |
31 | && !criteria->urgent | 32 | && !criteria->urgent |
@@ -50,6 +51,23 @@ static int regex_cmp(const char *item, const pcre *regex) { | |||
50 | return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); | 51 | return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); |
51 | } | 52 | } |
52 | 53 | ||
54 | static bool view_has_window_type(struct sway_view *view, enum atom_name name) { | ||
55 | #ifdef HAVE_XWAYLAND | ||
56 | if (view->type != SWAY_VIEW_XWAYLAND) { | ||
57 | return false; | ||
58 | } | ||
59 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | ||
60 | struct sway_xwayland *xwayland = &server.xwayland; | ||
61 | xcb_atom_t desired_atom = xwayland->atoms[name]; | ||
62 | for (size_t i = 0; i < surface->window_type_len; ++i) { | ||
63 | if (surface->window_type[i] == desired_atom) { | ||
64 | return true; | ||
65 | } | ||
66 | } | ||
67 | #endif | ||
68 | return false; | ||
69 | } | ||
70 | |||
53 | static int cmp_urgent(const void *_a, const void *_b) { | 71 | static int cmp_urgent(const void *_a, const void *_b) { |
54 | struct sway_view *a = *(void **)_a; | 72 | struct sway_view *a = *(void **)_a; |
55 | struct sway_view *b = *(void **)_b; | 73 | struct sway_view *b = *(void **)_b; |
@@ -144,9 +162,8 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
144 | // TODO | 162 | // TODO |
145 | } | 163 | } |
146 | 164 | ||
147 | if (criteria->window_type) { | 165 | if (criteria->window_type != ATOM_LAST) { |
148 | uint32_t type = view_get_window_type(view); | 166 | if (!view_has_window_type(view, criteria->window_type)) { |
149 | if (!type || type != criteria->window_type) { | ||
150 | return false; | 167 | return false; |
151 | } | 168 | } |
152 | } | 169 | } |
@@ -254,6 +271,21 @@ static bool generate_regex(pcre **regex, char *value) { | |||
254 | return true; | 271 | return true; |
255 | } | 272 | } |
256 | 273 | ||
274 | static enum atom_name parse_window_type(const char *type) { | ||
275 | if (strcasecmp(type, "normal") == 0) { | ||
276 | return NET_WM_WINDOW_TYPE_NORMAL; | ||
277 | } else if (strcasecmp(type, "dialog") == 0) { | ||
278 | return NET_WM_WINDOW_TYPE_DIALOG; | ||
279 | } else if (strcasecmp(type, "utility") == 0) { | ||
280 | return NET_WM_WINDOW_TYPE_UTILITY; | ||
281 | } else if (strcasecmp(type, "toolbar") == 0) { | ||
282 | return NET_WM_WINDOW_TYPE_TOOLBAR; | ||
283 | } else if (strcasecmp(type, "splash") == 0) { | ||
284 | return NET_WM_WINDOW_TYPE_SPLASH; | ||
285 | } | ||
286 | return ATOM_LAST; // ie. invalid | ||
287 | } | ||
288 | |||
257 | enum criteria_token { | 289 | enum criteria_token { |
258 | T_APP_ID, | 290 | T_APP_ID, |
259 | T_CLASS, | 291 | T_CLASS, |
@@ -434,7 +466,7 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { | |||
434 | generate_regex(&criteria->window_role, effective_value); | 466 | generate_regex(&criteria->window_role, effective_value); |
435 | break; | 467 | break; |
436 | case T_WINDOW_TYPE: | 468 | case T_WINDOW_TYPE: |
437 | // TODO: This is a string but will be stored as an enum or integer | 469 | criteria->window_type = parse_window_type(effective_value); |
438 | break; | 470 | break; |
439 | #ifdef HAVE_XWAYLAND | 471 | #ifdef HAVE_XWAYLAND |
440 | case T_ID: | 472 | case T_ID: |
@@ -526,7 +558,8 @@ struct criteria *criteria_parse(char *raw, char **error_arg) { | |||
526 | } | 558 | } |
527 | ++head; | 559 | ++head; |
528 | 560 | ||
529 | struct criteria *criteria = calloc(sizeof(struct criteria), 1); | 561 | struct criteria *criteria = calloc(1, sizeof(struct criteria)); |
562 | criteria->window_type = ATOM_LAST; // default value | ||
530 | char *name = NULL, *value = NULL; | 563 | char *name = NULL, *value = NULL; |
531 | bool in_quotes = false; | 564 | bool in_quotes = false; |
532 | 565 | ||
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 1fae5db2..a4f7f928 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -176,7 +176,7 @@ void arrange_layers(struct sway_output *output) { | |||
176 | sizeof(struct wlr_box)) != 0) { | 176 | sizeof(struct wlr_box)) != 0) { |
177 | wlr_log(WLR_DEBUG, "Usable area changed, rearranging output"); | 177 | wlr_log(WLR_DEBUG, "Usable area changed, rearranging output"); |
178 | memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); | 178 | memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); |
179 | container_set_dirty(output->swayc); | 179 | arrange_output(output->swayc); |
180 | } | 180 | } |
181 | 181 | ||
182 | // Arrange non-exlusive surfaces from top->bottom | 182 | // Arrange non-exlusive surfaces from top->bottom |
@@ -247,7 +247,6 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
247 | layer_surface->surface, false); | 247 | layer_surface->surface, false); |
248 | } | 248 | } |
249 | 249 | ||
250 | arrange_windows(output->swayc); | ||
251 | transaction_commit_dirty(); | 250 | transaction_commit_dirty(); |
252 | } | 251 | } |
253 | 252 | ||
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4e401008..2adc28c5 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "sway/tree/view.h" | 17 | #include "sway/tree/view.h" |
18 | 18 | ||
19 | static const char *atom_map[ATOM_LAST] = { | 19 | static const char *atom_map[ATOM_LAST] = { |
20 | "_NET_WM_WINDOW_TYPE_NORMAL", | ||
20 | "_NET_WM_WINDOW_TYPE_DIALOG", | 21 | "_NET_WM_WINDOW_TYPE_DIALOG", |
21 | "_NET_WM_WINDOW_TYPE_UTILITY", | 22 | "_NET_WM_WINDOW_TYPE_UTILITY", |
22 | "_NET_WM_WINDOW_TYPE_TOOLBAR", | 23 | "_NET_WM_WINDOW_TYPE_TOOLBAR", |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 6a6e3096..4b7c7893 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -779,7 +779,7 @@ void seat_set_focus_layer(struct sway_seat *seat, | |||
779 | wlr_log(WLR_DEBUG, "Returning focus to %p %s '%s'", previous, | 779 | wlr_log(WLR_DEBUG, "Returning focus to %p %s '%s'", previous, |
780 | container_type_to_str(previous->type), previous->name); | 780 | container_type_to_str(previous->type), previous->name); |
781 | // Hack to get seat to re-focus the return value of get_focus | 781 | // Hack to get seat to re-focus the return value of get_focus |
782 | seat_set_focus(seat, previous->parent); | 782 | seat_set_focus(seat, NULL); |
783 | seat_set_focus(seat, previous); | 783 | seat_set_focus(seat, previous); |
784 | } | 784 | } |
785 | return; | 785 | return; |