diff options
-rw-r--r-- | sway/desktop/output.c | 7 | ||||
-rw-r--r-- | sway/tree/container.c | 45 | ||||
-rw-r--r-- | sway/tree/workspace.c | 35 |
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, | |||
832 | for (int j = 0; j < output->children->length; ++j) { | 832 | for (int j = 0; j < output->children->length; ++j) { |
833 | struct sway_container *workspace = output->children->items[j]; | 833 | struct sway_container *workspace = output->children->items[j]; |
834 | struct sway_workspace *ws = workspace->sway_workspace; | 834 | struct sway_workspace *ws = workspace->sway_workspace; |
835 | bool ws_is_visible = workspace_is_visible(workspace); | 835 | if (!workspace_is_visible(workspace)) { |
836 | continue; | ||
837 | } | ||
836 | for (int k = 0; k < ws->floating->children->length; ++k) { | 838 | for (int k = 0; k < ws->floating->children->length; ++k) { |
837 | struct sway_container *floater = | 839 | struct sway_container *floater = |
838 | ws->floating->children->items[k]; | 840 | ws->floating->children->items[k]; |
839 | if ((ws_is_visible || floater->is_sticky) | 841 | if (floater_intersects_output(floater, soutput->swayc)) { |
840 | && floater_intersects_output(floater, soutput->swayc)) { | ||
841 | render_floating_container(soutput, damage, floater); | 842 | render_floating_container(soutput, damage, floater); |
842 | } | 843 | } |
843 | } | 844 | } |
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) { | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | static void container_close_notify(struct sway_container *container) { | ||
68 | if (container == NULL) { | ||
69 | return; | ||
70 | } | ||
71 | // TODO send ipc event type based on the container type | ||
72 | if (container->type == C_VIEW || container->type == C_WORKSPACE) { | ||
73 | ipc_event_window(container, "close"); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | static void container_update_textures_recursive(struct sway_container *con) { | 67 | static void container_update_textures_recursive(struct sway_container *con) { |
78 | container_update_title_textures(con); | 68 | container_update_title_textures(con); |
79 | 69 | ||
@@ -143,7 +133,6 @@ static void _container_destroy(struct sway_container *cont) { | |||
143 | } | 133 | } |
144 | 134 | ||
145 | wl_signal_emit(&cont->events.destroy, cont); | 135 | wl_signal_emit(&cont->events.destroy, cont); |
146 | container_close_notify(cont); | ||
147 | 136 | ||
148 | struct sway_container *parent = cont->parent; | 137 | struct sway_container *parent = cont->parent; |
149 | if (cont->children != NULL && cont->children->length) { | 138 | if (cont->children != NULL && cont->children->length) { |
@@ -151,6 +140,7 @@ static void _container_destroy(struct sway_container *cont) { | |||
151 | // container_remove_child, which removes child from this container | 140 | // container_remove_child, which removes child from this container |
152 | while (cont->children != NULL && cont->children->length > 0) { | 141 | while (cont->children != NULL && cont->children->length > 0) { |
153 | struct sway_container *child = cont->children->items[0]; | 142 | struct sway_container *child = cont->children->items[0]; |
143 | ipc_event_window(child, "close"); | ||
154 | container_remove_child(child); | 144 | container_remove_child(child); |
155 | _container_destroy(child); | 145 | _container_destroy(child); |
156 | } | 146 | } |
@@ -188,12 +178,11 @@ static struct sway_container *container_workspace_destroy( | |||
188 | return NULL; | 178 | return NULL; |
189 | } | 179 | } |
190 | 180 | ||
181 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
182 | ipc_event_window(workspace, "close"); | ||
183 | |||
191 | struct sway_container *parent = workspace->parent; | 184 | struct sway_container *parent = workspace->parent; |
192 | if (workspace_is_empty(workspace)) { | 185 | if (!workspace_is_empty(workspace) && output) { |
193 | // destroy the WS if there are no children | ||
194 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
195 | ipc_event_workspace(workspace, NULL, "empty"); | ||
196 | } else if (output) { | ||
197 | // Move children to a different workspace on this output | 186 | // Move children to a different workspace on this output |
198 | struct sway_container *new_workspace = NULL; | 187 | struct sway_container *new_workspace = NULL; |
199 | for (int i = 0; i < output->children->length; i++) { | 188 | for (int i = 0; i < output->children->length; i++) { |
@@ -357,10 +346,12 @@ struct sway_container *container_destroy(struct sway_container *con) { | |||
357 | if (con->children->length) { | 346 | if (con->children->length) { |
358 | for (int i = 0; i < con->children->length; ++i) { | 347 | for (int i = 0; i < con->children->length; ++i) { |
359 | struct sway_container *child = con->children->items[0]; | 348 | struct sway_container *child = con->children->items[0]; |
349 | ipc_event_window(child, "close"); | ||
360 | container_remove_child(child); | 350 | container_remove_child(child); |
361 | container_add_child(parent, child); | 351 | container_add_child(parent, child); |
362 | } | 352 | } |
363 | } | 353 | } |
354 | ipc_event_window(con, "close"); | ||
364 | _container_destroy(con); | 355 | _container_destroy(con); |
365 | break; | 356 | break; |
366 | case C_VIEW: | 357 | case C_VIEW: |
@@ -635,20 +626,20 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
635 | for (int j = 0; j < output->children->length; ++j) { | 626 | for (int j = 0; j < output->children->length; ++j) { |
636 | struct sway_container *workspace = output->children->items[j]; | 627 | struct sway_container *workspace = output->children->items[j]; |
637 | struct sway_workspace *ws = workspace->sway_workspace; | 628 | struct sway_workspace *ws = workspace->sway_workspace; |
638 | bool ws_is_visible = workspace_is_visible(workspace); | 629 | if (!workspace_is_visible(workspace)) { |
630 | continue; | ||
631 | } | ||
639 | for (int k = 0; k < ws->floating->children->length; ++k) { | 632 | for (int k = 0; k < ws->floating->children->length; ++k) { |
640 | struct sway_container *floater = | 633 | struct sway_container *floater = |
641 | ws->floating->children->items[k]; | 634 | ws->floating->children->items[k]; |
642 | if (ws_is_visible || floater->is_sticky) { | 635 | struct wlr_box box = { |
643 | struct wlr_box box = { | 636 | .x = floater->x, |
644 | .x = floater->x, | 637 | .y = floater->y, |
645 | .y = floater->y, | 638 | .width = floater->width, |
646 | .width = floater->width, | 639 | .height = floater->height, |
647 | .height = floater->height, | 640 | }; |
648 | }; | 641 | if (wlr_box_contains_point(&box, lx, ly)) { |
649 | if (wlr_box_contains_point(&box, lx, ly)) { | 642 | return container_at(floater, lx, ly, surface, sx, sy); |
650 | return container_at(floater, lx, ly, surface, sx, sy); | ||
651 | } | ||
652 | } | 643 | } |
653 | } | 644 | } |
654 | } | 645 | } |
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 | } |