aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c92
1 files changed, 41 insertions, 51 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index ba04c55c..861fda4d 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -3,10 +3,10 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <stdio.h> 4#include <stdio.h>
5#include <strings.h> 5#include <strings.h>
6#include "sway/tree/container.h" 6#include "sway/container.h"
7#include "sway/input/input-manager.h" 7#include "sway/input/input-manager.h"
8#include "sway/input/seat.h" 8#include "sway/input/seat.h"
9#include "sway/tree/workspace.h" 9#include "sway/workspace.h"
10#include "log.h" 10#include "log.h"
11#include "util.h" 11#include "util.h"
12 12
@@ -17,7 +17,7 @@ struct workspace_by_number_data {
17 const char *name; 17 const char *name;
18}; 18};
19 19
20void next_name_map(struct sway_container *ws, void *data) { 20void next_name_map(swayc_t *ws, void *data) {
21 int *count = data; 21 int *count = data;
22 ++count; 22 ++count;
23} 23}
@@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) {
37 return name; 37 return name;
38} 38}
39 39
40static bool _workspace_by_number(struct sway_container *view, void *data) { 40static bool _workspace_by_number(swayc_t *view, void *data) {
41 if (view->type != C_WORKSPACE) { 41 if (view->type != C_WORKSPACE) {
42 return false; 42 return false;
43 } 43 }
@@ -46,28 +46,27 @@ static bool _workspace_by_number(struct sway_container *view, void *data) {
46 return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; 46 return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0;
47} 47}
48 48
49struct sway_container *workspace_by_number(const char* name) { 49swayc_t *workspace_by_number(const char* name) {
50 struct workspace_by_number_data wbnd = {0, "1234567890", name}; 50 struct workspace_by_number_data wbnd = {0, "1234567890", name};
51 wbnd.len = strspn(name, wbnd.cset); 51 wbnd.len = strspn(name, wbnd.cset);
52 if (wbnd.len <= 0) { 52 if (wbnd.len <= 0) {
53 return NULL; 53 return NULL;
54 } 54 }
55 return container_find(&root_container, 55 return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd);
56 _workspace_by_number, (void *) &wbnd);
57} 56}
58 57
59static bool _workspace_by_name(struct sway_container *view, void *data) { 58static bool _workspace_by_name(swayc_t *view, void *data) {
60 return (view->type == C_WORKSPACE) && 59 return (view->type == C_WORKSPACE) &&
61 (strcasecmp(view->name, (char *) data) == 0); 60 (strcasecmp(view->name, (char *) data) == 0);
62} 61}
63 62
64struct sway_container *workspace_by_name(const char *name) { 63swayc_t *workspace_by_name(const char *name) {
65 struct sway_seat *seat = input_manager_current_seat(input_manager); 64 struct sway_seat *seat = input_manager_current_seat(input_manager);
66 struct sway_container *current_workspace = NULL, *current_output = NULL; 65 swayc_t *current_workspace = NULL, *current_output = NULL;
67 struct sway_container *focus = sway_seat_get_focus(seat); 66 swayc_t *focus = sway_seat_get_focus(seat);
68 if (focus) { 67 if (focus) {
69 current_workspace = container_parent(focus, C_WORKSPACE); 68 current_workspace = swayc_parent_by_type(focus, C_WORKSPACE);
70 current_output = container_parent(focus, C_OUTPUT); 69 current_output = swayc_parent_by_type(focus, C_OUTPUT);
71 } 70 }
72 if (strcmp(name, "prev") == 0) { 71 if (strcmp(name, "prev") == 0) {
73 return workspace_prev(current_workspace); 72 return workspace_prev(current_workspace);
@@ -80,13 +79,12 @@ struct sway_container *workspace_by_name(const char *name) {
80 } else if (strcmp(name, "current") == 0) { 79 } else if (strcmp(name, "current") == 0) {
81 return current_workspace; 80 return current_workspace;
82 } else { 81 } else {
83 return container_find(&root_container, _workspace_by_name, 82 return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
84 (void *)name);
85 } 83 }
86} 84}
87 85
88struct sway_container *workspace_create(const char *name) { 86swayc_t *workspace_create(const char *name) {
89 struct sway_container *parent; 87 swayc_t *parent;
90 // Search for workspace<->output pair 88 // Search for workspace<->output pair
91 int i, e = config->workspace_outputs->length; 89 int i, e = config->workspace_outputs->length;
92 for (i = 0; i < e; ++i) { 90 for (i = 0; i < e; ++i) {
@@ -97,7 +95,7 @@ struct sway_container *workspace_create(const char *name) {
97 for (i = 0; i < e; ++i) { 95 for (i = 0; i < e; ++i) {
98 parent = root_container.children->items[i]; 96 parent = root_container.children->items[i];
99 if (strcmp(parent->name, wso->output) == 0) { 97 if (strcmp(parent->name, wso->output) == 0) {
100 return container_workspace_create(parent, name); 98 return new_workspace(parent, name);
101 } 99 }
102 } 100 }
103 break; 101 break;
@@ -105,11 +103,10 @@ struct sway_container *workspace_create(const char *name) {
105 } 103 }
106 // Otherwise create a new one 104 // Otherwise create a new one
107 struct sway_seat *seat = input_manager_current_seat(input_manager); 105 struct sway_seat *seat = input_manager_current_seat(input_manager);
108 struct sway_container *focus = 106 swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
109 sway_seat_get_focus_inactive(seat, &root_container);
110 parent = focus; 107 parent = focus;
111 parent = container_parent(parent, C_OUTPUT); 108 parent = swayc_parent_by_type(parent, C_OUTPUT);
112 return container_workspace_create(parent, name); 109 return new_workspace(parent, name);
113} 110}
114 111
115/** 112/**
@@ -117,18 +114,17 @@ struct sway_container *workspace_create(const char *name) {
117 * the end and beginning. If next is false, the previous workspace is returned, 114 * the end and beginning. If next is false, the previous workspace is returned,
118 * otherwise the next one is returned. 115 * otherwise the next one is returned.
119 */ 116 */
120struct sway_container *workspace_output_prev_next_impl( 117swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) {
121 struct sway_container *output, bool next) {
122 if (!sway_assert(output->type == C_OUTPUT, 118 if (!sway_assert(output->type == C_OUTPUT,
123 "Argument must be an output, is %d", output->type)) { 119 "Argument must be an output, is %d", output->type)) {
124 return NULL; 120 return NULL;
125 } 121 }
126 122
127 struct sway_seat *seat = input_manager_current_seat(input_manager); 123 struct sway_seat *seat = input_manager_current_seat(input_manager);
128 struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); 124 swayc_t *focus = sway_seat_get_focus_inactive(seat, output);
129 struct sway_container *workspace = (focus->type == C_WORKSPACE ? 125 swayc_t *workspace = (focus->type == C_WORKSPACE ?
130 focus : 126 focus :
131 container_parent(focus, C_WORKSPACE)); 127 swayc_parent_by_type(focus, C_WORKSPACE));
132 128
133 int i; 129 int i;
134 for (i = 0; i < output->children->length; i++) { 130 for (i = 0; i < output->children->length; i++) {
@@ -138,8 +134,7 @@ struct sway_container *workspace_output_prev_next_impl(
138 } 134 }
139 } 135 }
140 136
141 // Doesn't happen, at worst the for loop returns the previously active 137 // Doesn't happen, at worst the for loop returns the previously active workspace
142 // workspace
143 return NULL; 138 return NULL;
144} 139}
145 140
@@ -149,14 +144,13 @@ struct sway_container *workspace_output_prev_next_impl(
149 * next is false, the previous workspace is returned, otherwise the next one is 144 * next is false, the previous workspace is returned, otherwise the next one is
150 * returned. 145 * returned.
151 */ 146 */
152struct sway_container *workspace_prev_next_impl( 147swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) {
153 struct sway_container *workspace, bool next) {
154 if (!sway_assert(workspace->type == C_WORKSPACE, 148 if (!sway_assert(workspace->type == C_WORKSPACE,
155 "Argument must be a workspace, is %d", workspace->type)) { 149 "Argument must be a workspace, is %d", workspace->type)) {
156 return NULL; 150 return NULL;
157 } 151 }
158 152
159 struct sway_container *current_output = workspace->parent; 153 swayc_t *current_output = workspace->parent;
160 int offset = next ? 1 : -1; 154 int offset = next ? 1 : -1;
161 int start = next ? 0 : 1; 155 int start = next ? 0 : 1;
162 int end; 156 int end;
@@ -172,57 +166,54 @@ struct sway_container *workspace_prev_next_impl(
172 } 166 }
173 } 167 }
174 168
175 // Given workspace is the first/last on the output, jump to the 169 // Given workspace is the first/last on the output, jump to the previous/next output
176 // previous/next output
177 int num_outputs = root_container.children->length; 170 int num_outputs = root_container.children->length;
178 for (i = 0; i < num_outputs; i++) { 171 for (i = 0; i < num_outputs; i++) {
179 if (root_container.children->items[i] == current_output) { 172 if (root_container.children->items[i] == current_output) {
180 struct sway_container *next_output = root_container.children->items[ 173 swayc_t *next_output = root_container.children->items[
181 wrap(i + offset, num_outputs)]; 174 wrap(i + offset, num_outputs)];
182 return workspace_output_prev_next_impl(next_output, next); 175 return workspace_output_prev_next_impl(next_output, next);
183 } 176 }
184 } 177 }
185 178
186 // Doesn't happen, at worst the for loop returns the previously active 179 // Doesn't happen, at worst the for loop returns the previously active workspace on the active output
187 // workspace on the active output
188 return NULL; 180 return NULL;
189} 181}
190 182
191struct sway_container *workspace_output_next(struct sway_container *current) { 183swayc_t *workspace_output_next(swayc_t *current) {
192 return workspace_output_prev_next_impl(current, true); 184 return workspace_output_prev_next_impl(current, true);
193} 185}
194 186
195struct sway_container *workspace_next(struct sway_container *current) { 187swayc_t *workspace_next(swayc_t *current) {
196 return workspace_prev_next_impl(current, true); 188 return workspace_prev_next_impl(current, true);
197} 189}
198 190
199struct sway_container *workspace_output_prev(struct sway_container *current) { 191swayc_t *workspace_output_prev(swayc_t *current) {
200 return workspace_output_prev_next_impl(current, false); 192 return workspace_output_prev_next_impl(current, false);
201} 193}
202 194
203struct sway_container *workspace_prev(struct sway_container *current) { 195swayc_t *workspace_prev(swayc_t *current) {
204 return workspace_prev_next_impl(current, false); 196 return workspace_prev_next_impl(current, false);
205} 197}
206 198
207bool workspace_switch(struct sway_container *workspace) { 199bool workspace_switch(swayc_t *workspace) {
208 if (!workspace) { 200 if (!workspace) {
209 return false; 201 return false;
210 } 202 }
211 struct sway_seat *seat = input_manager_current_seat(input_manager); 203 struct sway_seat *seat = input_manager_current_seat(input_manager);
212 struct sway_container *focus = 204 swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
213 sway_seat_get_focus_inactive(seat, &root_container);
214 if (!seat || !focus) { 205 if (!seat || !focus) {
215 return false; 206 return false;
216 } 207 }
217 struct sway_container *active_ws = focus; 208 swayc_t *active_ws = focus;
218 if (active_ws->type != C_WORKSPACE) { 209 if (active_ws->type != C_WORKSPACE) {
219 container_parent(focus, C_WORKSPACE); 210 swayc_parent_by_type(focus, C_WORKSPACE);
220 } 211 }
221 212
222 if (config->auto_back_and_forth 213 if (config->auto_back_and_forth
223 && active_ws == workspace 214 && active_ws == workspace
224 && prev_workspace_name) { 215 && prev_workspace_name) {
225 struct sway_container *new_ws = workspace_by_name(prev_workspace_name); 216 swayc_t *new_ws = workspace_by_name(prev_workspace_name);
226 workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); 217 workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
227 } 218 }
228 219
@@ -239,14 +230,13 @@ bool workspace_switch(struct sway_container *workspace) {
239 230
240 // TODO: Deal with sticky containers 231 // TODO: Deal with sticky containers
241 232
242 wlr_log(L_DEBUG, "Switching to workspace %p:%s", 233 wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
243 workspace, workspace->name); 234 swayc_t *next = sway_seat_get_focus_inactive(seat, workspace);
244 struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace);
245 if (next == NULL) { 235 if (next == NULL) {
246 next = workspace; 236 next = workspace;
247 } 237 }
248 sway_seat_set_focus(seat, next); 238 sway_seat_set_focus(seat, next);
249 struct sway_container *output = container_parent(workspace, C_OUTPUT); 239 swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
250 arrange_windows(output, -1, -1); 240 arrange_windows(output, -1, -1);
251 return true; 241 return true;
252} 242}