aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sway/desktop/output.c7
-rw-r--r--sway/tree/container.c45
-rw-r--r--sway/tree/workspace.c35
3 files changed, 54 insertions, 33 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index c0e368d0..fb80fd87 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -832,12 +832,13 @@ static void render_floating(struct sway_output *soutput,
for (int j = 0; j < output->children->length; ++j) {
struct sway_container *workspace = output->children->items[j];
struct sway_workspace *ws = workspace->sway_workspace;
- bool ws_is_visible = workspace_is_visible(workspace);
+ if (!workspace_is_visible(workspace)) {
+ continue;
+ }
for (int k = 0; k < ws->floating->children->length; ++k) {
struct sway_container *floater =
ws->floating->children->items[k];
- if ((ws_is_visible || floater->is_sticky)
- && floater_intersects_output(floater, soutput->swayc)) {
+ if (floater_intersects_output(floater, soutput->swayc)) {
render_floating_container(soutput, damage, floater);
}
}
diff --git a/sway/tree/container.c b/sway/tree/container.c
index fd7ee2c3..532722e8 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -64,16 +64,6 @@ void container_create_notify(struct sway_container *container) {
}
}
-static void container_close_notify(struct sway_container *container) {
- if (container == NULL) {
- return;
- }
- // TODO send ipc event type based on the container type
- if (container->type == C_VIEW || container->type == C_WORKSPACE) {
- ipc_event_window(container, "close");
- }
-}
-
static void container_update_textures_recursive(struct sway_container *con) {
container_update_title_textures(con);
@@ -143,7 +133,6 @@ static void _container_destroy(struct sway_container *cont) {
}
wl_signal_emit(&cont->events.destroy, cont);
- container_close_notify(cont);
struct sway_container *parent = cont->parent;
if (cont->children != NULL && cont->children->length) {
@@ -151,6 +140,7 @@ static void _container_destroy(struct sway_container *cont) {
// container_remove_child, which removes child from this container
while (cont->children != NULL && cont->children->length > 0) {
struct sway_container *child = cont->children->items[0];
+ ipc_event_window(child, "close");
container_remove_child(child);
_container_destroy(child);
}
@@ -188,12 +178,11 @@ static struct sway_container *container_workspace_destroy(
return NULL;
}
+ wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
+ ipc_event_window(workspace, "close");
+
struct sway_container *parent = workspace->parent;
- if (workspace_is_empty(workspace)) {
- // destroy the WS if there are no children
- wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
- ipc_event_workspace(workspace, NULL, "empty");
- } else if (output) {
+ if (!workspace_is_empty(workspace) && output) {
// Move children to a different workspace on this output
struct sway_container *new_workspace = NULL;
for (int i = 0; i < output->children->length; i++) {
@@ -357,10 +346,12 @@ struct sway_container *container_destroy(struct sway_container *con) {
if (con->children->length) {
for (int i = 0; i < con->children->length; ++i) {
struct sway_container *child = con->children->items[0];
+ ipc_event_window(child, "close");
container_remove_child(child);
container_add_child(parent, child);
}
}
+ ipc_event_window(con, "close");
_container_destroy(con);
break;
case C_VIEW:
@@ -635,20 +626,20 @@ struct sway_container *floating_container_at(double lx, double ly,
for (int j = 0; j < output->children->length; ++j) {
struct sway_container *workspace = output->children->items[j];
struct sway_workspace *ws = workspace->sway_workspace;
- bool ws_is_visible = workspace_is_visible(workspace);
+ if (!workspace_is_visible(workspace)) {
+ continue;
+ }
for (int k = 0; k < ws->floating->children->length; ++k) {
struct sway_container *floater =
ws->floating->children->items[k];
- if (ws_is_visible || floater->is_sticky) {
- struct wlr_box box = {
- .x = floater->x,
- .y = floater->y,
- .width = floater->width,
- .height = floater->height,
- };
- if (wlr_box_contains_point(&box, lx, ly)) {
- return container_at(floater, lx, ly, surface, sx, sy);
- }
+ struct wlr_box box = {
+ .x = floater->x,
+ .y = floater->y,
+ .width = floater->width,
+ .height = floater->height,
+ };
+ if (wlr_box_contains_point(&box, lx, ly)) {
+ return container_at(floater, lx, ly, surface, sx, sy);
}
}
}
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) {
strcpy(prev_workspace_name, active_ws->name);
}
- // TODO: Deal with sticky containers
+ // Move sticky containers to new workspace
+ struct sway_container *next_output = workspace->parent;
+ struct sway_container *next_output_prev_ws =
+ seat_get_active_child(seat, next_output);
+ struct sway_container *floating =
+ next_output_prev_ws->sway_workspace->floating;
+ bool has_sticky = false;
+ for (int i = 0; i < floating->children->length; ++i) {
+ struct sway_container *floater = floating->children->items[i];
+ if (floater->is_sticky) {
+ has_sticky = true;
+ container_remove_child(floater);
+ container_add_child(workspace->sway_workspace->floating, floater);
+ }
+ }
wlr_log(L_DEBUG, "Switching to workspace %p:%s",
workspace, workspace->name);
@@ -395,6 +409,16 @@ bool workspace_switch(struct sway_container *workspace) {
if (next == NULL) {
next = workspace;
}
+ if (has_sticky) {
+ // If there's a sticky container, we might be setting focus to the same
+ // container that's already focused, so seat_set_focus is effectively a
+ // no op. We therefore need to send the IPC event and clean up the old
+ // workspace here.
+ ipc_event_workspace(active_ws, workspace, "focus");
+ if (!workspace_is_visible(active_ws) && workspace_is_empty(active_ws)) {
+ container_destroy(active_ws);
+ }
+ }
seat_set_focus(seat, next);
struct sway_container *output = container_parent(workspace, C_OUTPUT);
arrange_output(output);
@@ -418,8 +442,13 @@ bool workspace_is_empty(struct sway_container *ws) {
if (ws->children->length) {
return false;
}
- if (ws->sway_workspace->floating->children->length) {
- return false;
+ // Sticky views are not considered to be part of this workspace
+ struct sway_container *floating = ws->sway_workspace->floating;
+ for (int i = 0; i < floating->children->length; ++i) {
+ struct sway_container *floater = floating->children->items[i];
+ if (!floater->is_sticky) {
+ return false;
+ }
}
return true;
}