aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 00:34:24 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 00:34:24 -0400
commite62cc0ac26b20af92ae082b110a3ab77cf0c4e60 (patch)
tree87850e69b87408cfb20292311a2ecddbef29ca52 /sway/tree/workspace.c
parentFix issues with swaybar on DRM (diff)
downloadsway-e62cc0ac26b20af92ae082b110a3ab77cf0c4e60.tar.gz
sway-e62cc0ac26b20af92ae082b110a3ab77cf0c4e60.tar.zst
sway-e62cc0ac26b20af92ae082b110a3ab77cf0c4e60.zip
Finish porting over workspace_next_name
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c107
1 files changed, 100 insertions, 7 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index ba04c55c..5800ea09 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -1,8 +1,11 @@
1#define _XOPEN_SOURCE 500 1#define _XOPEN_SOURCE 500
2#include <ctype.h>
3#include <limits.h>
2#include <stdbool.h> 4#include <stdbool.h>
3#include <stdlib.h> 5#include <stdlib.h>
4#include <stdio.h> 6#include <stdio.h>
5#include <strings.h> 7#include <strings.h>
8#include "stringop.h"
6#include "sway/tree/container.h" 9#include "sway/tree/container.h"
7#include "sway/input/input-manager.h" 10#include "sway/input/input-manager.h"
8#include "sway/input/seat.h" 11#include "sway/input/seat.h"
@@ -22,18 +25,108 @@ void next_name_map(struct sway_container *ws, void *data) {
22 ++count; 25 ++count;
23} 26}
24 27
28static bool workspace_valid_on_output(const char *output_name,
29 const char *ws_name) {
30 int i;
31 for (i = 0; i < config->workspace_outputs->length; ++i) {
32 struct workspace_output *wso = config->workspace_outputs->items[i];
33 if (strcasecmp(wso->workspace, ws_name) == 0) {
34 if (strcasecmp(wso->output, output_name) != 0) {
35 return false;
36 }
37 }
38 }
39
40 return true;
41}
42
25char *workspace_next_name(const char *output_name) { 43char *workspace_next_name(const char *output_name) {
26 wlr_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", 44 wlr_log(L_DEBUG, "Workspace: Generating new workspace name for output %s",
27 output_name); 45 output_name);
28 int count = 0; 46 int l = 1;
29 next_name_map(&root_container, &count); 47 // Scan all workspace bindings to find the next available workspace name,
30 ++count; 48 // if none are found/available then default to a number
31 int len = snprintf(NULL, 0, "%d", count); 49 struct sway_mode *mode = config->current_mode;
32 char *name = malloc(len + 1); 50
33 if (!sway_assert(name, "Failed to allocate workspace name")) { 51 // TODO: iterate over keycode bindings too
52 int order = INT_MAX;
53 char *target = NULL;
54 for (int i = 0; i < mode->keysym_bindings->length; ++i) {
55 struct sway_binding *binding = mode->keysym_bindings->items[i];
56 char *cmdlist = strdup(binding->command);
57 char *dup = cmdlist;
58 char *name = NULL;
59
60 // workspace n
61 char *cmd = argsep(&cmdlist, " ");
62 if (cmdlist) {
63 name = argsep(&cmdlist, ",;");
64 }
65
66 if (strcmp("workspace", cmd) == 0 && name) {
67 wlr_log(L_DEBUG, "Got valid workspace command for target: '%s'", name);
68 char *_target = strdup(name);
69 strip_quotes(_target);
70 while (isspace(*_target)) {
71 memmove(_target, _target+1, strlen(_target+1));
72 }
73
74 // Make sure that the command references an actual workspace
75 // not a command about workspaces
76 if (strcmp(_target, "next") == 0 ||
77 strcmp(_target, "prev") == 0 ||
78 strcmp(_target, "next_on_output") == 0 ||
79 strcmp(_target, "prev_on_output") == 0 ||
80 strcmp(_target, "number") == 0 ||
81 strcmp(_target, "back_and_forth") == 0 ||
82 strcmp(_target, "current") == 0)
83 {
84 free(_target);
85 free(dup);
86 continue;
87 }
88
89 // Make sure that the workspace doesn't already exist
90 if (workspace_by_name(_target)) {
91 free(_target);
92 free(dup);
93 continue;
94 }
95
96 // make sure that the workspace can appear on the given
97 // output
98 if (!workspace_valid_on_output(output_name, _target)) {
99 free(_target);
100 free(dup);
101 continue;
102 }
103
104 if (binding->order < order) {
105 order = binding->order;
106 free(target);
107 target = _target;
108 wlr_log(L_DEBUG, "Workspace: Found free name %s", _target);
109 }
110 }
111 free(dup);
112 }
113 if (target != NULL) {
114 return target;
115 }
116 // As a fall back, get the current number of active workspaces
117 // and return that + 1 for the next workspace's name
118 int ws_num = root_container.children->length;
119 if (ws_num >= 10) {
120 l = 2;
121 } else if (ws_num >= 100) {
122 l = 3;
123 }
124 char *name = malloc(l + 1);
125 if (!name) {
126 wlr_log(L_ERROR, "Could not allocate workspace name");
34 return NULL; 127 return NULL;
35 } 128 }
36 snprintf(name, len + 1, "%d", count); 129 sprintf(name, "%d", ws_num++);
37 return name; 130 return name;
38} 131}
39 132