summaryrefslogtreecommitdiffstats
path: root/sway/tree/arrange.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/arrange.c')
-rw-r--r--sway/tree/arrange.c197
1 files changed, 90 insertions, 107 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 8d67116a..92f20fcc 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -13,27 +13,18 @@
13#include "list.h" 13#include "list.h"
14#include "log.h" 14#include "log.h"
15 15
16static void apply_horiz_layout(struct sway_container *parent) { 16static void apply_horiz_layout(list_t *children, struct wlr_box *parent) {
17 size_t num_children = parent->children->length; 17 if (!children->length) {
18 if (!num_children) {
19 return; 18 return;
20 } 19 }
21 size_t parent_offset = 0;
22 if (parent->parent->layout == L_TABBED) {
23 parent_offset = container_titlebar_height();
24 } else if (parent->parent->layout == L_STACKED) {
25 parent_offset = container_titlebar_height() *
26 parent->parent->children->length;
27 }
28 size_t parent_height = parent->height - parent_offset;
29 20
30 // Calculate total width of children 21 // Calculate total width of children
31 double total_width = 0; 22 double total_width = 0;
32 for (size_t i = 0; i < num_children; ++i) { 23 for (int i = 0; i < children->length; ++i) {
33 struct sway_container *child = parent->children->items[i]; 24 struct sway_container *child = children->items[i];
34 if (child->width <= 0) { 25 if (child->width <= 0) {
35 if (num_children > 1) { 26 if (children->length > 1) {
36 child->width = parent->width / (num_children - 1); 27 child->width = parent->width / (children->length - 1);
37 } else { 28 } else {
38 child->width = parent->width; 29 child->width = parent->width;
39 } 30 }
@@ -46,63 +37,48 @@ static void apply_horiz_layout(struct sway_container *parent) {
46 // Resize windows 37 // Resize windows
47 wlr_log(WLR_DEBUG, "Arranging %p horizontally", parent); 38 wlr_log(WLR_DEBUG, "Arranging %p horizontally", parent);
48 double child_x = parent->x; 39 double child_x = parent->x;
49 for (size_t i = 0; i < num_children; ++i) { 40 for (int i = 0; i < children->length; ++i) {
50 struct sway_container *child = parent->children->items[i]; 41 struct sway_container *child = children->items[i];
51 wlr_log(WLR_DEBUG,
52 "Calculating arrangement for %p:%d (will scale %f by %f)",
53 child, child->type, child->width, scale);
54 child->x = child_x; 42 child->x = child_x;
55 child->y = parent->y + parent_offset; 43 child->y = parent->y;
56 child->width = floor(child->width * scale); 44 child->width = floor(child->width * scale);
57 child->height = parent_height; 45 child->height = parent->height;
58 child_x += child->width; 46 child_x += child->width;
59 47
60 // Make last child use remaining width of parent 48 // Make last child use remaining width of parent
61 if (i == num_children - 1) { 49 if (i == children->length - 1) {
62 child->width = parent->x + parent->width - child->x; 50 child->width = parent->x + parent->width - child->x;
63 } 51 }
64 container_add_gaps(child); 52 container_add_gaps(child);
65 } 53 }
66} 54}
67 55
68static void apply_vert_layout(struct sway_container *parent) { 56static void apply_vert_layout(list_t *children, struct wlr_box *parent) {
69 size_t num_children = parent->children->length; 57 if (!children->length) {
70 if (!num_children) {
71 return; 58 return;
72 } 59 }
73 size_t parent_offset = 0;
74 if (parent->parent->layout == L_TABBED) {
75 parent_offset = container_titlebar_height();
76 } else if (parent->parent->layout == L_STACKED) {
77 parent_offset =
78 container_titlebar_height() * parent->parent->children->length;
79 }
80 size_t parent_height = parent->height + parent_offset;
81 60
82 // Calculate total height of children 61 // Calculate total height of children
83 double total_height = 0; 62 double total_height = 0;
84 for (size_t i = 0; i < num_children; ++i) { 63 for (int i = 0; i < children->length; ++i) {
85 struct sway_container *child = parent->children->items[i]; 64 struct sway_container *child = children->items[i];
86 if (child->height <= 0) { 65 if (child->height <= 0) {
87 if (num_children > 1) { 66 if (children->length > 1) {
88 child->height = parent_height / (num_children - 1); 67 child->height = parent->height / (children->length - 1);
89 } else { 68 } else {
90 child->height = parent_height; 69 child->height = parent->height;
91 } 70 }
92 } 71 }
93 container_remove_gaps(child); 72 container_remove_gaps(child);
94 total_height += child->height; 73 total_height += child->height;
95 } 74 }
96 double scale = parent_height / total_height; 75 double scale = parent->height / total_height;
97 76
98 // Resize 77 // Resize
99 wlr_log(WLR_DEBUG, "Arranging %p vertically", parent); 78 wlr_log(WLR_DEBUG, "Arranging %p vertically", parent);
100 double child_y = parent->y + parent_offset; 79 double child_y = parent->y;
101 for (size_t i = 0; i < num_children; ++i) { 80 for (int i = 0; i < children->length; ++i) {
102 struct sway_container *child = parent->children->items[i]; 81 struct sway_container *child = children->items[i];
103 wlr_log(WLR_DEBUG,
104 "Calculating arrangement for %p:%d (will scale %f by %f)",
105 child, child->type, child->height, scale);
106 child->x = parent->x; 82 child->x = parent->x;
107 child->y = child_y; 83 child->y = child_y;
108 child->width = parent->width; 84 child->width = parent->width;
@@ -110,28 +86,21 @@ static void apply_vert_layout(struct sway_container *parent) {
110 child_y += child->height; 86 child_y += child->height;
111 87
112 // Make last child use remaining height of parent 88 // Make last child use remaining height of parent
113 if (i == num_children - 1) { 89 if (i == children->length - 1) {
114 child->height = 90 child->height = parent->y + parent->height - child->y;
115 parent->y + parent_offset + parent_height - child->y;
116 } 91 }
117 container_add_gaps(child); 92 container_add_gaps(child);
118 } 93 }
119} 94}
120 95
121static void apply_tabbed_or_stacked_layout(struct sway_container *parent) { 96static void apply_tabbed_layout(list_t *children, struct wlr_box *parent) {
122 if (!parent->children->length) { 97 if (!children->length) {
123 return; 98 return;
124 } 99 }
125 size_t parent_offset = 0; 100 size_t parent_offset = container_titlebar_height();
126 if (parent->parent->layout == L_TABBED) {
127 parent_offset = container_titlebar_height();
128 } else if (parent->parent->layout == L_STACKED) {
129 parent_offset =
130 container_titlebar_height() * parent->parent->children->length;
131 }
132 size_t parent_height = parent->height - parent_offset; 101 size_t parent_height = parent->height - parent_offset;
133 for (int i = 0; i < parent->children->length; ++i) { 102 for (int i = 0; i < children->length; ++i) {
134 struct sway_container *child = parent->children->items[i]; 103 struct sway_container *child = children->items[i];
135 container_remove_gaps(child); 104 container_remove_gaps(child);
136 child->x = parent->x; 105 child->x = parent->x;
137 child->y = parent->y + parent_offset; 106 child->y = parent->y + parent_offset;
@@ -141,65 +110,83 @@ static void apply_tabbed_or_stacked_layout(struct sway_container *parent) {
141 } 110 }
142} 111}
143 112
144static void arrange_children_of(struct sway_container *parent); 113static void apply_stacked_layout(list_t *children, struct wlr_box *parent) {
114 if (!children->length) {
115 return;
116 }
117 size_t parent_offset = container_titlebar_height() * children->length;
118 size_t parent_height = parent->height - parent_offset;
119 for (int i = 0; i < children->length; ++i) {
120 struct sway_container *child = children->items[i];
121 container_remove_gaps(child);
122 child->x = parent->x;
123 child->y = parent->y + parent_offset;
124 child->width = parent->width;
125 child->height = parent_height;
126 container_add_gaps(child);
127 }
128}
145 129
146static void arrange_floating(list_t *floating) { 130static void arrange_floating(list_t *floating) {
147 for (int i = 0; i < floating->length; ++i) { 131 for (int i = 0; i < floating->length; ++i) {
148 struct sway_container *floater = floating->items[i]; 132 struct sway_container *floater = floating->items[i];
149 if (floater->type == C_VIEW) { 133 arrange_container(floater);
150 view_autoconfigure(floater->sway_view);
151 } else {
152 arrange_children_of(floater);
153 }
154 container_set_dirty(floater);
155 } 134 }
156} 135}
157 136
158static void arrange_children_of(struct sway_container *parent) { 137static void arrange_children(list_t *children,
159 if (config->reloading) { 138 enum sway_container_layout layout, struct wlr_box *parent) {
160 return;
161 }
162 wlr_log(WLR_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", parent,
163 parent->name, parent->width, parent->height, parent->x, parent->y);
164
165 // Calculate x, y, width and height of children 139 // Calculate x, y, width and height of children
166 switch (parent->layout) { 140 switch (layout) {
167 case L_HORIZ: 141 case L_HORIZ:
168 apply_horiz_layout(parent); 142 apply_horiz_layout(children, parent);
169 break; 143 break;
170 case L_VERT: 144 case L_VERT:
171 apply_vert_layout(parent); 145 apply_vert_layout(children, parent);
172 break; 146 break;
173 case L_TABBED: 147 case L_TABBED:
148 apply_tabbed_layout(children, parent);
149 break;
174 case L_STACKED: 150 case L_STACKED:
175 apply_tabbed_or_stacked_layout(parent); 151 apply_stacked_layout(children, parent);
176 break; 152 break;
177 case L_NONE: 153 case L_NONE:
178 apply_horiz_layout(parent); 154 apply_horiz_layout(children, parent);
179 break; 155 break;
180 } 156 }
181 157
182 // Recurse into child containers 158 // Recurse into child containers
183 for (int i = 0; i < parent->children->length; ++i) { 159 for (int i = 0; i < children->length; ++i) {
184 struct sway_container *child = parent->children->items[i]; 160 struct sway_container *child = children->items[i];
185 if (parent->has_gaps && !child->has_gaps) { 161 arrange_container(child);
186 child->has_gaps = true; 162 }
187 child->gaps_inner = parent->gaps_inner; 163}
188 child->gaps_outer = parent->gaps_outer; 164
189 } 165void arrange_container(struct sway_container *container) {
190 if (child->type == C_VIEW) { 166 if (config->reloading) {
191 view_autoconfigure(child->sway_view); 167 return;
192 } else { 168 }
193 arrange_children_of(child); 169 if (container->type == C_VIEW) {
194 } 170 view_autoconfigure(container->sway_view);
195 container_set_dirty(child); 171 container_set_dirty(container);
172 return;
196 } 173 }
174 if (!sway_assert(container->type == C_CONTAINER, "Expected a container")) {
175 return;
176 }
177 struct wlr_box box;
178 container_get_box(container, &box);
179 arrange_children(container->children, container->layout, &box);
180 container_set_dirty(container);
197} 181}
198 182
199static void arrange_workspace(struct sway_container *workspace) { 183void arrange_workspace(struct sway_container *workspace) {
200 if (config->reloading) { 184 if (config->reloading) {
201 return; 185 return;
202 } 186 }
187 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) {
188 return;
189 }
203 struct sway_container *output = workspace->parent; 190 struct sway_container *output = workspace->parent;
204 struct wlr_box *area = &output->sway_output->usable_area; 191 struct wlr_box *area = &output->sway_output->usable_area;
205 wlr_log(WLR_DEBUG, "Usable area for ws: %dx%d@%d,%d", 192 wlr_log(WLR_DEBUG, "Usable area for ws: %dx%d@%d,%d",
@@ -241,22 +228,22 @@ static void arrange_workspace(struct sway_container *workspace) {
241 fs->y = workspace->parent->y; 228 fs->y = workspace->parent->y;
242 fs->width = workspace->parent->width; 229 fs->width = workspace->parent->width;
243 fs->height = workspace->parent->height; 230 fs->height = workspace->parent->height;
244 if (fs->type == C_VIEW) { 231 arrange_container(fs);
245 view_autoconfigure(fs->sway_view);
246 } else {
247 arrange_children_of(fs);
248 }
249 container_set_dirty(fs);
250 } else { 232 } else {
233 struct wlr_box box;
234 container_get_box(workspace, &box);
235 arrange_children(workspace->children, workspace->layout, &box);
251 arrange_floating(workspace->sway_workspace->floating); 236 arrange_floating(workspace->sway_workspace->floating);
252 arrange_children_of(workspace);
253 } 237 }
254} 238}
255 239
256static void arrange_output(struct sway_container *output) { 240void arrange_output(struct sway_container *output) {
257 if (config->reloading) { 241 if (config->reloading) {
258 return; 242 return;
259 } 243 }
244 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
245 return;
246 }
260 const struct wlr_box *output_box = wlr_output_layout_get_box( 247 const struct wlr_box *output_box = wlr_output_layout_get_box(
261 root_container.sway_root->output_layout, 248 root_container.sway_root->output_layout,
262 output->sway_output->wlr_output); 249 output->sway_output->wlr_output);
@@ -273,7 +260,7 @@ static void arrange_output(struct sway_container *output) {
273 } 260 }
274} 261}
275 262
276static void arrange_root() { 263void arrange_root(void) {
277 if (config->reloading) { 264 if (config->reloading) {
278 return; 265 return;
279 } 266 }
@@ -304,12 +291,8 @@ void arrange_windows(struct sway_container *container) {
304 arrange_workspace(container); 291 arrange_workspace(container);
305 break; 292 break;
306 case C_CONTAINER: 293 case C_CONTAINER:
307 arrange_children_of(container);
308 container_set_dirty(container);
309 break;
310 case C_VIEW: 294 case C_VIEW:
311 view_autoconfigure(container->sway_view); 295 arrange_container(container);
312 container_set_dirty(container);
313 break; 296 break;
314 case C_TYPES: 297 case C_TYPES:
315 break; 298 break;