aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-25 15:39:14 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-01 23:14:58 +1000
commitdc83b158e12ae33f03165cfd64a50aa7f0a52e26 (patch)
treea618595ef3b8c2eb29004cf8479742dc012a4561 /sway/tree/workspace.c
parentFix unfullscreening a floating view (diff)
downloadsway-dc83b158e12ae33f03165cfd64a50aa7f0a52e26.tar.gz
sway-dc83b158e12ae33f03165cfd64a50aa7f0a52e26.tar.zst
sway-dc83b158e12ae33f03165cfd64a50aa7f0a52e26.zip
Fix issues with sticky containers and workspaces
* Attach sticky containers to new workspaces when switching * Fire the close event *before* we start destroying the workspace to prevent a crash Because the sticky container now follows the visible workspace, this simplifies the rendering and container_at logic.
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 37d4a06a..f78ae9a5 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -387,7 +387,21 @@ bool workspace_switch(struct sway_container *workspace) {
387 strcpy(prev_workspace_name, active_ws->name); 387 strcpy(prev_workspace_name, active_ws->name);
388 } 388 }
389 389
390 // TODO: Deal with sticky containers 390 // Move sticky containers to new workspace
391 struct sway_container *next_output = workspace->parent;
392 struct sway_container *next_output_prev_ws =
393 seat_get_active_child(seat, next_output);
394 struct sway_container *floating =
395 next_output_prev_ws->sway_workspace->floating;
396 bool has_sticky = false;
397 for (int i = 0; i < floating->children->length; ++i) {
398 struct sway_container *floater = floating->children->items[i];
399 if (floater->is_sticky) {
400 has_sticky = true;
401 container_remove_child(floater);
402 container_add_child(workspace->sway_workspace->floating, floater);
403 }
404 }
391 405
392 wlr_log(L_DEBUG, "Switching to workspace %p:%s", 406 wlr_log(L_DEBUG, "Switching to workspace %p:%s",
393 workspace, workspace->name); 407 workspace, workspace->name);
@@ -395,6 +409,16 @@ bool workspace_switch(struct sway_container *workspace) {
395 if (next == NULL) { 409 if (next == NULL) {
396 next = workspace; 410 next = workspace;
397 } 411 }
412 if (has_sticky) {
413 // If there's a sticky container, we might be setting focus to the same
414 // container that's already focused, so seat_set_focus is effectively a
415 // no op. We therefore need to send the IPC event and clean up the old
416 // workspace here.
417 ipc_event_workspace(active_ws, workspace, "focus");
418 if (!workspace_is_visible(active_ws) && workspace_is_empty(active_ws)) {
419 container_destroy(active_ws);
420 }
421 }
398 seat_set_focus(seat, next); 422 seat_set_focus(seat, next);
399 struct sway_container *output = container_parent(workspace, C_OUTPUT); 423 struct sway_container *output = container_parent(workspace, C_OUTPUT);
400 arrange_output(output); 424 arrange_output(output);
@@ -418,8 +442,13 @@ bool workspace_is_empty(struct sway_container *ws) {
418 if (ws->children->length) { 442 if (ws->children->length) {
419 return false; 443 return false;
420 } 444 }
421 if (ws->sway_workspace->floating->children->length) { 445 // Sticky views are not considered to be part of this workspace
422 return false; 446 struct sway_container *floating = ws->sway_workspace->floating;
447 for (int i = 0; i < floating->children->length; ++i) {
448 struct sway_container *floater = floating->children->items[i];
449 if (!floater->is_sticky) {
450 return false;
451 }
423 } 452 }
424 return true; 453 return true;
425} 454}