summaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 16:24:11 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 16:24:11 +1000
commit38398e2d77d57dc06b67ec88a54091c897915602 (patch)
treec80935807865fd96ab7d037070287d4dfaba1863 /sway/desktop/output.c
parentPreserve buffers during transactions (diff)
downloadsway-38398e2d77d57dc06b67ec88a54091c897915602.tar.gz
sway-38398e2d77d57dc06b67ec88a54091c897915602.tar.zst
sway-38398e2d77d57dc06b67ec88a54091c897915602.zip
Implement atomic layout updates for tree operations
This implements atomic layout updates for when views map, reparent or unmap.
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c293
1 files changed, 146 insertions, 147 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index a485cb10..9db95ef5 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -102,40 +102,8 @@ static bool get_surface_box(struct root_geometry *geo,
102 wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); 102 wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box);
103 103
104 struct wlr_box output_box = { 104 struct wlr_box output_box = {
105 .width = output->swayc->width, 105 .width = output->swayc->current.swayc_width,
106 .height = output->swayc->height, 106 .height = output->swayc->current.swayc_height,
107 };
108
109 struct wlr_box intersection;
110 return wlr_box_intersection(&output_box, &rotated_box, &intersection);
111}
112
113static bool get_view_box(struct root_geometry *geo,
114 struct sway_output *output, struct sway_view *view, int sx, int sy,
115 struct wlr_box *surface_box) {
116 int sw = view->saved_surface_width;
117 int sh = view->saved_surface_height;
118
119 double _sx = sx, _sy = sy;
120 rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height,
121 geo->rotation);
122
123 struct wlr_box box = {
124 .x = geo->x + _sx,
125 .y = geo->y + _sy,
126 .width = sw,
127 .height = sh,
128 };
129 if (surface_box != NULL) {
130 memcpy(surface_box, &box, sizeof(struct wlr_box));
131 }
132
133 struct wlr_box rotated_box;
134 wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box);
135
136 struct wlr_box output_box = {
137 .width = output->swayc->width,
138 .height = output->swayc->height,
139 }; 107 };
140 108
141 struct wlr_box intersection; 109 struct wlr_box intersection;
@@ -158,8 +126,8 @@ static void output_view_for_each_surface(struct sway_view *view,
158 struct root_geometry *geo, wlr_surface_iterator_func_t iterator, 126 struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
159 void *user_data) { 127 void *user_data) {
160 struct render_data *data = user_data; 128 struct render_data *data = user_data;
161 geo->x = view->swayc->current.view_x - data->output->swayc->x; 129 geo->x = view->swayc->current.view_x - data->output->swayc->current.swayc_x;
162 geo->y = view->swayc->current.view_y - data->output->swayc->y; 130 geo->y = view->swayc->current.view_y - data->output->swayc->current.swayc_y;
163 geo->width = view->swayc->current.view_width; 131 geo->width = view->swayc->current.view_width;
164 geo->height = view->swayc->current.view_height; 132 geo->height = view->swayc->current.view_height;
165 geo->rotation = 0; // TODO 133 geo->rotation = 0; // TODO
@@ -187,8 +155,8 @@ static void unmanaged_for_each_surface(struct wl_list *unmanaged,
187 wl_list_for_each(unmanaged_surface, unmanaged, link) { 155 wl_list_for_each(unmanaged_surface, unmanaged, link) {
188 struct wlr_xwayland_surface *xsurface = 156 struct wlr_xwayland_surface *xsurface =
189 unmanaged_surface->wlr_xwayland_surface; 157 unmanaged_surface->wlr_xwayland_surface;
190 double ox = unmanaged_surface->lx - output->swayc->x; 158 double ox = unmanaged_surface->lx - output->swayc->current.swayc_x;
191 double oy = unmanaged_surface->ly - output->swayc->y; 159 double oy = unmanaged_surface->ly - output->swayc->current.swayc_y;
192 160
193 surface_for_each_surface(xsurface->surface, ox, oy, geo, 161 surface_for_each_surface(xsurface->surface, ox, oy, geo,
194 iterator, user_data); 162 iterator, user_data);
@@ -274,26 +242,14 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
274 pixman_region32_t *output_damage = data->damage; 242 pixman_region32_t *output_damage = data->damage;
275 float alpha = data->alpha; 243 float alpha = data->alpha;
276 244
277 struct wlr_texture *texture = NULL; 245 struct wlr_texture *texture = wlr_surface_get_texture(surface);
278 struct wlr_box box; 246 if (!texture) {
279 bool intersects; 247 return;
280
281 // If this is the main surface of a view, render the saved_buffer instead
282 // if it exists. It exists when we are mid-transaction.
283 if (data->view && data->view->saved_buffer &&
284 data->view->surface == surface) {
285 texture = data->view->saved_buffer->texture;
286 intersects = get_view_box(&data->root_geo, data->output, data->view,
287 sx, sy, &box);
288 } else {
289 texture = wlr_surface_get_texture(surface);
290 if (texture == NULL) {
291 return;
292 }
293 intersects = get_surface_box(&data->root_geo, data->output, surface,
294 sx, sy, &box);
295 } 248 }
296 249
250 struct wlr_box box;
251 bool intersects = get_surface_box(&data->root_geo, data->output, surface,
252 sx, sy, &box);
297 if (!intersects) { 253 if (!intersects) {
298 return; 254 return;
299 } 255 }
@@ -394,58 +350,98 @@ static void render_view_surfaces(struct sway_view *view,
394 view, &data.root_geo, render_surface_iterator, &data); 350 view, &data.root_geo, render_surface_iterator, &data);
395} 351}
396 352
353static void render_saved_view(struct sway_view *view,
354 struct sway_output *output, pixman_region32_t *damage, float alpha) {
355 struct wlr_output *wlr_output = output->wlr_output;
356
357 struct wlr_texture *texture = transaction_get_texture(view);
358 if (!texture) {
359 return;
360 }
361 struct wlr_box box = {
362 .x = view->swayc->current.view_x - output->swayc->current.swayc_x,
363 .y = view->swayc->current.view_y - output->swayc->current.swayc_y,
364 .width = view->swayc->current.view_width,
365 .height = view->swayc->current.view_height,
366 };
367
368 struct wlr_box output_box = {
369 .width = output->swayc->current.swayc_width,
370 .height = output->swayc->current.swayc_height,
371 };
372
373 struct wlr_box intersection;
374 bool intersects = wlr_box_intersection(&output_box, &box, &intersection);
375 if (!intersects) {
376 return;
377 }
378
379 scale_box(&box, wlr_output->scale);
380
381 float matrix[9];
382 wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
383 wlr_output->transform_matrix);
384
385 render_texture(wlr_output, damage, texture, &box, matrix, alpha);
386}
387
397/** 388/**
398 * Render a view's surface and left/bottom/right borders. 389 * Render a view's surface and left/bottom/right borders.
399 */ 390 */
400static void render_view(struct sway_output *output, pixman_region32_t *damage, 391static void render_view(struct sway_output *output, pixman_region32_t *damage,
401 struct sway_container *con, struct border_colors *colors) { 392 struct sway_container *con, struct border_colors *colors) {
402 struct sway_view *view = con->sway_view; 393 struct sway_view *view = con->sway_view;
403 render_view_surfaces(view, output, damage, view->swayc->alpha); 394 if (view->swayc->instructions->length) {
395 render_saved_view(view, output, damage, view->swayc->alpha);
396 } else {
397 render_view_surfaces(view, output, damage, view->swayc->alpha);
398 }
404 399
405 struct wlr_box box; 400 struct wlr_box box;
406 float output_scale = output->wlr_output->scale; 401 float output_scale = output->wlr_output->scale;
407 float color[4]; 402 float color[4];
403 struct sway_container_state *state = &con->current;
408 404
409 if (con->current.border != B_NONE) { 405 if (state->border != B_NONE) {
410 if (con->current.border_left) { 406 if (state->border_left) {
411 memcpy(&color, colors->child_border, sizeof(float) * 4); 407 memcpy(&color, colors->child_border, sizeof(float) * 4);
412 premultiply_alpha(color, con->alpha); 408 premultiply_alpha(color, con->alpha);
413 box.x = con->current.swayc_x; 409 box.x = state->swayc_x;
414 box.y = con->current.view_y; 410 box.y = state->view_y;
415 box.width = con->current.border_thickness; 411 box.width = state->border_thickness;
416 box.height = con->current.view_height; 412 box.height = state->view_height;
417 scale_box(&box, output_scale); 413 scale_box(&box, output_scale);
418 render_rect(output->wlr_output, damage, &box, color); 414 render_rect(output->wlr_output, damage, &box, color);
419 } 415 }
420 416
421 if (con->current.border_right) { 417 if (state->border_right) {
422 if (con->parent->children->length == 1 418 if (state->parent->current.children->length == 1
423 && con->parent->current.layout == L_HORIZ) { 419 && state->parent->current.layout == L_HORIZ) {
424 memcpy(&color, colors->indicator, sizeof(float) * 4); 420 memcpy(&color, colors->indicator, sizeof(float) * 4);
425 } else { 421 } else {
426 memcpy(&color, colors->child_border, sizeof(float) * 4); 422 memcpy(&color, colors->child_border, sizeof(float) * 4);
427 } 423 }
428 premultiply_alpha(color, con->alpha); 424 premultiply_alpha(color, con->alpha);
429 box.x = con->current.view_x + con->current.view_width; 425 box.x = state->view_x + state->view_width;
430 box.y = con->current.view_y; 426 box.y = state->view_y;
431 box.width = con->current.border_thickness; 427 box.width = state->border_thickness;
432 box.height = con->current.view_height; 428 box.height = state->view_height;
433 scale_box(&box, output_scale); 429 scale_box(&box, output_scale);
434 render_rect(output->wlr_output, damage, &box, color); 430 render_rect(output->wlr_output, damage, &box, color);
435 } 431 }
436 432
437 if (con->current.border_bottom) { 433 if (state->border_bottom) {
438 if (con->parent->children->length == 1 434 if (state->parent->current.children->length == 1
439 && con->parent->current.layout == L_VERT) { 435 && con->current.parent->current.layout == L_VERT) {
440 memcpy(&color, colors->indicator, sizeof(float) * 4); 436 memcpy(&color, colors->indicator, sizeof(float) * 4);
441 } else { 437 } else {
442 memcpy(&color, colors->child_border, sizeof(float) * 4); 438 memcpy(&color, colors->child_border, sizeof(float) * 4);
443 } 439 }
444 premultiply_alpha(color, con->alpha); 440 premultiply_alpha(color, con->alpha);
445 box.x = con->current.swayc_x; 441 box.x = state->swayc_x;
446 box.y = con->current.view_y + con->current.view_height; 442 box.y = state->view_y + state->view_height;
447 box.width = con->current.swayc_width; 443 box.width = state->swayc_width;
448 box.height = con->current.border_thickness; 444 box.height = state->border_thickness;
449 scale_box(&box, output_scale); 445 scale_box(&box, output_scale);
450 render_rect(output->wlr_output, damage, &box, color); 446 render_rect(output->wlr_output, damage, &box, color);
451 } 447 }
@@ -469,10 +465,13 @@ static void render_titlebar(struct sway_output *output,
469 struct wlr_texture *marks_texture) { 465 struct wlr_texture *marks_texture) {
470 struct wlr_box box; 466 struct wlr_box box;
471 float color[4]; 467 float color[4];
468 struct sway_container_state *state = &con->current;
472 float output_scale = output->wlr_output->scale; 469 float output_scale = output->wlr_output->scale;
473 enum sway_container_layout layout = con->parent->current.layout; 470 enum sway_container_layout layout = state->parent->current.layout;
474 bool is_last_child = 471 list_t *children = state->parent->current.children;
475 con->parent->children->items[con->parent->children->length - 1] == con; 472 bool is_last_child = children->items[children->length - 1] == con;
473 double output_x = output->swayc->current.swayc_x;
474 double output_y = output->swayc->current.swayc_y;
476 475
477 // Single pixel bar above title 476 // Single pixel bar above title
478 memcpy(&color, colors->border, sizeof(float) * 4); 477 memcpy(&color, colors->border, sizeof(float) * 4);
@@ -490,10 +489,8 @@ static void render_titlebar(struct sway_output *output,
490 if (layout == L_HORIZ || layout == L_VERT || 489 if (layout == L_HORIZ || layout == L_VERT ||
491 (layout == L_STACKED && is_last_child)) { 490 (layout == L_STACKED && is_last_child)) {
492 if (con->type == C_VIEW) { 491 if (con->type == C_VIEW) {
493 left_offset = 492 left_offset = state->border_left * state->border_thickness;
494 con->current.border_left * con->current.border_thickness; 493 right_offset = state->border_right * state->border_thickness;
495 right_offset =
496 con->current.border_right * con->current.border_thickness;
497 connects_sides = true; 494 connects_sides = true;
498 } 495 }
499 } 496 }
@@ -527,10 +524,9 @@ static void render_titlebar(struct sway_output *output,
527 struct wlr_box texture_box; 524 struct wlr_box texture_box;
528 wlr_texture_get_size(marks_texture, 525 wlr_texture_get_size(marks_texture,
529 &texture_box.width, &texture_box.height); 526 &texture_box.width, &texture_box.height);
530 texture_box.x = (x - output->swayc->x + width - TITLEBAR_H_PADDING) 527 texture_box.x = (x - output_x + width - TITLEBAR_H_PADDING)
531 * output_scale - texture_box.width; 528 * output_scale - texture_box.width;
532 texture_box.y = (y - output->swayc->y + TITLEBAR_V_PADDING) 529 texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
533 * output_scale;
534 530
535 float matrix[9]; 531 float matrix[9];
536 wlr_matrix_project_box(matrix, &texture_box, 532 wlr_matrix_project_box(matrix, &texture_box,
@@ -551,10 +547,8 @@ static void render_titlebar(struct sway_output *output,
551 struct wlr_box texture_box; 547 struct wlr_box texture_box;
552 wlr_texture_get_size(title_texture, 548 wlr_texture_get_size(title_texture,
553 &texture_box.width, &texture_box.height); 549 &texture_box.width, &texture_box.height);
554 texture_box.x = (x - output->swayc->x + TITLEBAR_H_PADDING) 550 texture_box.x = (x - output_x + TITLEBAR_H_PADDING) * output_scale;
555 * output_scale; 551 texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
556 texture_box.y = (y - output->swayc->y + TITLEBAR_V_PADDING)
557 * output_scale;
558 552
559 float matrix[9]; 553 float matrix[9];
560 wlr_matrix_project_box(matrix, &texture_box, 554 wlr_matrix_project_box(matrix, &texture_box,
@@ -614,16 +608,15 @@ static void render_titlebar(struct sway_output *output,
614 // Left pixel in line with bottom bar 608 // Left pixel in line with bottom bar
615 box.x = x; 609 box.x = x;
616 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; 610 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
617 box.width = con->current.border_thickness * con->current.border_left; 611 box.width = state->border_thickness * state->border_left;
618 box.height = TITLEBAR_BORDER_THICKNESS; 612 box.height = TITLEBAR_BORDER_THICKNESS;
619 scale_box(&box, output_scale); 613 scale_box(&box, output_scale);
620 render_rect(output->wlr_output, output_damage, &box, color); 614 render_rect(output->wlr_output, output_damage, &box, color);
621 615
622 // Right pixel in line with bottom bar 616 // Right pixel in line with bottom bar
623 box.x = x + width - 617 box.x = x + width - state->border_thickness * state->border_right;
624 con->current.border_thickness * con->current.border_right;
625 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS; 618 box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
626 box.width = con->current.border_thickness * con->current.border_right; 619 box.width = state->border_thickness * state->border_right;
627 box.height = TITLEBAR_BORDER_THICKNESS; 620 box.height = TITLEBAR_BORDER_THICKNESS;
628 scale_box(&box, output_scale); 621 scale_box(&box, output_scale);
629 render_rect(output->wlr_output, output_damage, &box, color); 622 render_rect(output->wlr_output, output_damage, &box, color);
@@ -636,7 +629,8 @@ static void render_titlebar(struct sway_output *output,
636static void render_top_border(struct sway_output *output, 629static void render_top_border(struct sway_output *output,
637 pixman_region32_t *output_damage, struct sway_container *con, 630 pixman_region32_t *output_damage, struct sway_container *con,
638 struct border_colors *colors) { 631 struct border_colors *colors) {
639 if (!con->current.border_top) { 632 struct sway_container_state *state = &con->current;
633 if (!state->border_top) {
640 return; 634 return;
641 } 635 }
642 struct wlr_box box; 636 struct wlr_box box;
@@ -646,10 +640,10 @@ static void render_top_border(struct sway_output *output,
646 // Child border - top edge 640 // Child border - top edge
647 memcpy(&color, colors->child_border, sizeof(float) * 4); 641 memcpy(&color, colors->child_border, sizeof(float) * 4);
648 premultiply_alpha(color, con->alpha); 642 premultiply_alpha(color, con->alpha);
649 box.x = con->current.swayc_x; 643 box.x = state->swayc_x;
650 box.y = con->current.swayc_y; 644 box.y = state->swayc_y;
651 box.width = con->current.swayc_width; 645 box.width = state->swayc_width;
652 box.height = con->current.border_thickness; 646 box.height = state->border_thickness;
653 scale_box(&box, output_scale); 647 scale_box(&box, output_scale);
654 render_rect(output->wlr_output, output_damage, &box, color); 648 render_rect(output->wlr_output, output_damage, &box, color);
655} 649}
@@ -669,31 +663,34 @@ static void render_container_simple(struct sway_output *output,
669 struct sway_seat *seat = input_manager_current_seat(input_manager); 663 struct sway_seat *seat = input_manager_current_seat(input_manager);
670 struct sway_container *focus = seat_get_focus(seat); 664 struct sway_container *focus = seat_get_focus(seat);
671 665
672 for (int i = 0; i < con->children->length; ++i) { 666 for (int i = 0; i < con->current.children->length; ++i) {
673 struct sway_container *child = con->children->items[i]; 667 struct sway_container *child = con->current.children->items[i];
674 668
675 if (child->type == C_VIEW) { 669 if (child->type == C_VIEW) {
670 struct sway_view *view = child->sway_view;
676 struct border_colors *colors; 671 struct border_colors *colors;
677 struct wlr_texture *title_texture; 672 struct wlr_texture *title_texture;
678 struct wlr_texture *marks_texture; 673 struct wlr_texture *marks_texture;
674 struct sway_container_state *state = &child->current;
675
679 if (focus == child || parent_focused) { 676 if (focus == child || parent_focused) {
680 colors = &config->border_colors.focused; 677 colors = &config->border_colors.focused;
681 title_texture = child->title_focused; 678 title_texture = child->title_focused;
682 marks_texture = child->sway_view->marks_focused; 679 marks_texture = view->marks_focused;
683 } else if (seat_get_focus_inactive(seat, con) == child) { 680 } else if (seat_get_focus_inactive(seat, con) == child) {
684 colors = &config->border_colors.focused_inactive; 681 colors = &config->border_colors.focused_inactive;
685 title_texture = child->title_focused_inactive; 682 title_texture = child->title_focused_inactive;
686 marks_texture = child->sway_view->marks_focused_inactive; 683 marks_texture = view->marks_focused_inactive;
687 } else { 684 } else {
688 colors = &config->border_colors.unfocused; 685 colors = &config->border_colors.unfocused;
689 title_texture = child->title_unfocused; 686 title_texture = child->title_unfocused;
690 marks_texture = child->sway_view->marks_unfocused; 687 marks_texture = view->marks_unfocused;
691 } 688 }
692 689
693 if (child->current.border == B_NORMAL) { 690 if (state->border == B_NORMAL) {
694 render_titlebar(output, damage, child, child->current.swayc_x, 691 render_titlebar(output, damage, child, state->swayc_x,
695 child->current.swayc_y, child->current.swayc_width, 692 state->swayc_y, state->swayc_width, colors,
696 colors, title_texture, marks_texture); 693 title_texture, marks_texture);
697 } else { 694 } else {
698 render_top_border(output, damage, child, colors); 695 render_top_border(output, damage, child, colors);
699 } 696 }
@@ -711,22 +708,23 @@ static void render_container_simple(struct sway_output *output,
711static void render_container_tabbed(struct sway_output *output, 708static void render_container_tabbed(struct sway_output *output,
712 pixman_region32_t *damage, struct sway_container *con, 709 pixman_region32_t *damage, struct sway_container *con,
713 bool parent_focused) { 710 bool parent_focused) {
714 if (!con->children->length) { 711 if (!con->current.children->length) {
715 return; 712 return;
716 } 713 }
717 struct sway_seat *seat = input_manager_current_seat(input_manager); 714 struct sway_seat *seat = input_manager_current_seat(input_manager);
718 struct sway_container *focus = seat_get_focus(seat); 715 struct sway_container *focus = seat_get_focus(seat);
719 struct sway_container *current = seat_get_active_child(seat, con); 716 struct sway_container *current = seat_get_active_child(seat, con);
720 struct border_colors *current_colors = NULL; 717 struct border_colors *current_colors = NULL;
718 struct sway_container_state *pstate = &con->current;
721 719
722 // Render tabs 720 // Render tabs
723 for (int i = 0; i < con->children->length; ++i) { 721 for (int i = 0; i < con->current.children->length; ++i) {
724 struct sway_container *child = con->children->items[i]; 722 struct sway_container *child = con->current.children->items[i];
723 struct sway_view *view = child->type == C_VIEW ? child->sway_view : NULL;
724 struct sway_container_state *cstate = &child->current;
725 struct border_colors *colors; 725 struct border_colors *colors;
726 struct wlr_texture *title_texture; 726 struct wlr_texture *title_texture;
727 struct wlr_texture *marks_texture; 727 struct wlr_texture *marks_texture;
728 struct sway_view *view =
729 child->type == C_VIEW ? child->sway_view : NULL;
730 728
731 if (focus == child || parent_focused) { 729 if (focus == child || parent_focused) {
732 colors = &config->border_colors.focused; 730 colors = &config->border_colors.focused;
@@ -735,22 +733,22 @@ static void render_container_tabbed(struct sway_output *output,
735 } else if (child == current) { 733 } else if (child == current) {
736 colors = &config->border_colors.focused_inactive; 734 colors = &config->border_colors.focused_inactive;
737 title_texture = child->title_focused_inactive; 735 title_texture = child->title_focused_inactive;
738 marks_texture = view ? view->marks_focused : NULL; 736 marks_texture = view ? view->marks_focused_inactive : NULL;
739 } else { 737 } else {
740 colors = &config->border_colors.unfocused; 738 colors = &config->border_colors.unfocused;
741 title_texture = child->title_unfocused; 739 title_texture = child->title_unfocused;
742 marks_texture = view ? view->marks_unfocused : NULL; 740 marks_texture = view ? view->marks_unfocused : NULL;
743 } 741 }
744 742
745 int tab_width = con->current.swayc_width / con->children->length; 743 int tab_width = pstate->swayc_width / pstate->children->length;
746 int x = con->current.swayc_x + tab_width * i; 744 int x = pstate->swayc_x + tab_width * i;
747 // Make last tab use the remaining width of the parent 745 // Make last tab use the remaining width of the parent
748 if (i == con->children->length - 1) { 746 if (i == pstate->children->length - 1) {
749 tab_width = con->current.swayc_width - tab_width * i; 747 tab_width = pstate->swayc_width - tab_width * i;
750 } 748 }
751 749
752 render_titlebar(output, damage, child, x, child->current.swayc_y, 750 render_titlebar(output, damage, child, x, cstate->swayc_y, tab_width,
753 tab_width, colors, title_texture, marks_texture); 751 colors, title_texture, marks_texture);
754 752
755 if (child == current) { 753 if (child == current) {
756 current_colors = colors; 754 current_colors = colors;
@@ -772,22 +770,23 @@ static void render_container_tabbed(struct sway_output *output,
772static void render_container_stacked(struct sway_output *output, 770static void render_container_stacked(struct sway_output *output,
773 pixman_region32_t *damage, struct sway_container *con, 771 pixman_region32_t *damage, struct sway_container *con,
774 bool parent_focused) { 772 bool parent_focused) {
775 if (!con->children->length) { 773 if (!con->current.children->length) {
776 return; 774 return;
777 } 775 }
778 struct sway_seat *seat = input_manager_current_seat(input_manager); 776 struct sway_seat *seat = input_manager_current_seat(input_manager);
779 struct sway_container *focus = seat_get_focus(seat); 777 struct sway_container *focus = seat_get_focus(seat);
780 struct sway_container *current = seat_get_active_child(seat, con); 778 struct sway_container *current = seat_get_active_child(seat, con);
781 struct border_colors *current_colors = NULL; 779 struct border_colors *current_colors = NULL;
780 struct sway_container_state *pstate = &con->current;
782 781
783 // Render titles 782 // Render titles
784 for (int i = 0; i < con->children->length; ++i) { 783 for (int i = 0; i < con->current.children->length; ++i) {
785 struct sway_container *child = con->children->items[i]; 784 struct sway_container *child = con->current.children->items[i];
785 struct sway_view *view = child->type == C_VIEW ? child->sway_view : NULL;
786 struct sway_container_state *cstate = &child->current;
786 struct border_colors *colors; 787 struct border_colors *colors;
787 struct wlr_texture *title_texture; 788 struct wlr_texture *title_texture;
788 struct wlr_texture *marks_texture; 789 struct wlr_texture *marks_texture;
789 struct sway_view *view =
790 child->type == C_VIEW ? child->sway_view : NULL;
791 790
792 if (focus == child || parent_focused) { 791 if (focus == child || parent_focused) {
793 colors = &config->border_colors.focused; 792 colors = &config->border_colors.focused;
@@ -803,10 +802,9 @@ static void render_container_stacked(struct sway_output *output,
803 marks_texture = view ? view->marks_unfocused : NULL; 802 marks_texture = view ? view->marks_unfocused : NULL;
804 } 803 }
805 804
806 int y = con->current.swayc_y + container_titlebar_height() * i; 805 int y = pstate->swayc_y + container_titlebar_height() * i;
807 render_titlebar(output, damage, child, child->current.swayc_x, y, 806 render_titlebar(output, damage, child, cstate->swayc_x, y,
808 child->current.swayc_width, colors, 807 cstate->swayc_width, colors, title_texture, marks_texture);
809 title_texture, marks_texture);
810 808
811 if (child == current) { 809 if (child == current) {
812 current_colors = colors; 810 current_colors = colors;
@@ -877,17 +875,18 @@ static void render_floating_container(struct sway_output *soutput,
877 875
878static void render_floating(struct sway_output *soutput, 876static void render_floating(struct sway_output *soutput,
879 pixman_region32_t *damage) { 877 pixman_region32_t *damage) {
880 for (int i = 0; i < root_container.children->length; ++i) { 878 for (int i = 0; i < root_container.current.children->length; ++i) {
881 struct sway_container *output = root_container.children->items[i]; 879 struct sway_container *output =
882 for (int j = 0; j < output->children->length; ++j) { 880 root_container.current.children->items[i];
883 struct sway_container *workspace = output->children->items[j]; 881 for (int j = 0; j < output->current.children->length; ++j) {
884 struct sway_workspace *ws = workspace->sway_workspace; 882 struct sway_container *ws = output->current.children->items[j];
885 if (!workspace_is_visible(workspace)) { 883 if (!workspace_is_visible(ws)) {
886 continue; 884 continue;
887 } 885 }
888 for (int k = 0; k < ws->floating->children->length; ++k) { 886 list_t *floating =
889 struct sway_container *floater = 887 ws->current.ws_floating->current.children;
890 ws->floating->children->items[k]; 888 for (int k = 0; k < floating->length; ++k) {
889 struct sway_container *floater = floating->items[k];
891 render_floating_container(soutput, damage, floater); 890 render_floating_container(soutput, damage, floater);
892 } 891 }
893 } 892 }
@@ -901,7 +900,7 @@ static struct sway_container *output_get_active_workspace(
901 seat_get_focus_inactive(seat, output->swayc); 900 seat_get_focus_inactive(seat, output->swayc);
902 if (!focus) { 901 if (!focus) {
903 // We've never been to this output before 902 // We've never been to this output before
904 focus = output->swayc->children->items[0]; 903 focus = output->swayc->current.children->items[0];
905 } 904 }
906 struct sway_container *workspace = focus; 905 struct sway_container *workspace = focus;
907 if (workspace->type != C_WORKSPACE) { 906 if (workspace->type != C_WORKSPACE) {
@@ -942,8 +941,9 @@ static void render_output(struct sway_output *output, struct timespec *when,
942 } 941 }
943 942
944 struct sway_container *workspace = output_get_active_workspace(output); 943 struct sway_container *workspace = output_get_active_workspace(output);
944 struct sway_view *fullscreen_view = workspace->current.ws_fullscreen;
945 945
946 if (workspace->sway_workspace->fullscreen) { 946 if (fullscreen_view) {
947 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; 947 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
948 948
949 int nrects; 949 int nrects;
@@ -954,10 +954,9 @@ static void render_output(struct sway_output *output, struct timespec *when,
954 } 954 }
955 955
956 // TODO: handle views smaller than the output 956 // TODO: handle views smaller than the output
957 render_view_surfaces( 957 render_view_surfaces(fullscreen_view, output, damage, 1.0f);
958 workspace->sway_workspace->fullscreen, output, damage, 1.0f);
959 958
960 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { 959 if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) {
961 render_unmanaged(output, damage, 960 render_unmanaged(output, damage,
962 &root_container.sway_root->xwayland_unmanaged); 961 &root_container.sway_root->xwayland_unmanaged);
963 } 962 }
@@ -1073,11 +1072,11 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
1073 }; 1072 };
1074 1073
1075 struct sway_container *workspace = output_get_active_workspace(output); 1074 struct sway_container *workspace = output_get_active_workspace(output);
1076 if (workspace->sway_workspace->fullscreen) { 1075 if (workspace->current.ws_fullscreen) {
1077 send_frame_done_container_iterator( 1076 send_frame_done_container_iterator(
1078 workspace->sway_workspace->fullscreen->swayc, &data); 1077 workspace->current.ws_fullscreen->swayc, &data);
1079 1078
1080 if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { 1079 if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) {
1081 send_frame_done_unmanaged(&data, 1080 send_frame_done_unmanaged(&data,
1082 &root_container.sway_root->xwayland_unmanaged); 1081 &root_container.sway_root->xwayland_unmanaged);
1083 } 1082 }