aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-24 22:30:44 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-01 23:14:58 +1000
commit1f2e399ade77070a2d0b82856ad9a3eef96b8676 (patch)
treec469197e140051aea912cb173723c7e55ce1e410 /sway/tree/container.c
parentSend frame done to floating views (diff)
downloadsway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.tar.gz
sway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.tar.zst
sway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.zip
Implement floating
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c133
1 files changed, 122 insertions, 11 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 33d88d7f..f9a0474c 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -123,6 +123,7 @@ struct sway_container *container_create(enum sway_container_type type) {
123 c->layout = L_NONE; 123 c->layout = L_NONE;
124 c->type = type; 124 c->type = type;
125 c->alpha = 1.0f; 125 c->alpha = 1.0f;
126 c->reapable = true;
126 127
127 if (type != C_VIEW) { 128 if (type != C_VIEW) {
128 c->children = create_list(); 129 c->children = create_list();
@@ -189,14 +190,13 @@ static struct sway_container *container_workspace_destroy(
189 } 190 }
190 191
191 struct sway_container *parent = workspace->parent; 192 struct sway_container *parent = workspace->parent;
192 if (workspace->children->length == 0) { 193 if (workspace_is_empty(workspace)) {
193 // destroy the WS if there are no children (TODO check for floating) 194 // destroy the WS if there are no children
194 wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); 195 wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
195 ipc_event_workspace(workspace, NULL, "empty"); 196 ipc_event_workspace(workspace, NULL, "empty");
196 } else if (output) { 197 } else if (output) {
197 // Move children to a different workspace on this output 198 // Move children to a different workspace on this output
198 struct sway_container *new_workspace = NULL; 199 struct sway_container *new_workspace = NULL;
199 // TODO move floating
200 for (int i = 0; i < output->children->length; i++) { 200 for (int i = 0; i < output->children->length; i++) {
201 if (output->children->items[i] != workspace) { 201 if (output->children->items[i] != workspace) {
202 new_workspace = output->children->items[i]; 202 new_workspace = output->children->items[i];
@@ -209,6 +209,11 @@ static struct sway_container *container_workspace_destroy(
209 for (int i = 0; i < workspace->children->length; i++) { 209 for (int i = 0; i < workspace->children->length; i++) {
210 container_move_to(workspace->children->items[i], new_workspace); 210 container_move_to(workspace->children->items[i], new_workspace);
211 } 211 }
212 struct sway_container *floating = workspace->sway_workspace->floating;
213 for (int i = 0; i < floating->children->length; i++) {
214 container_move_to(floating->children->items[i],
215 new_workspace->sway_workspace->floating);
216 }
212 } 217 }
213 218
214 free(workspace->sway_workspace); 219 free(workspace->sway_workspace);
@@ -275,13 +280,16 @@ static void container_root_finish(struct sway_container *con) {
275} 280}
276 281
277bool container_reap_empty(struct sway_container *con) { 282bool container_reap_empty(struct sway_container *con) {
283 if (!con->reapable) {
284 return false;
285 }
278 switch (con->type) { 286 switch (con->type) {
279 case C_ROOT: 287 case C_ROOT:
280 case C_OUTPUT: 288 case C_OUTPUT:
281 // dont reap these 289 // dont reap these
282 break; 290 break;
283 case C_WORKSPACE: 291 case C_WORKSPACE:
284 if (!workspace_is_visible(con) && con->children->length == 0) { 292 if (!workspace_is_visible(con) && workspace_is_empty(con)) {
285 wlr_log(L_DEBUG, "Destroying workspace via reaper"); 293 wlr_log(L_DEBUG, "Destroying workspace via reaper");
286 container_workspace_destroy(con); 294 container_workspace_destroy(con);
287 return true; 295 return true;
@@ -436,7 +444,6 @@ struct sway_container *container_find(struct sway_container *container,
436 if (!container->children) { 444 if (!container->children) {
437 return NULL; 445 return NULL;
438 } 446 }
439 // TODO: floating windows
440 for (int i = 0; i < container->children->length; ++i) { 447 for (int i = 0; i < container->children->length; ++i) {
441 struct sway_container *child = container->children->items[i]; 448 struct sway_container *child = container->children->items[i];
442 if (test(child, data)) { 449 if (test(child, data)) {
@@ -448,6 +455,9 @@ struct sway_container *container_find(struct sway_container *container,
448 } 455 }
449 } 456 }
450 } 457 }
458 if (container->type == C_WORKSPACE) {
459 return container_find(container->sway_workspace->floating, test, data);
460 }
451 return NULL; 461 return NULL;
452} 462}
453 463
@@ -608,8 +618,6 @@ struct sway_container *container_at(struct sway_container *parent,
608 return container_at_tabbed(parent, ox, oy, surface, sx, sy); 618 return container_at_tabbed(parent, ox, oy, surface, sx, sy);
609 case L_STACKED: 619 case L_STACKED:
610 return container_at_stacked(parent, ox, oy, surface, sx, sy); 620 return container_at_stacked(parent, ox, oy, surface, sx, sy);
611 case L_FLOATING:
612 return NULL; // TODO
613 case L_NONE: 621 case L_NONE:
614 return NULL; 622 return NULL;
615 } 623 }
@@ -617,6 +625,34 @@ struct sway_container *container_at(struct sway_container *parent,
617 return NULL; 625 return NULL;
618} 626}
619 627
628struct sway_container *floating_container_at(double lx, double ly,
629 struct wlr_surface **surface, double *sx, double *sy) {
630 for (int i = 0; i < root_container.children->length; ++i) {
631 struct sway_container *output = root_container.children->items[i];
632 for (int j = 0; j < output->children->length; ++j) {
633 struct sway_container *workspace = output->children->items[j];
634 struct sway_workspace *ws = workspace->sway_workspace;
635 bool ws_is_visible = workspace_is_visible(workspace);
636 for (int k = 0; k < ws->floating->children->length; ++k) {
637 struct sway_container *floater =
638 ws->floating->children->items[k];
639 if (ws_is_visible || floater->is_sticky) {
640 struct wlr_box box = {
641 .x = floater->x,
642 .y = floater->y,
643 .width = floater->width,
644 .height = floater->height,
645 };
646 if (wlr_box_contains_point(&box, lx, ly)) {
647 return container_at(floater, lx, ly, surface, sx, sy);
648 }
649 }
650 }
651 }
652 }
653 return NULL;
654}
655
620void container_for_each_descendant_dfs(struct sway_container *container, 656void container_for_each_descendant_dfs(struct sway_container *container,
621 void (*f)(struct sway_container *container, void *data), 657 void (*f)(struct sway_container *container, void *data),
622 void *data) { 658 void *data) {
@@ -674,7 +710,7 @@ static bool find_child_func(struct sway_container *con, void *data) {
674 710
675bool container_has_child(struct sway_container *con, 711bool container_has_child(struct sway_container *con,
676 struct sway_container *child) { 712 struct sway_container *child) {
677 if (con == NULL || con->type == C_VIEW || con->children->length == 0) { 713 if (con == NULL || con->type == C_VIEW) {
678 return false; 714 return false;
679 } 715 }
680 return container_find(con, find_child_func, child); 716 return container_find(con, find_child_func, child);
@@ -806,9 +842,6 @@ static size_t get_tree_representation(struct sway_container *parent, char *buffe
806 case L_STACKED: 842 case L_STACKED:
807 lenient_strcat(buffer, "S["); 843 lenient_strcat(buffer, "S[");
808 break; 844 break;
809 case L_FLOATING:
810 lenient_strcat(buffer, "F[");
811 break;
812 case L_NONE: 845 case L_NONE:
813 lenient_strcat(buffer, "D["); 846 lenient_strcat(buffer, "D[");
814 break; 847 break;
@@ -866,3 +899,81 @@ void container_notify_subtree_changed(struct sway_container *container) {
866size_t container_titlebar_height() { 899size_t container_titlebar_height() {
867 return config->font_height + TITLEBAR_V_PADDING * 2; 900 return config->font_height + TITLEBAR_V_PADDING * 2;
868} 901}
902
903static void configure_floating_view(struct sway_view *view) {
904 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
905 int max_width = ws->width * 0.6666;
906 int max_height = ws->height * 0.6666;
907 int width =
908 view->natural_width > max_width ? max_width : view->natural_width;
909 int height =
910 view->natural_height > max_height ? max_height : view->natural_height;
911 struct sway_container *output = ws->parent;
912 int lx = output->x + (ws->width - width) / 2;
913 int ly = output->y + (ws->height - height) / 2;
914
915 view->border_left = view->border_right = view->border_bottom = true;
916 view_set_maximized(view, false);
917 view_configure(view, lx, ly, width, height);
918}
919
920void container_set_floating(struct sway_container *container, bool enable) {
921 if (container->is_floating == enable) {
922 return;
923 }
924
925 struct sway_container *workspace = container_parent(container, C_WORKSPACE);
926 struct sway_seat *seat = input_manager_current_seat(input_manager);
927 container_damage_whole(container);
928
929 if (enable) {
930 container_remove_child(container);
931 container_add_child(workspace->sway_workspace->floating, container);
932 container->is_floating = true;
933 if (container->type == C_VIEW) {
934 configure_floating_view(container->sway_view);
935 }
936 seat_set_focus(seat, seat_get_focus_inactive(seat, container));
937 container_reap_empty_recursive(workspace);
938 } else {
939 // Returning to tiled
940 container_remove_child(container);
941 container_add_child(workspace, container);
942 container->width = container->parent->width;
943 container->height = container->parent->height;
944 if (container->type == C_VIEW) {
945 view_set_maximized(container->sway_view, true);
946 }
947 container->is_floating = false;
948 container->is_sticky = false;
949 container_reap_empty_recursive(workspace->sway_workspace->floating);
950 }
951 arrange_workspace(workspace);
952 container_damage_whole(container);
953}
954
955void container_set_geometry_from_view(struct sway_container *container) {
956 if (!sway_assert(container->type == C_VIEW, "Expected a view")) {
957 return;
958 }
959 if (!sway_assert(container->is_floating, "Expected a floating view")) {
960 return;
961 }
962 struct sway_view *view = container->sway_view;
963 size_t border_width = view->border_thickness * (view->border != B_NONE);
964 size_t top =
965 view->border == B_NORMAL ? container_titlebar_height() : border_width;
966
967 container->x = view->x - border_width;
968 container->y = view->y - top;
969 container->width = view->width + border_width * 2;
970 container->height = top + view->height + border_width;
971}
972
973bool container_self_or_parent_floating(struct sway_container *container) {
974 while (container->parent->type != C_WORKSPACE
975 && container->parent->parent->type != C_WORKSPACE) {
976 container = container->parent;
977 }
978 return container->is_floating;
979}