diff options
-rw-r--r-- | include/sway/criteria.h | 5 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/no_focus.c | 26 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/tree/view.c | 28 |
5 files changed, 56 insertions, 5 deletions
diff --git a/include/sway/criteria.h b/include/sway/criteria.h index bd3ca0ac..6a8337c5 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h | |||
@@ -6,9 +6,10 @@ | |||
6 | #include "tree/view.h" | 6 | #include "tree/view.h" |
7 | 7 | ||
8 | enum criteria_type { | 8 | enum criteria_type { |
9 | CT_COMMAND = 1 << 0, | 9 | CT_COMMAND = 1 << 0, |
10 | CT_ASSIGN_OUTPUT = 1 << 1, | 10 | CT_ASSIGN_OUTPUT = 1 << 1, |
11 | CT_ASSIGN_WORKSPACE = 1 << 2, | 11 | CT_ASSIGN_WORKSPACE = 1 << 2, |
12 | CT_NO_FOCUS = 1 << 3, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | struct criteria { | 15 | struct criteria { |
diff --git a/sway/commands.c b/sway/commands.c index addd64a6..c2ba02cf 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -114,6 +114,7 @@ static struct cmd_handler handlers[] = { | |||
114 | { "input", cmd_input }, | 114 | { "input", cmd_input }, |
115 | { "mode", cmd_mode }, | 115 | { "mode", cmd_mode }, |
116 | { "mouse_warping", cmd_mouse_warping }, | 116 | { "mouse_warping", cmd_mouse_warping }, |
117 | { "no_focus", cmd_no_focus }, | ||
117 | { "output", cmd_output }, | 118 | { "output", cmd_output }, |
118 | { "seat", cmd_seat }, | 119 | { "seat", cmd_seat }, |
119 | { "set", cmd_set }, | 120 | { "set", cmd_set }, |
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c new file mode 100644 index 00000000..61a8de7e --- /dev/null +++ b/sway/commands/no_focus.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <string.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/criteria.h" | ||
5 | #include "list.h" | ||
6 | #include "log.h" | ||
7 | |||
8 | struct cmd_results *cmd_no_focus(int argc, char **argv) { | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "no_focus", EXPECTED_AT_LEAST, 1))) { | ||
11 | return error; | ||
12 | } | ||
13 | |||
14 | char *err_str = NULL; | ||
15 | struct criteria *criteria = criteria_parse(argv[0], &err_str); | ||
16 | if (!criteria) { | ||
17 | error = cmd_results_new(CMD_INVALID, "no_focus", err_str); | ||
18 | free(err_str); | ||
19 | return error; | ||
20 | } | ||
21 | |||
22 | criteria->type = CT_NO_FOCUS; | ||
23 | list_add(config->criteria, criteria); | ||
24 | |||
25 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
26 | } | ||
diff --git a/sway/meson.build b/sway/meson.build index f878450d..4afef7b4 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -59,6 +59,7 @@ sway_sources = files( | |||
59 | 'commands/mode.c', | 59 | 'commands/mode.c', |
60 | 'commands/mouse_warping.c', | 60 | 'commands/mouse_warping.c', |
61 | 'commands/move.c', | 61 | 'commands/move.c', |
62 | 'commands/no_focus.c', | ||
62 | 'commands/output.c', | 63 | 'commands/output.c', |
63 | 'commands/reload.c', | 64 | 'commands/reload.c', |
64 | 'commands/rename.c', | 65 | 'commands/rename.c', |
diff --git a/sway/tree/view.c b/sway/tree/view.c index bf380d98..bc66a701 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -518,6 +518,26 @@ void view_execute_criteria(struct sway_view *view) { | |||
518 | seat_set_focus(seat, prior_focus); | 518 | seat_set_focus(seat, prior_focus); |
519 | } | 519 | } |
520 | 520 | ||
521 | static bool should_focus(struct sway_view *view) { | ||
522 | // If the view is the only one in the focused workspace, it'll get focus | ||
523 | // regardless of any no_focus criteria. | ||
524 | struct sway_container *parent = view->swayc->parent; | ||
525 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
526 | if (parent->type == C_WORKSPACE && seat_get_focus(seat) == parent) { | ||
527 | size_t num_children = parent->children->length + | ||
528 | parent->sway_workspace->floating->children->length; | ||
529 | if (num_children == 1) { | ||
530 | return true; | ||
531 | } | ||
532 | } | ||
533 | |||
534 | // Check no_focus criteria | ||
535 | list_t *criterias = criteria_for_view(view, CT_NO_FOCUS); | ||
536 | size_t len = criterias->length; | ||
537 | list_free(criterias); | ||
538 | return len == 0; | ||
539 | } | ||
540 | |||
521 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | 541 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { |
522 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { | 542 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { |
523 | return; | 543 | return; |
@@ -571,9 +591,11 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
571 | view_set_tiled(view, true); | 591 | view_set_tiled(view, true); |
572 | } | 592 | } |
573 | 593 | ||
574 | input_manager_set_focus(input_manager, cont); | 594 | if (should_focus(view)) { |
575 | if (workspace) { | 595 | input_manager_set_focus(input_manager, cont); |
576 | workspace_switch(workspace); | 596 | if (workspace) { |
597 | workspace_switch(workspace); | ||
598 | } | ||
577 | } | 599 | } |
578 | 600 | ||
579 | view_update_title(view, false); | 601 | view_update_title(view, false); |