summaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c204
1 files changed, 100 insertions, 104 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 343f349a..9580d3a7 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -24,10 +24,10 @@ static void output_layout_handle_change(struct wl_listener *listener,
24 root_container.sway_root->output_layout; 24 root_container.sway_root->output_layout;
25 const struct wlr_box *layout_box = 25 const struct wlr_box *layout_box =
26 wlr_output_layout_get_box(output_layout, NULL); 26 wlr_output_layout_get_box(output_layout, NULL);
27 root_container.x = layout_box->x; 27 root_container.box.x = layout_box->x;
28 root_container.y = layout_box->y; 28 root_container.box.y = layout_box->y;
29 root_container.width = layout_box->width; 29 root_container.box.width = layout_box->width;
30 root_container.height = layout_box->height; 30 root_container.box.height = layout_box->height;
31 31
32 for (int i = 0 ; i < root_container.children->length; ++i) { 32 for (int i = 0 ; i < root_container.children->length; ++i) {
33 struct sway_container *output_container = 33 struct sway_container *output_container =
@@ -42,10 +42,10 @@ static void output_layout_handle_change(struct wl_listener *listener,
42 if (!output_box) { 42 if (!output_box) {
43 continue; 43 continue;
44 } 44 }
45 output_container->x = output_box->x; 45 output_container->box.x = output_box->x;
46 output_container->y = output_box->y; 46 output_container->box.y = output_box->y;
47 output_container->width = output_box->width; 47 output_container->box.width = output_box->width;
48 output_container->height = output_box->height; 48 output_container->box.height = output_box->height;
49 } 49 }
50 50
51 arrange_windows(&root_container, -1, -1); 51 arrange_windows(&root_container, -1, -1);
@@ -112,9 +112,9 @@ struct sway_container *container_add_sibling(struct sway_container *fixed,
112 112
113void container_add_child(struct sway_container *parent, 113void container_add_child(struct sway_container *parent,
114 struct sway_container *child) { 114 struct sway_container *child) {
115 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", 115 wlr_log(L_DEBUG, "Adding id:%zd (%d, %dx%d) to id:%zd (%d, %dx%d)",
116 child, child->type, child->width, child->height, 116 child->id, child->type, child->box.width, child->box.height,
117 parent, parent->type, parent->width, parent->height); 117 parent->id, parent->type, parent->box.width, parent->box.height);
118 list_add(parent->children, child); 118 list_add(parent->children, child);
119 child->parent = parent; 119 child->parent = parent;
120} 120}
@@ -138,7 +138,7 @@ void container_move_to(struct sway_container *container,
138 return; 138 return;
139 } 139 }
140 struct sway_container *old_parent = container_remove_child(container); 140 struct sway_container *old_parent = container_remove_child(container);
141 container->width = container->height = 0; 141 container->box.width = container->box.height = 0;
142 struct sway_container *new_parent; 142 struct sway_container *new_parent;
143 if (destination->type == C_VIEW) { 143 if (destination->type == C_VIEW) {
144 new_parent = container_add_sibling(destination, container); 144 new_parent = container_add_sibling(destination, container);
@@ -187,11 +187,10 @@ enum sway_container_layout container_get_default_layout(
187 return config->default_layout; 187 return config->default_layout;
188 } else if (config->default_orientation != L_NONE) { 188 } else if (config->default_orientation != L_NONE) {
189 return config->default_orientation; 189 return config->default_orientation;
190 } else if (con->width >= con->height) { 190 } else if (con->box.width >= con->box.height) {
191 return L_HORIZ; 191 return L_HORIZ;
192 } else {
193 return L_VERT;
194 } 192 }
193 return L_VERT;
195} 194}
196 195
197static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { 196static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
@@ -216,25 +215,23 @@ void container_sort_workspaces(struct sway_container *output) {
216 list_stable_sort(output->children, sort_workspace_cmp_qsort); 215 list_stable_sort(output->children, sort_workspace_cmp_qsort);
217} 216}
218 217
219static void apply_horiz_layout(struct sway_container *container, const double x, 218static void apply_horiz_layout(struct sway_container *container,
220 const double y, const double width, 219 const int x, const int y, const int width,
221 const double height, const int start, 220 const int height, const int start, const int end);
222 const int end);
223 221
224static void apply_vert_layout(struct sway_container *container, const double x, 222static void apply_vert_layout(struct sway_container *container,
225 const double y, const double width, 223 const int x, const int y, const int width,
226 const double height, const int start, 224 const int height, const int start, const int end);
227 const int end);
228 225
229void arrange_windows(struct sway_container *container, 226void arrange_windows(struct sway_container *container,
230 double width, double height) { 227 int width, int height) {
231 if (config->reloading) { 228 if (config->reloading) {
232 return; 229 return;
233 } 230 }
234 int i; 231 int i;
235 if (width == -1 || height == -1) { 232 if (width == -1 || height == -1) {
236 width = container->width; 233 width = container->box.width;
237 height = container->height; 234 height = container->box.height;
238 } 235 }
239 // pixels are indivisible. if we don't round the pixels, then the view 236 // pixels are indivisible. if we don't round the pixels, then the view
240 // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's 237 // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's
@@ -242,17 +239,17 @@ void arrange_windows(struct sway_container *container,
242 width = floor(width); 239 width = floor(width);
243 height = floor(height); 240 height = floor(height);
244 241
245 wlr_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container, 242 wlr_log(L_DEBUG, "Arranging layout for %p %s %dx%d+%d,%d", container,
246 container->name, container->width, container->height, container->x, 243 container->name, container->box.width, container->box.height,
247 container->y); 244 container->box.x, container->box.y);
248 245
249 double x = 0, y = 0; 246 int x = 0, y = 0;
250 switch (container->type) { 247 switch (container->type) {
251 case C_ROOT: 248 case C_ROOT:
252 for (i = 0; i < container->children->length; ++i) { 249 for (i = 0; i < container->children->length; ++i) {
253 struct sway_container *output = container->children->items[i]; 250 struct sway_container *output = container->children->items[i];
254 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f", 251 wlr_log(L_DEBUG, "Arranging output '%s' at %d,%d",
255 output->name, output->x, output->y); 252 output->name, output->box.x, output->box.y);
256 arrange_windows(output, -1, -1); 253 arrange_windows(output, -1, -1);
257 } 254 }
258 return; 255 return;
@@ -261,8 +258,8 @@ void arrange_windows(struct sway_container *container,
261 int _width, _height; 258 int _width, _height;
262 wlr_output_effective_resolution( 259 wlr_output_effective_resolution(
263 container->sway_output->wlr_output, &_width, &_height); 260 container->sway_output->wlr_output, &_width, &_height);
264 width = container->width = _width; 261 width = container->box.width = _width;
265 height = container->height = _height; 262 height = container->box.height = _height;
266 } 263 }
267 // arrange all workspaces: 264 // arrange all workspaces:
268 for (i = 0; i < container->children->length; ++i) { 265 for (i = 0; i < container->children->length; ++i) {
@@ -277,31 +274,32 @@ void arrange_windows(struct sway_container *container,
277 struct wlr_box *area = &output->sway_output->usable_area; 274 struct wlr_box *area = &output->sway_output->usable_area;
278 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", 275 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
279 area->width, area->height, area->x, area->y); 276 area->width, area->height, area->x, area->y);
280 container->width = width = area->width; 277 container->box.width = width = area->width;
281 container->height = height = area->height; 278 container->box.height = height = area->height;
282 container->x = x = area->x; 279 container->box.x = x = area->x;
283 container->y = y = area->y; 280 container->box.y = y = area->y;
284 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", 281 wlr_log(L_DEBUG, "Arranging workspace '%s' at %d,%d",
285 container->name, container->x, container->y); 282 container->name, container->box.x, container->box.y);
286 } 283 }
287 // children are properly handled below 284 // children are properly handled below
288 break; 285 break;
289 case C_VIEW: 286 case C_VIEW:
290 { 287 {
291 container->width = width; 288 container->box.width = width;
292 container->height = height; 289 container->box.height = height;
293 view_configure(container->sway_view, container->x, container->y, 290 view_configure(container->sway_view,
294 container->width, container->height); 291 container->box.x, container->box.y,
295 wlr_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f", 292 container->box.width, container->box.height);
296 container->width, container->height, 293 wlr_log(L_DEBUG, "Set view to %d x %d @ %d, %d",
297 container->x, container->y); 294 container->box.width, container->box.height,
295 container->box.x, container->box.y);
298 } 296 }
299 return; 297 return;
300 default: 298 default:
301 container->width = width; 299 container->box.width = width;
302 container->height = height; 300 container->box.height = height;
303 x = container->x; 301 x = container->box.x;
304 y = container->y; 302 y = container->box.y;
305 break; 303 break;
306 } 304 }
307 305
@@ -323,50 +321,49 @@ void arrange_windows(struct sway_container *container,
323} 321}
324 322
325static void apply_horiz_layout(struct sway_container *container, 323static void apply_horiz_layout(struct sway_container *container,
326 const double x, const double y, 324 const int x, const int y, const int width, const int height,
327 const double width, const double height,
328 const int start, const int end) { 325 const int start, const int end) {
329 double scale = 0; 326 double scale = 0;
330 // Calculate total width 327 // Calculate total width
331 for (int i = start; i < end; ++i) { 328 for (int i = start; i < end; ++i) {
332 double *old_width = 329 struct sway_container *child = container->children->items[i];
333 &((struct sway_container *)container->children->items[i])->width; 330 int old_width = child->box.width;
334 if (*old_width <= 0) { 331 if (old_width <= 0) {
335 if (end - start > 1) { 332 if (end - start > 1) {
336 *old_width = width / (end - start - 1); 333 old_width = width / (end - start - 1);
337 } else { 334 } else {
338 *old_width = width; 335 old_width = width;
339 } 336 }
340 } 337 }
341 scale += *old_width; 338 scale += old_width;
342 } 339 }
343 scale = width / scale; 340 scale = width / scale;
344 341
345 // Resize windows 342 // Resize windows
346 double child_x = x; 343 int child_x = x;
347 if (scale > 0.1) { 344 if (scale > 0.1) {
348 wlr_log(L_DEBUG, "Arranging %p horizontally", container); 345 wlr_log(L_DEBUG, "Arranging %p horizontally", container);
349 for (int i = start; i < end; ++i) { 346 for (int i = start; i < end; ++i) {
350 struct sway_container *child = container->children->items[i]; 347 struct sway_container *child = container->children->items[i];
351 wlr_log(L_DEBUG, 348 wlr_log(L_DEBUG,
352 "Calculating arrangement for %p:%d (will scale %f by %f)", 349 "Calculating arrangement for %p:%d (will scale %d by %f)",
353 child, child->type, width, scale); 350 child, child->type, width, scale);
354 351
355 if (child->type == C_VIEW) { 352 if (child->type == C_VIEW) {
356 view_configure(child->sway_view, child_x, y, child->width, 353 view_configure(child->sway_view, child_x, y,
357 child->height); 354 child->box.width, child->box.height);
358 } else { 355 } else {
359 child->x = child_x; 356 child->box.x = child_x;
360 child->y = y; 357 child->box.y = y;
361 } 358 }
362 359
363 if (i == end - 1) { 360 if (i == end - 1) {
364 double remaining_width = x + width - child_x; 361 int remaining_width = x + width - child_x;
365 arrange_windows(child, remaining_width, height); 362 arrange_windows(child, remaining_width, height);
366 } else { 363 } else {
367 arrange_windows(child, child->width * scale, height); 364 arrange_windows(child, child->box.width * scale, height);
368 } 365 }
369 child_x += child->width; 366 child_x += child->box.width;
370 } 367 }
371 368
372 // update focused view border last because it may 369 // update focused view border last because it may
@@ -380,50 +377,49 @@ static void apply_horiz_layout(struct sway_container *container,
380} 377}
381 378
382void apply_vert_layout(struct sway_container *container, 379void apply_vert_layout(struct sway_container *container,
383 const double x, const double y, 380 const int x, const int y, const int width, const int height,
384 const double width, const double height, const int start, 381 const int start, const int end) {
385 const int end) {
386 int i; 382 int i;
387 double scale = 0; 383 double scale = 0;
388 // Calculate total height 384 // Calculate total height
389 for (i = start; i < end; ++i) { 385 for (i = start; i < end; ++i) {
390 double *old_height = 386 struct sway_container *child = container->children->items[i];
391 &((struct sway_container *)container->children->items[i])->height; 387 int old_height = child->box.height;
392 if (*old_height <= 0) { 388 if (old_height <= 0) {
393 if (end - start > 1) { 389 if (end - start > 1) {
394 *old_height = height / (end - start - 1); 390 old_height = height / (end - start - 1);
395 } else { 391 } else {
396 *old_height = height; 392 old_height = height;
397 } 393 }
398 } 394 }
399 scale += *old_height; 395 scale += old_height;
400 } 396 }
401 scale = height / scale; 397 scale = height / scale;
402 398
403 // Resize 399 // Resize
404 double child_y = y; 400 int child_y = y;
405 if (scale > 0.1) { 401 if (scale > 0.1) {
406 wlr_log(L_DEBUG, "Arranging %p vertically", container); 402 wlr_log(L_DEBUG, "Arranging %p vertically", container);
407 for (i = start; i < end; ++i) { 403 for (i = start; i < end; ++i) {
408 struct sway_container *child = container->children->items[i]; 404 struct sway_container *child = container->children->items[i];
409 wlr_log(L_DEBUG, 405 wlr_log(L_DEBUG,
410 "Calculating arrangement for %p:%d (will scale %f by %f)", 406 "Calculating arrangement for %p:%d (will scale %d by %f)",
411 child, child->type, height, scale); 407 child, child->type, height, scale);
412 if (child->type == C_VIEW) { 408 if (child->type == C_VIEW) {
413 view_configure(child->sway_view, x, child_y, child->width, 409 view_configure(child->sway_view, x, child_y,
414 child->height); 410 child->box.width, child->box.height);
415 } else { 411 } else {
416 child->x = x; 412 child->box.x = x;
417 child->y = child_y; 413 child->box.y = child_y;
418 } 414 }
419 415
420 if (i == end - 1) { 416 if (i == end - 1) {
421 double remaining_height = y + height - child_y; 417 int remaining_height = y + height - child_y;
422 arrange_windows(child, width, remaining_height); 418 arrange_windows(child, width, remaining_height);
423 } else { 419 } else {
424 arrange_windows(child, width, child->height * scale); 420 arrange_windows(child, width, child->box.height * scale);
425 } 421 }
426 child_y += child->height; 422 child_y += child->box.height;
427 } 423 }
428 424
429 // update focused view border last because it may 425 // update focused view border last because it may
@@ -496,18 +492,18 @@ static void get_layout_center_position(struct sway_container *container,
496 int *x, int *y) { 492 int *x, int *y) {
497 // FIXME view coords are inconsistently referred to in layout/output systems 493 // FIXME view coords are inconsistently referred to in layout/output systems
498 if (container->type == C_OUTPUT) { 494 if (container->type == C_OUTPUT) {
499 *x = container->x + container->width/2; 495 *x = container->box.x + container->box.width / 2;
500 *y = container->y + container->height/2; 496 *y = container->box.y + container->box.height / 2;
501 } else { 497 } else {
502 struct sway_container *output = container_parent(container, C_OUTPUT); 498 struct sway_container *output = container_parent(container, C_OUTPUT);
503 if (container->type == C_WORKSPACE) { 499 if (container->type == C_WORKSPACE) {
504 // Workspace coordinates are actually wrong/arbitrary, but should 500 // Workspace coordinates are actually wrong/arbitrary, but should
505 // be same as output. 501 // be same as output.
506 *x = output->x; 502 *x = output->box.x;
507 *y = output->y; 503 *y = output->box.y;
508 } else { 504 } else {
509 *x = output->x + container->x; 505 *x = output->box.x + container->box.x;
510 *y = output->y + container->y; 506 *y = output->box.y + container->box.y;
511 } 507 }
512 } 508 }
513} 509}
@@ -678,14 +674,14 @@ struct sway_container *container_replace_child(struct sway_container *child,
678 child->parent = NULL; 674 child->parent = NULL;
679 675
680 // Set geometry for new child 676 // Set geometry for new child
681 new_child->x = child->x; 677 new_child->box.x = child->box.x;
682 new_child->y = child->y; 678 new_child->box.y = child->box.y;
683 new_child->width = child->width; 679 new_child->box.width = child->box.width;
684 new_child->height = child->height; 680 new_child->box.height = child->box.height;
685 681
686 // reset geometry for child 682 // reset geometry for child
687 child->width = 0; 683 child->box.width = 0;
688 child->height = 0; 684 child->box.height = 0;
689 685
690 return parent; 686 return parent;
691} 687}
@@ -701,10 +697,10 @@ struct sway_container *container_split(struct sway_container *child,
701 wlr_log(L_DEBUG, "creating container %p around %p", cont, child); 697 wlr_log(L_DEBUG, "creating container %p around %p", cont, child);
702 698
703 cont->prev_layout = L_NONE; 699 cont->prev_layout = L_NONE;
704 cont->width = child->width; 700 cont->box.width = child->box.width;
705 cont->height = child->height; 701 cont->box.height = child->box.height;
706 cont->x = child->x; 702 cont->box.x = child->box.x;
707 cont->y = child->y; 703 cont->box.y = child->box.y;
708 704
709 if (child->type == C_WORKSPACE) { 705 if (child->type == C_WORKSPACE) {
710 struct sway_seat *seat = input_manager_get_default_seat(input_manager); 706 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
@@ -737,10 +733,10 @@ void container_recursive_resize(struct sway_container *container,
737 bool layout_match = true; 733 bool layout_match = true;
738 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount); 734 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount);
739 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { 735 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) {
740 container->width += amount; 736 container->box.width += amount;
741 layout_match = container->layout == L_HORIZ; 737 layout_match = container->layout == L_HORIZ;
742 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) { 738 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) {
743 container->height += amount; 739 container->box.height += amount;
744 layout_match = container->layout == L_VERT; 740 layout_match = container->layout == L_VERT;
745 } 741 }
746 if (container->children) { 742 if (container->children) {