diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-16 08:31:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-16 08:31:00 -0700 |
commit | 6a9ca6efa057999df3ce047887bd009700c3dc1b (patch) | |
tree | c380b85e10b4008218c43238e06abce8a296b8df | |
parent | Merge pull request #2282 from RyanDwyer/fix-tab-split-focus (diff) | |
parent | Focus view before running criteria when mapping (diff) | |
download | sway-6a9ca6efa057999df3ce047887bd009700c3dc1b.tar.gz sway-6a9ca6efa057999df3ce047887bd009700c3dc1b.tar.zst sway-6a9ca6efa057999df3ce047887bd009700c3dc1b.zip |
Merge pull request #2283 from RyanDwyer/no-focus
Implement no_focus command
-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 | 32 |
5 files changed, 57 insertions, 8 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..10c97518 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -504,20 +504,38 @@ void view_execute_criteria(struct sway_view *view) { | |||
504 | } | 504 | } |
505 | wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", | 505 | wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", |
506 | criteria->raw, view, criteria->cmdlist); | 506 | criteria->raw, view, criteria->cmdlist); |
507 | seat_set_focus(seat, view->swayc); | ||
507 | list_add(view->executed_criteria, criteria); | 508 | list_add(view->executed_criteria, criteria); |
508 | struct cmd_results *res = execute_command(criteria->cmdlist, NULL); | 509 | struct cmd_results *res = execute_command(criteria->cmdlist, NULL); |
509 | if (res->status != CMD_SUCCESS) { | 510 | if (res->status != CMD_SUCCESS) { |
510 | wlr_log(WLR_ERROR, "Command '%s' failed: %s", res->input, res->error); | 511 | wlr_log(WLR_ERROR, "Command '%s' failed: %s", res->input, res->error); |
511 | } | 512 | } |
512 | free_cmd_results(res); | 513 | free_cmd_results(res); |
513 | // view must be focused for commands to affect it, | ||
514 | // so always refocus in-between command lists | ||
515 | seat_set_focus(seat, view->swayc); | ||
516 | } | 514 | } |
517 | list_free(criterias); | 515 | list_free(criterias); |
518 | seat_set_focus(seat, prior_focus); | 516 | seat_set_focus(seat, prior_focus); |
519 | } | 517 | } |
520 | 518 | ||
519 | static bool should_focus(struct sway_view *view) { | ||
520 | // If the view is the only one in the focused workspace, it'll get focus | ||
521 | // regardless of any no_focus criteria. | ||
522 | struct sway_container *parent = view->swayc->parent; | ||
523 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
524 | if (parent->type == C_WORKSPACE && seat_get_focus(seat) == parent) { | ||
525 | size_t num_children = parent->children->length + | ||
526 | parent->sway_workspace->floating->children->length; | ||
527 | if (num_children == 1) { | ||
528 | return true; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | // Check no_focus criteria | ||
533 | list_t *criterias = criteria_for_view(view, CT_NO_FOCUS); | ||
534 | size_t len = criterias->length; | ||
535 | list_free(criterias); | ||
536 | return len == 0; | ||
537 | } | ||
538 | |||
521 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | 539 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { |
522 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { | 540 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { |
523 | return; | 541 | return; |
@@ -571,9 +589,11 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
571 | view_set_tiled(view, true); | 589 | view_set_tiled(view, true); |
572 | } | 590 | } |
573 | 591 | ||
574 | input_manager_set_focus(input_manager, cont); | 592 | if (should_focus(view)) { |
575 | if (workspace) { | 593 | input_manager_set_focus(input_manager, cont); |
576 | workspace_switch(workspace); | 594 | if (workspace) { |
595 | workspace_switch(workspace); | ||
596 | } | ||
577 | } | 597 | } |
578 | 598 | ||
579 | view_update_title(view, false); | 599 | view_update_title(view, false); |