aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-19 22:54:50 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-21 20:16:56 +1000
commitc08f9bf257c38c92a75988d89fba2d4de6bb2aea (patch)
tree76ea44c5548301ff4892c44838b783eeeb569c62 /sway/tree/container.c
parentMerge pull request #2011 from RyanDwyer/fix-hide-edge-border-bottom (diff)
downloadsway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.tar.gz
sway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.tar.zst
sway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.zip
Implement tabbed layout
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c267
1 files changed, 195 insertions, 72 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index feaf7647..76a21c19 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -452,80 +452,139 @@ struct sway_container *container_parent(struct sway_container *container,
452 return container; 452 return container;
453} 453}
454 454
455struct sway_container *container_at(struct sway_container *parent, 455static struct sway_container *container_at_view(struct sway_container *swayc,
456 double lx, double ly, 456 double ox, double oy,
457 struct wlr_surface **surface, double *sx, double *sy) { 457 struct wlr_surface **surface, double *sx, double *sy) {
458 list_t *queue = get_bfs_queue(); 458 struct sway_view *sview = swayc->sway_view;
459 if (!queue) { 459 double view_sx = ox - sview->x;
460 double view_sy = oy - sview->y;
461
462 double _sx, _sy;
463 struct wlr_surface *_surface = NULL;
464 switch (sview->type) {
465 case SWAY_VIEW_XWAYLAND:
466 _surface = wlr_surface_surface_at(sview->surface,
467 view_sx, view_sy, &_sx, &_sy);
468 break;
469 case SWAY_VIEW_XDG_SHELL_V6:
470 // the top left corner of the sway container is the
471 // coordinate of the top left corner of the window geometry
472 view_sx += sview->wlr_xdg_surface_v6->geometry.x;
473 view_sy += sview->wlr_xdg_surface_v6->geometry.y;
474
475 _surface = wlr_xdg_surface_v6_surface_at(
476 sview->wlr_xdg_surface_v6,
477 view_sx, view_sy, &_sx, &_sy);
478 break;
479 case SWAY_VIEW_XDG_SHELL:
480 // the top left corner of the sway container is the
481 // coordinate of the top left corner of the window geometry
482 view_sx += sview->wlr_xdg_surface->geometry.x;
483 view_sy += sview->wlr_xdg_surface->geometry.y;
484
485 _surface = wlr_xdg_surface_surface_at(
486 sview->wlr_xdg_surface,
487 view_sx, view_sy, &_sx, &_sy);
488 break;
489 }
490 if (_surface) {
491 *sx = _sx;
492 *sy = _sy;
493 *surface = _surface;
494 }
495 return swayc;
496}
497
498/**
499 * container_at for a container with layout L_TABBED.
500 */
501static struct sway_container *container_at_tabbed(struct sway_container *parent,
502 double ox, double oy,
503 struct wlr_surface **surface, double *sx, double *sy) {
504 if (oy < parent->y || oy > parent->y + parent->height) {
460 return NULL; 505 return NULL;
461 } 506 }
507 struct sway_seat *seat = input_manager_current_seat(input_manager);
462 508
463 list_add(queue, parent); 509 // Tab titles
510 int title_height = config->border_thickness * 2 + config->font_height;
511 if (oy < parent->y + title_height) {
512 int tab_width = parent->width / parent->children->length;
513 int child_index = (ox - parent->x) / tab_width;
514 if (child_index >= parent->children->length) {
515 child_index = parent->children->length - 1;
516 }
517 struct sway_container *child = parent->children->items[child_index];
518 return seat_get_focus_inactive(seat, child);
519 }
464 520
465 struct sway_container *swayc = NULL; 521 // Surfaces
466 while (queue->length) { 522 struct sway_container *current = seat_get_focus_inactive(seat, parent);
467 swayc = queue->items[0]; 523 while (current->parent != parent) {
468 list_del(queue, 0); 524 current = current->parent;
469 if (swayc->type == C_VIEW) { 525 }
470 struct sway_view *sview = swayc->sway_view; 526
471 struct sway_container *soutput = container_parent(swayc, C_OUTPUT); 527 return container_at(current, ox, oy, surface, sx, sy);
472 struct wlr_box *output_box = 528}
473 wlr_output_layout_get_box( 529
474 root_container.sway_root->output_layout, 530/**
475 soutput->sway_output->wlr_output); 531 * container_at for a container with layout L_STACKED.
476 double ox = lx - output_box->x; 532 */
477 double oy = ly - output_box->y; 533static struct sway_container *container_at_stacked(
478 double view_sx = ox - sview->x; 534 struct sway_container *parent, double ox, double oy,
479 double view_sy = oy - sview->y; 535 struct wlr_surface **surface, double *sx, double *sy) {
480 536 // TODO
481 double _sx, _sy; 537 return NULL;
482 struct wlr_surface *_surface; 538}
483 switch (sview->type) { 539
484 case SWAY_VIEW_XWAYLAND: 540/**
485 _surface = wlr_surface_surface_at(sview->surface, 541 * container_at for a container with layout L_HORIZ or L_VERT.
486 view_sx, view_sy, &_sx, &_sy); 542 */
487 break; 543static struct sway_container *container_at_linear(struct sway_container *parent,
488 case SWAY_VIEW_XDG_SHELL_V6: 544 double ox, double oy,
489 // the top left corner of the sway container is the 545 struct wlr_surface **surface, double *sx, double *sy) {
490 // coordinate of the top left corner of the window geometry 546 for (int i = 0; i < parent->children->length; ++i) {
491 view_sx += sview->wlr_xdg_surface_v6->geometry.x; 547 struct sway_container *child = parent->children->items[i];
492 view_sy += sview->wlr_xdg_surface_v6->geometry.y; 548 struct wlr_box box = {
493 549 .x = child->x,
494 _surface = wlr_xdg_surface_v6_surface_at( 550 .y = child->y,
495 sview->wlr_xdg_surface_v6, 551 .width = child->width,
496 view_sx, view_sy, &_sx, &_sy); 552 .height = child->height,
497 break; 553 };
498 case SWAY_VIEW_XDG_SHELL: 554 if (wlr_box_contains_point(&box, ox, oy)) {
499 // the top left corner of the sway container is the 555 return container_at(child, ox, oy, surface, sx, sy);
500 // coordinate of the top left corner of the window geometry
501 view_sx += sview->wlr_xdg_surface->geometry.x;
502 view_sy += sview->wlr_xdg_surface->geometry.y;
503
504 _surface = wlr_xdg_surface_surface_at(
505 sview->wlr_xdg_surface,
506 view_sx, view_sy, &_sx, &_sy);
507 break;
508 }
509 if (_surface) {
510 *sx = _sx;
511 *sy = _sy;
512 *surface = _surface;
513 return swayc;
514 }
515 // Check the view's decorations
516 struct wlr_box swayc_box = {
517 .x = swayc->x,
518 .y = swayc->y,
519 .width = swayc->width,
520 .height = swayc->height,
521 };
522 if (wlr_box_contains_point(&swayc_box, ox, oy)) {
523 return swayc;
524 }
525 } else {
526 list_cat(queue, swayc->children);
527 } 556 }
528 } 557 }
558 return NULL;
559}
560
561struct sway_container *container_at(struct sway_container *parent,
562 double ox, double oy,
563 struct wlr_surface **surface, double *sx, double *sy) {
564 if (!sway_assert(parent->type >= C_WORKSPACE,
565 "Expected workspace or deeper")) {
566 return NULL;
567 }
568 if (parent->type == C_VIEW) {
569 return container_at_view(parent, ox, oy, surface, sx, sy);
570 }
571 if (!parent->children->length) {
572 return NULL;
573 }
574
575 switch (parent->layout) {
576 case L_HORIZ:
577 case L_VERT:
578 return container_at_linear(parent, ox, oy, surface, sx, sy);
579 case L_TABBED:
580 return container_at_tabbed(parent, ox, oy, surface, sx, sy);
581 case L_STACKED:
582 return container_at_stacked(parent, ox, oy, surface, sx, sy);
583 case L_FLOATING:
584 return NULL; // TODO
585 case L_NONE:
586 return NULL;
587 }
529 588
530 return NULL; 589 return NULL;
531} 590}
@@ -699,18 +758,82 @@ void container_calculate_title_height(struct sway_container *container) {
699 container->title_height = height; 758 container->title_height = height;
700} 759}
701 760
761/**
762 * Calculate and return the length of the concatenated child titles.
763 * An example concatenated title is: V[Terminal, Firefox]
764 * If buffer is not NULL, also populate the buffer with the concatenated title.
765 */
766static size_t concatenate_child_titles(struct sway_container *parent,
767 char *buffer) {
768 size_t len = 2; // V[
769 if (buffer) {
770 switch (parent->layout) {
771 case L_VERT:
772 strcpy(buffer, "V[");
773 break;
774 case L_HORIZ:
775 strcpy(buffer, "H[");
776 break;
777 case L_TABBED:
778 strcpy(buffer, "T[");
779 break;
780 case L_STACKED:
781 strcpy(buffer, "S[");
782 break;
783 case L_FLOATING:
784 strcpy(buffer, "F[");
785 break;
786 case L_NONE:
787 strcpy(buffer, "?[");
788 break;
789 }
790 }
791
792 for (int i = 0; i < parent->children->length; ++i) {
793 if (i != 0) {
794 len += 2;
795 if (buffer) {
796 strcat(buffer, ", ");
797 }
798 }
799 struct sway_container *child = parent->children->items[i];
800 if (child->name) {
801 len += strlen(child->name);
802 if (buffer) {
803 strcat(buffer, child->name);
804 }
805 } else {
806 len += 6;
807 if (buffer) {
808 strcat(buffer, "(null)");
809 }
810 }
811 }
812
813 len += 1;
814 if (buffer) {
815 strcat(buffer, "]");
816 }
817 return len;
818}
819
702void container_notify_child_title_changed(struct sway_container *container) { 820void container_notify_child_title_changed(struct sway_container *container) {
703 if (!container || container->type != C_CONTAINER) { 821 if (!container || container->type != C_CONTAINER) {
704 return; 822 return;
705 } 823 }
706 if (container->layout != L_TABBED && container->layout != L_STACKED) {
707 return;
708 }
709 if (container->formatted_title) { 824 if (container->formatted_title) {
710 free(container->formatted_title); 825 free(container->formatted_title);
711 } 826 }
712 // TODO: iterate children and concatenate their titles 827
713 container->formatted_title = strdup(""); 828 size_t len = concatenate_child_titles(container, NULL);
829 char *buffer = calloc(len + 1, sizeof(char));
830 if (!sway_assert(buffer, "Unable to allocate title string")) {
831 return;
832 }
833 concatenate_child_titles(container, buffer);
834
835 container->name = buffer;
836 container->formatted_title = buffer;
714 container_calculate_title_height(container); 837 container_calculate_title_height(container);
715 container_update_title_textures(container); 838 container_update_title_textures(container);
716 container_notify_child_title_changed(container->parent); 839 container_notify_child_title_changed(container->parent);