summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/stringop.c14
-rw-r--r--include/stringop.h5
-rw-r--r--include/sway/tree/container.h6
-rw-r--r--sway/commands/layout.c1
-rw-r--r--sway/tree/container.c90
-rw-r--r--sway/tree/layout.c32
-rw-r--r--sway/tree/view.c34
7 files changed, 94 insertions, 88 deletions
diff --git a/common/stringop.c b/common/stringop.c
index 4a37543d..d9ae9925 100644
--- a/common/stringop.c
+++ b/common/stringop.c
@@ -55,6 +55,20 @@ void strip_quotes(char *str) {
55 *end = '\0'; 55 *end = '\0';
56} 56}
57 57
58char *lenient_strcat(char *dest, const char *src) {
59 if (dest && src) {
60 return strcat(dest, src);
61 }
62 return dest;
63}
64
65char *lenient_strncat(char *dest, const char *src, size_t len) {
66 if (dest && src) {
67 return strncat(dest, src, len);
68 }
69 return dest;
70}
71
58// strcmp that also handles null pointers. 72// strcmp that also handles null pointers.
59int lenient_strcmp(char *a, char *b) { 73int lenient_strcmp(char *a, char *b) {
60 if (a == b) { 74 if (a == b) {
diff --git a/include/stringop.h b/include/stringop.h
index 7c29a745..e7f58011 100644
--- a/include/stringop.h
+++ b/include/stringop.h
@@ -1,5 +1,6 @@
1#ifndef _SWAY_STRINGOP_H 1#ifndef _SWAY_STRINGOP_H
2#define _SWAY_STRINGOP_H 2#define _SWAY_STRINGOP_H
3#include <stdlib.h>
3#include "list.h" 4#include "list.h"
4 5
5#if !HAVE_DECL_SETENV 6#if !HAVE_DECL_SETENV
@@ -14,6 +15,10 @@ char *strip_whitespace(char *str);
14char *strip_comments(char *str); 15char *strip_comments(char *str);
15void strip_quotes(char *str); 16void strip_quotes(char *str);
16 17
18// strcat that does nothing if dest or src is NULL
19char *lenient_strcat(char *dest, const char *src);
20char *lenient_strncat(char *dest, const char *src, size_t len);
21
17// strcmp that also handles null pointers. 22// strcmp that also handles null pointers.
18int lenient_strcmp(char *a, char *b); 23int lenient_strcmp(char *a, char *b);
19 24
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 493c70e2..a5f591ce 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -216,7 +216,11 @@ void container_update_title_textures(struct sway_container *container);
216 */ 216 */
217void container_calculate_title_height(struct sway_container *container); 217void container_calculate_title_height(struct sway_container *container);
218 218
219void container_notify_child_title_changed(struct sway_container *container); 219/**
220 * Notify a container that a tree modification has changed in its children,
221 * so the container can update its tree representation.
222 */
223void container_notify_subtree_changed(struct sway_container *container);
220 224
221/** 225/**
222 * Return the height of a regular title bar. 226 * Return the height of a regular title bar.
diff --git a/sway/commands/layout.c b/sway/commands/layout.c
index 58728f16..6b44b001 100644
--- a/sway/commands/layout.c
+++ b/sway/commands/layout.c
@@ -52,6 +52,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
52 } 52 }
53 } 53 }
54 54
55 container_notify_subtree_changed(parent);
55 arrange_children_of(parent); 56 arrange_children_of(parent);
56 57
57 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 58 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 9cf18f61..f29a9adc 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -21,6 +21,7 @@
21#include "sway/tree/view.h" 21#include "sway/tree/view.h"
22#include "sway/tree/workspace.h" 22#include "sway/tree/workspace.h"
23#include "log.h" 23#include "log.h"
24#include "stringop.h"
24 25
25static list_t *bfs_queue; 26static list_t *bfs_queue;
26 27
@@ -774,42 +775,36 @@ void container_calculate_title_height(struct sway_container *container) {
774} 775}
775 776
776/** 777/**
777 * Calculate and return the length of the concatenated child titles. 778 * Calculate and return the length of the tree representation.
778 * An example concatenated title is: V[Terminal, Firefox] 779 * An example tree representation is: V[Terminal, Firefox]
779 * If buffer is not NULL, also populate the buffer with the concatenated title. 780 * If buffer is not NULL, also populate the buffer with the representation.
780 */ 781 */
781static size_t concatenate_child_titles(struct sway_container *parent, 782static size_t get_tree_representation(struct sway_container *parent, char *buffer) {
782 char *buffer) { 783 size_t len = 2;
783 size_t len = 2; // V[ 784 switch (parent->layout) {
784 if (buffer) { 785 case L_VERT:
785 switch (parent->layout) { 786 lenient_strcat(buffer, "V[");
786 case L_VERT: 787 break;
787 strcpy(buffer, "V["); 788 case L_HORIZ:
788 break; 789 lenient_strcat(buffer, "H[");
789 case L_HORIZ: 790 break;
790 strcpy(buffer, "H["); 791 case L_TABBED:
791 break; 792 lenient_strcat(buffer, "T[");
792 case L_TABBED: 793 break;
793 strcpy(buffer, "T["); 794 case L_STACKED:
794 break; 795 lenient_strcat(buffer, "S[");
795 case L_STACKED: 796 break;
796 strcpy(buffer, "S["); 797 case L_FLOATING:
797 break; 798 lenient_strcat(buffer, "F[");
798 case L_FLOATING: 799 break;
799 strcpy(buffer, "F["); 800 case L_NONE:
800 break; 801 lenient_strcat(buffer, "D[");
801 case L_NONE: 802 break;
802 strcpy(buffer, "D[");
803 break;
804 }
805 } 803 }
806
807 for (int i = 0; i < parent->children->length; ++i) { 804 for (int i = 0; i < parent->children->length; ++i) {
808 if (i != 0) { 805 if (i != 0) {
809 len += 1; 806 ++len;
810 if (buffer) { 807 lenient_strcat(buffer, " ");
811 strcat(buffer, " ");
812 }
813 } 808 }
814 struct sway_container *child = parent->children->items[i]; 809 struct sway_container *child = parent->children->items[i];
815 const char *identifier = NULL; 810 const char *identifier = NULL;
@@ -819,48 +814,39 @@ static size_t concatenate_child_titles(struct sway_container *parent,
819 identifier = view_get_app_id(child->sway_view); 814 identifier = view_get_app_id(child->sway_view);
820 } 815 }
821 } else { 816 } else {
822 identifier = child->name; 817 identifier = child->formatted_title;
823 } 818 }
824 if (identifier) { 819 if (identifier) {
825 len += strlen(identifier); 820 len += strlen(identifier);
826 if (buffer) { 821 lenient_strcat(buffer, identifier);
827 strcat(buffer, identifier);
828 }
829 } else { 822 } else {
830 len += 6; 823 len += 6;
831 if (buffer) { 824 lenient_strcat(buffer, "(null)");
832 strcat(buffer, "(null)");
833 }
834 } 825 }
835 } 826 }
836 827 ++len;
837 len += 1; 828 lenient_strcat(buffer, "]");
838 if (buffer) {
839 strcat(buffer, "]");
840 }
841 return len; 829 return len;
842} 830}
843 831
844void container_notify_child_title_changed(struct sway_container *container) { 832void container_notify_subtree_changed(struct sway_container *container) {
845 if (!container || container->type != C_CONTAINER) { 833 if (!container || container->type != C_CONTAINER) {
846 return; 834 return;
847 } 835 }
848 if (container->formatted_title) { 836 free(container->formatted_title);
849 free(container->formatted_title); 837 container->formatted_title = NULL;
850 }
851 838
852 size_t len = concatenate_child_titles(container, NULL); 839 size_t len = get_tree_representation(container, NULL);
853 char *buffer = calloc(len + 1, sizeof(char)); 840 char *buffer = calloc(len + 1, sizeof(char));
854 if (!sway_assert(buffer, "Unable to allocate title string")) { 841 if (!sway_assert(buffer, "Unable to allocate title string")) {
855 return; 842 return;
856 } 843 }
857 concatenate_child_titles(container, buffer); 844 get_tree_representation(container, buffer);
858 845
859 container->name = buffer;
860 container->formatted_title = buffer; 846 container->formatted_title = buffer;
861 container_calculate_title_height(container); 847 container_calculate_title_height(container);
862 container_update_title_textures(container); 848 container_update_title_textures(container);
863 container_notify_child_title_changed(container->parent); 849 container_notify_subtree_changed(container->parent);
864} 850}
865 851
866size_t container_titlebar_height() { 852size_t container_titlebar_height() {
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 91759f7b..21cec529 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -149,7 +149,7 @@ struct sway_container *container_remove_child(struct sway_container *child) {
149 } 149 }
150 } 150 }
151 child->parent = NULL; 151 child->parent = NULL;
152 container_notify_child_title_changed(parent); 152 container_notify_subtree_changed(parent);
153 153
154 return parent; 154 return parent;
155} 155}
@@ -184,8 +184,8 @@ void container_move_to(struct sway_container *container,
184 container_sort_workspaces(new_parent); 184 container_sort_workspaces(new_parent);
185 seat_set_focus(seat, new_parent); 185 seat_set_focus(seat, new_parent);
186 } 186 }
187 container_notify_child_title_changed(old_parent); 187 container_notify_subtree_changed(old_parent);
188 container_notify_child_title_changed(new_parent); 188 container_notify_subtree_changed(new_parent);
189 if (old_parent) { 189 if (old_parent) {
190 if (old_parent->type == C_OUTPUT) { 190 if (old_parent->type == C_OUTPUT) {
191 arrange_output(old_parent); 191 arrange_output(old_parent);
@@ -327,9 +327,11 @@ void container_move(struct sway_container *container,
327 current = container_parent(container, C_OUTPUT); 327 current = container_parent(container, C_OUTPUT);
328 } 328 }
329 329
330 if (parent != container_flatten(parent)) { 330 struct sway_container *new_parent = container_flatten(parent);
331 if (new_parent != parent) {
331 // Special case: we were the last one in this container, so flatten it 332 // Special case: we were the last one in this container, so flatten it
332 // and leave 333 // and leave
334 arrange_children_of(new_parent);
333 update_debug_tree(); 335 update_debug_tree();
334 return; 336 return;
335 } 337 }
@@ -497,8 +499,8 @@ void container_move(struct sway_container *container,
497 } 499 }
498 } 500 }
499 501
500 container_notify_child_title_changed(old_parent); 502 container_notify_subtree_changed(old_parent);
501 container_notify_child_title_changed(container->parent); 503 container_notify_subtree_changed(container->parent);
502 504
503 if (old_parent) { 505 if (old_parent) {
504 seat_set_focus(config->handler_context.seat, old_parent); 506 seat_set_focus(config->handler_context.seat, old_parent);
@@ -586,11 +588,19 @@ static struct sway_container *get_swayc_in_output_direction(
586 if (ws->children->length > 0) { 588 if (ws->children->length > 0) {
587 switch (dir) { 589 switch (dir) {
588 case MOVE_LEFT: 590 case MOVE_LEFT:
589 // get most right child of new output 591 if (ws->layout == L_HORIZ || ws->layout == L_TABBED) {
590 return ws->children->items[ws->children->length-1]; 592 // get most right child of new output
593 return ws->children->items[ws->children->length-1];
594 } else {
595 return seat_get_focus_inactive(seat, ws);
596 }
591 case MOVE_RIGHT: 597 case MOVE_RIGHT:
592 // get most left child of new output 598 if (ws->layout == L_HORIZ || ws->layout == L_TABBED) {
593 return ws->children->items[0]; 599 // get most left child of new output
600 return ws->children->items[0];
601 } else {
602 return seat_get_focus_inactive(seat, ws);
603 }
594 case MOVE_UP: 604 case MOVE_UP:
595 case MOVE_DOWN: { 605 case MOVE_DOWN: {
596 struct sway_container *focused = 606 struct sway_container *focused =
@@ -847,7 +857,7 @@ struct sway_container *container_split(struct sway_container *child,
847 container_add_child(cont, child); 857 container_add_child(cont, child);
848 } 858 }
849 859
850 container_notify_child_title_changed(cont); 860 container_notify_subtree_changed(cont);
851 861
852 return cont; 862 return cont;
853} 863}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 349a16a4..812d7740 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -17,6 +17,7 @@
17#include "sway/tree/workspace.h" 17#include "sway/tree/workspace.h"
18#include "sway/config.h" 18#include "sway/config.h"
19#include "pango.h" 19#include "pango.h"
20#include "stringop.h"
20 21
21void view_init(struct sway_view *view, enum sway_view_type type, 22void view_init(struct sway_view *view, enum sway_view_type type,
22 const struct sway_view_impl *impl) { 23 const struct sway_view_impl *impl) {
@@ -474,7 +475,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
474 } 475 }
475 476
476 view_update_title(view, false); 477 view_update_title(view, false);
477 container_notify_child_title_changed(view->swayc->parent); 478 container_notify_subtree_changed(view->swayc->parent);
478 view_execute_criteria(view); 479 view_execute_criteria(view);
479 480
480 container_damage_whole(cont); 481 container_damage_whole(cont);
@@ -665,49 +666,35 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) {
665 char *format = view->title_format; 666 char *format = view->title_format;
666 char *next = strchr(format, '%'); 667 char *next = strchr(format, '%');
667 while (next) { 668 while (next) {
668 if (buffer) { 669 // Copy everything up to the %
669 // Copy everything up to the % 670 lenient_strncat(buffer, format, next - format);
670 strncat(buffer, format, next - format);
671 }
672 len += next - format; 671 len += next - format;
673 format = next; 672 format = next;
674 673
675 if (strncmp(next, "%title", 6) == 0) { 674 if (strncmp(next, "%title", 6) == 0) {
676 if (buffer && title) { 675 lenient_strcat(buffer, title);
677 strcat(buffer, title);
678 }
679 len += title_len; 676 len += title_len;
680 format += 6; 677 format += 6;
681 } else if (strncmp(next, "%class", 6) == 0) { 678 } else if (strncmp(next, "%class", 6) == 0) {
682 if (buffer && class) { 679 lenient_strcat(buffer, class);
683 strcat(buffer, class);
684 }
685 len += class_len; 680 len += class_len;
686 format += 6; 681 format += 6;
687 } else if (strncmp(next, "%instance", 9) == 0) { 682 } else if (strncmp(next, "%instance", 9) == 0) {
688 if (buffer && instance) { 683 lenient_strcat(buffer, instance);
689 strcat(buffer, instance);
690 }
691 len += instance_len; 684 len += instance_len;
692 format += 9; 685 format += 9;
693 } else if (strncmp(next, "%shell", 6) == 0) { 686 } else if (strncmp(next, "%shell", 6) == 0) {
694 if (buffer) { 687 lenient_strcat(buffer, shell);
695 strcat(buffer, shell);
696 }
697 len += shell_len; 688 len += shell_len;
698 format += 6; 689 format += 6;
699 } else { 690 } else {
700 if (buffer) { 691 lenient_strcat(buffer, "%");
701 strcat(buffer, "%");
702 }
703 ++format; 692 ++format;
704 ++len; 693 ++len;
705 } 694 }
706 next = strchr(format, '%'); 695 next = strchr(format, '%');
707 } 696 }
708 if (buffer) { 697 lenient_strcat(buffer, format);
709 strcat(buffer, format);
710 }
711 len += strlen(format); 698 len += strlen(format);
712 699
713 return len; 700 return len;
@@ -763,7 +750,6 @@ void view_update_title(struct sway_view *view, bool force) {
763 } 750 }
764 container_calculate_title_height(view->swayc); 751 container_calculate_title_height(view->swayc);
765 container_update_title_textures(view->swayc); 752 container_update_title_textures(view->swayc);
766 container_notify_child_title_changed(view->swayc->parent);
767 config_update_font_height(false); 753 config_update_font_height(false);
768} 754}
769 755