summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-16 08:31:00 -0700
committerLibravatar GitHub <noreply@github.com>2018-07-16 08:31:00 -0700
commit6a9ca6efa057999df3ce047887bd009700c3dc1b (patch)
treec380b85e10b4008218c43238e06abce8a296b8df
parentMerge pull request #2282 from RyanDwyer/fix-tab-split-focus (diff)
parentFocus view before running criteria when mapping (diff)
downloadsway-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.h5
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/no_focus.c26
-rw-r--r--sway/meson.build1
-rw-r--r--sway/tree/view.c32
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
8enum criteria_type { 8enum 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
14struct criteria { 15struct 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
8struct 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
519static 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
521void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { 539void 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);