summaryrefslogtreecommitdiffstats
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c124
1 files changed, 55 insertions, 69 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 8077de2e..316f01e4 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -14,6 +14,58 @@
14#include "log.h" 14#include "log.h"
15#include "util.h" 15#include "util.h"
16 16
17static struct sway_container *get_workspace_initial_output(const char *name) {
18 struct sway_container *parent;
19 // Search for workspace<->output pair
20 int e = config->workspace_outputs->length;
21 for (int i = 0; i < config->workspace_outputs->length; ++i) {
22 struct workspace_output *wso = config->workspace_outputs->items[i];
23 if (strcasecmp(wso->workspace, name) == 0) {
24 // Find output to use if it exists
25 e = root_container.children->length;
26 for (i = 0; i < e; ++i) {
27 parent = root_container.children->items[i];
28 if (strcmp(parent->name, wso->output) == 0) {
29 return parent;
30 }
31 }
32 break;
33 }
34 }
35 // Otherwise put it on the focused output
36 struct sway_seat *seat = input_manager_current_seat(input_manager);
37 struct sway_container *focus =
38 seat_get_focus_inactive(seat, &root_container);
39 parent = focus;
40 parent = container_parent(parent, C_OUTPUT);
41 return parent;
42}
43
44struct sway_container *workspace_create(struct sway_container *output,
45 const char *name) {
46 if (output == NULL) {
47 output = get_workspace_initial_output(name);
48 }
49
50 wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name);
51 struct sway_container *workspace = container_create(C_WORKSPACE);
52
53 workspace->x = output->x;
54 workspace->y = output->y;
55 workspace->width = output->width;
56 workspace->height = output->height;
57 workspace->name = !name ? NULL : strdup(name);
58 workspace->prev_layout = L_NONE;
59 workspace->layout = container_get_default_layout(output);
60 workspace->workspace_layout = workspace->layout;
61
62 container_add_child(output, workspace);
63 container_sort_workspaces(output);
64 container_create_notify(workspace);
65
66 return workspace;
67}
68
17char *prev_workspace_name = NULL; 69char *prev_workspace_name = NULL;
18struct workspace_by_number_data { 70struct workspace_by_number_data {
19 int len; 71 int len;
@@ -197,74 +249,6 @@ struct sway_container *workspace_by_name(const char *name) {
197 } 249 }
198} 250}
199 251
200struct sway_container *workspace_create(const char *name) {
201 struct sway_container *parent;
202 // Search for workspace<->output pair
203 int i, e = config->workspace_outputs->length;
204 for (i = 0; i < e; ++i) {
205 struct workspace_output *wso = config->workspace_outputs->items[i];
206 if (strcasecmp(wso->workspace, name) == 0) {
207 // Find output to use if it exists
208 e = root_container.children->length;
209 for (i = 0; i < e; ++i) {
210 parent = root_container.children->items[i];
211 if (strcmp(parent->name, wso->output) == 0) {
212 return container_workspace_create(parent, name);
213 }
214 }
215 break;
216 }
217 }
218 // Otherwise create a new one
219 struct sway_seat *seat = input_manager_current_seat(input_manager);
220 struct sway_container *focus =
221 seat_get_focus_inactive(seat, &root_container);
222 parent = focus;
223 parent = container_parent(parent, C_OUTPUT);
224 struct sway_container *new_ws = container_workspace_create(parent, name);
225 ipc_event_workspace(NULL, new_ws, "init");
226 return new_ws;
227}
228
229struct sway_container *container_workspace_destroy(
230 struct sway_container *workspace) {
231 if (!sway_assert(workspace, "cannot destroy null workspace")) {
232 return NULL;
233 }
234
235 // Do not destroy this if it's the last workspace on this output
236 struct sway_container *output = container_parent(workspace, C_OUTPUT);
237 if (output && output->children->length == 1) {
238 return NULL;
239 }
240
241 struct sway_container *parent = workspace->parent;
242 if (workspace->children->length == 0) {
243 // destroy the WS if there are no children (TODO check for floating)
244 wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
245 ipc_event_workspace(workspace, NULL, "empty");
246 } else {
247 // Move children to a different workspace on this output
248 struct sway_container *new_workspace = NULL;
249 // TODO move floating
250 for (int i = 0; i < output->children->length; i++) {
251 if (output->children->items[i] != workspace) {
252 new_workspace = output->children->items[i];
253 break;
254 }
255 }
256
257 wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'",
258 workspace->name, new_workspace->name);
259 for (int i = 0; i < workspace->children->length; i++) {
260 container_move_to(workspace->children->items[i], new_workspace);
261 }
262 }
263
264 container_destroy(workspace);
265 return parent;
266}
267
268/** 252/**
269 * Get the previous or next workspace on the specified output. Wraps around at 253 * Get the previous or next workspace on the specified output. Wraps around at
270 * the end and beginning. If next is false, the previous workspace is returned, 254 * the end and beginning. If next is false, the previous workspace is returned,
@@ -376,7 +360,9 @@ bool workspace_switch(struct sway_container *workspace) {
376 && active_ws == workspace 360 && active_ws == workspace
377 && prev_workspace_name) { 361 && prev_workspace_name) {
378 struct sway_container *new_ws = workspace_by_name(prev_workspace_name); 362 struct sway_container *new_ws = workspace_by_name(prev_workspace_name);
379 workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); 363 workspace = new_ws ?
364 new_ws :
365 workspace_create(NULL, prev_workspace_name);
380 } 366 }
381 367
382 if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) 368 if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name)