summaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/no_focus.c41
-rw-r--r--sway/config.c6
-rw-r--r--sway/criteria.c10
-rw-r--r--sway/handlers.c12
5 files changed, 67 insertions, 3 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 4d7af301..01e5e6b5 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -198,6 +198,7 @@ static struct cmd_handler handlers[] = {
198 { "move", cmd_move }, 198 { "move", cmd_move },
199 { "new_float", cmd_new_float }, 199 { "new_float", cmd_new_float },
200 { "new_window", cmd_new_window }, 200 { "new_window", cmd_new_window },
201 { "no_focus", cmd_no_focus },
201 { "output", cmd_output }, 202 { "output", cmd_output },
202 { "permit", cmd_permit }, 203 { "permit", cmd_permit },
203 { "reject", cmd_reject }, 204 { "reject", cmd_reject },
diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c
new file mode 100644
index 00000000..b3b88e5a
--- /dev/null
+++ b/sway/commands/no_focus.c
@@ -0,0 +1,41 @@
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#include "stringop.h"
8
9struct cmd_results *cmd_no_focus(int argc, char **argv) {
10 struct cmd_results *error = NULL;
11 if ((error = checkarg(argc, "no_focus", EXPECTED_EQUAL_TO, 1))) {
12 return error;
13 }
14 // add command to a criteria/command pair that is run against views when they appear.
15 char *criteria = argv[0];
16
17 struct criteria *crit = malloc(sizeof(struct criteria));
18 if (!crit) {
19 return cmd_results_new(CMD_FAILURE, "no_focus", "Unable to allocate criteria");
20 }
21 crit->crit_raw = strdup(criteria);
22 crit->tokens = create_list();
23 crit->cmdlist = NULL;
24 char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
25
26 if (err_str) {
27 error = cmd_results_new(CMD_INVALID, "no_focus", err_str);
28 free(err_str);
29 free_criteria(crit);
30 } else if (crit->tokens->length == 0) {
31 error = cmd_results_new(CMD_INVALID, "no_focus", "Found no name/value pairs in criteria");
32 free_criteria(crit);
33 } else if (list_seq_find(config->no_focus, criteria_cmp, crit) != -1) {
34 sway_log(L_DEBUG, "no_focus: Duplicate, skipping.");
35 free_criteria(crit);
36 } else {
37 sway_log(L_DEBUG, "no_focus: '%s' added", crit->crit_raw);
38 list_add(config->no_focus, crit);
39 }
40 return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
41}
diff --git a/sway/config.c b/sway/config.c
index 0014b33a..19b1882f 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -249,6 +249,11 @@ void free_config(struct sway_config *config) {
249 } 249 }
250 list_free(config->criteria); 250 list_free(config->criteria);
251 251
252 for (i = 0; config->no_focus && i < config->no_focus->length; ++i) {
253 free_criteria(config->no_focus->items[i]);
254 }
255 list_free(config->no_focus);
256
252 for (i = 0; config->input_configs && i < config->input_configs->length; ++i) { 257 for (i = 0; config->input_configs && i < config->input_configs->length; ++i) {
253 free_input_config(config->input_configs->items[i]); 258 free_input_config(config->input_configs->items[i]);
254 } 259 }
@@ -291,6 +296,7 @@ static void config_defaults(struct sway_config *config) {
291 if (!(config->workspace_outputs = create_list())) goto cleanup; 296 if (!(config->workspace_outputs = create_list())) goto cleanup;
292 if (!(config->pid_workspaces = create_list())) goto cleanup; 297 if (!(config->pid_workspaces = create_list())) goto cleanup;
293 if (!(config->criteria = create_list())) goto cleanup; 298 if (!(config->criteria = create_list())) goto cleanup;
299 if (!(config->no_focus = create_list())) goto cleanup;
294 if (!(config->input_configs = create_list())) goto cleanup; 300 if (!(config->input_configs = create_list())) goto cleanup;
295 if (!(config->output_configs = create_list())) goto cleanup; 301 if (!(config->output_configs = create_list())) goto cleanup;
296 302
diff --git a/sway/criteria.c b/sway/criteria.c
index ee6d4d1c..1ea8311e 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -359,6 +359,16 @@ void free_criteria(struct criteria *crit) {
359 free(crit); 359 free(crit);
360} 360}
361 361
362bool criteria_any(swayc_t *cont, list_t *criteria) {
363 for (int i = 0; i < criteria->length; i++) {
364 struct criteria *bc = criteria->items[i];
365 if (criteria_test(cont, bc->tokens)) {
366 return true;
367 }
368 }
369 return false;
370}
371
362list_t *criteria_for(swayc_t *cont) { 372list_t *criteria_for(swayc_t *cont) {
363 list_t *criteria = config->criteria, *matches = create_list(); 373 list_t *criteria = config->criteria, *matches = create_list();
364 for (int i = 0; i < criteria->length; i++) { 374 for (int i = 0; i < criteria->length; i++) {
diff --git a/sway/handlers.c b/sway/handlers.c
index a8de135f..5e031321 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -390,8 +390,10 @@ static bool handle_view_created(wlc_handle handle) {
390 } 390 }
391 } 391 }
392 392
393 swayc_t *prev_focus = get_focused_container(&root_container);
394
393 if (!focused || focused->type == C_OUTPUT) { 395 if (!focused || focused->type == C_OUTPUT) {
394 focused = get_focused_container(&root_container); 396 focused = prev_focus;
395 // Move focus from floating view 397 // Move focus from floating view
396 if (focused->is_floating) { 398 if (focused->is_floating) {
397 // To workspace if there are no children 399 // To workspace if there are no children
@@ -458,7 +460,11 @@ static bool handle_view_created(wlc_handle handle) {
458 460
459 if (newview) { 461 if (newview) {
460 ipc_event_window(newview, "new"); 462 ipc_event_window(newview, "new");
461 set_focused_container(newview); 463 swayc_t *workspace = swayc_parent_by_type(newview, C_WORKSPACE);
464 if ((workspace && workspace->children->length == 1)
465 || !criteria_any(newview, config->no_focus)) {
466 set_focused_container(newview);
467 }
462 wlc_view_set_mask(handle, VISIBLE); 468 wlc_view_set_mask(handle, VISIBLE);
463 swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT); 469 swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
464 arrange_windows(output, -1, -1); 470 arrange_windows(output, -1, -1);
@@ -477,7 +483,7 @@ static bool handle_view_created(wlc_handle handle) {
477 // refocus in-between command lists 483 // refocus in-between command lists
478 set_focused_container(newview); 484 set_focused_container(newview);
479 } 485 }
480 swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE); 486 workspace = swayc_parent_by_type(focused, C_WORKSPACE);
481 if (workspace && workspace->fullscreen) { 487 if (workspace && workspace->fullscreen) {
482 set_focused_container(workspace->fullscreen); 488 set_focused_container(workspace->fullscreen);
483 } 489 }