aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.c28
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 @@
#include "tree/view.h"
enum criteria_type {
- CT_COMMAND = 1 << 0,
- CT_ASSIGN_OUTPUT = 1 << 1,
+ CT_COMMAND = 1 << 0,
+ CT_ASSIGN_OUTPUT = 1 << 1,
CT_ASSIGN_WORKSPACE = 1 << 2,
+ CT_NO_FOCUS = 1 << 3,
};
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[] = {
{ "input", cmd_input },
{ "mode", cmd_mode },
{ "mouse_warping", cmd_mouse_warping },
+ { "no_focus", cmd_no_focus },
{ "output", cmd_output },
{ "seat", cmd_seat },
{ "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 @@
+#define _XOPEN_SOURCE 500
+#include <string.h>
+#include "sway/commands.h"
+#include "sway/criteria.h"
+#include "list.h"
+#include "log.h"
+
+struct cmd_results *cmd_no_focus(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "no_focus", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+
+ char *err_str = NULL;
+ struct criteria *criteria = criteria_parse(argv[0], &err_str);
+ if (!criteria) {
+ error = cmd_results_new(CMD_INVALID, "no_focus", err_str);
+ free(err_str);
+ return error;
+ }
+
+ criteria->type = CT_NO_FOCUS;
+ list_add(config->criteria, criteria);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
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(
'commands/mode.c',
'commands/mouse_warping.c',
'commands/move.c',
+ 'commands/no_focus.c',
'commands/output.c',
'commands/reload.c',
'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) {
seat_set_focus(seat, prior_focus);
}
+static bool should_focus(struct sway_view *view) {
+ // If the view is the only one in the focused workspace, it'll get focus
+ // regardless of any no_focus criteria.
+ struct sway_container *parent = view->swayc->parent;
+ struct sway_seat *seat = input_manager_current_seat(input_manager);
+ if (parent->type == C_WORKSPACE && seat_get_focus(seat) == parent) {
+ size_t num_children = parent->children->length +
+ parent->sway_workspace->floating->children->length;
+ if (num_children == 1) {
+ return true;
+ }
+ }
+
+ // Check no_focus criteria
+ list_t *criterias = criteria_for_view(view, CT_NO_FOCUS);
+ size_t len = criterias->length;
+ list_free(criterias);
+ return len == 0;
+}
+
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
return;
@@ -571,9 +591,11 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
view_set_tiled(view, true);
}
- input_manager_set_focus(input_manager, cont);
- if (workspace) {
- workspace_switch(workspace);
+ if (should_focus(view)) {
+ input_manager_set_focus(input_manager, cont);
+ if (workspace) {
+ workspace_switch(workspace);
+ }
}
view_update_title(view, false);