diff options
-rw-r--r-- | common/stringop.c | 14 | ||||
-rw-r--r-- | include/stringop.h | 5 | ||||
-rw-r--r-- | include/sway/tree/container.h | 6 | ||||
-rw-r--r-- | sway/commands/layout.c | 1 | ||||
-rw-r--r-- | sway/tree/container.c | 90 | ||||
-rw-r--r-- | sway/tree/layout.c | 12 | ||||
-rw-r--r-- | sway/tree/view.c | 34 |
7 files changed, 79 insertions, 83 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 | ||
58 | char *lenient_strcat(char *dest, const char *src) { | ||
59 | if (dest && src) { | ||
60 | return strcat(dest, src); | ||
61 | } | ||
62 | return dest; | ||
63 | } | ||
64 | |||
65 | char *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. |
59 | int lenient_strcmp(char *a, char *b) { | 73 | int 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); | |||
14 | char *strip_comments(char *str); | 15 | char *strip_comments(char *str); |
15 | void strip_quotes(char *str); | 16 | void strip_quotes(char *str); |
16 | 17 | ||
18 | // strcat that does nothing if dest or src is NULL | ||
19 | char *lenient_strcat(char *dest, const char *src); | ||
20 | char *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. |
18 | int lenient_strcmp(char *a, char *b); | 23 | int 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 | */ |
217 | void container_calculate_title_height(struct sway_container *container); | 217 | void container_calculate_title_height(struct sway_container *container); |
218 | 218 | ||
219 | void 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 | */ | ||
223 | void 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 | ||
25 | static list_t *bfs_queue; | 26 | static 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 | */ |
781 | static size_t concatenate_child_titles(struct sway_container *parent, | 782 | static 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 | ||
844 | void container_notify_child_title_changed(struct sway_container *container) { | 832 | void 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 | ||
866 | size_t container_titlebar_height() { | 852 | size_t container_titlebar_height() { |
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 91759f7b..edc24deb 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); |
@@ -497,8 +497,8 @@ void container_move(struct sway_container *container, | |||
497 | } | 497 | } |
498 | } | 498 | } |
499 | 499 | ||
500 | container_notify_child_title_changed(old_parent); | 500 | container_notify_subtree_changed(old_parent); |
501 | container_notify_child_title_changed(container->parent); | 501 | container_notify_subtree_changed(container->parent); |
502 | 502 | ||
503 | if (old_parent) { | 503 | if (old_parent) { |
504 | seat_set_focus(config->handler_context.seat, old_parent); | 504 | seat_set_focus(config->handler_context.seat, old_parent); |
@@ -847,7 +847,7 @@ struct sway_container *container_split(struct sway_container *child, | |||
847 | container_add_child(cont, child); | 847 | container_add_child(cont, child); |
848 | } | 848 | } |
849 | 849 | ||
850 | container_notify_child_title_changed(cont); | 850 | container_notify_subtree_changed(cont); |
851 | 851 | ||
852 | return cont; | 852 | return cont; |
853 | } | 853 | } |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 07157818..2f718a73 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 | ||
21 | void view_init(struct sway_view *view, enum sway_view_type type, | 22 | void 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) { |
@@ -470,7 +471,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
470 | input_manager_set_focus(input_manager, cont); | 471 | input_manager_set_focus(input_manager, cont); |
471 | 472 | ||
472 | view_update_title(view, false); | 473 | view_update_title(view, false); |
473 | container_notify_child_title_changed(view->swayc->parent); | 474 | container_notify_subtree_changed(view->swayc->parent); |
474 | view_execute_criteria(view); | 475 | view_execute_criteria(view); |
475 | 476 | ||
476 | container_damage_whole(cont); | 477 | container_damage_whole(cont); |
@@ -661,49 +662,35 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) { | |||
661 | char *format = view->title_format; | 662 | char *format = view->title_format; |
662 | char *next = strchr(format, '%'); | 663 | char *next = strchr(format, '%'); |
663 | while (next) { | 664 | while (next) { |
664 | if (buffer) { | 665 | // Copy everything up to the % |
665 | // Copy everything up to the % | 666 | lenient_strncat(buffer, format, next - format); |
666 | strncat(buffer, format, next - format); | ||
667 | } | ||
668 | len += next - format; | 667 | len += next - format; |
669 | format = next; | 668 | format = next; |
670 | 669 | ||
671 | if (strncmp(next, "%title", 6) == 0) { | 670 | if (strncmp(next, "%title", 6) == 0) { |
672 | if (buffer && title) { | 671 | lenient_strcat(buffer, title); |
673 | strcat(buffer, title); | ||
674 | } | ||
675 | len += title_len; | 672 | len += title_len; |
676 | format += 6; | 673 | format += 6; |
677 | } else if (strncmp(next, "%class", 6) == 0) { | 674 | } else if (strncmp(next, "%class", 6) == 0) { |
678 | if (buffer && class) { | 675 | lenient_strcat(buffer, class); |
679 | strcat(buffer, class); | ||
680 | } | ||
681 | len += class_len; | 676 | len += class_len; |
682 | format += 6; | 677 | format += 6; |
683 | } else if (strncmp(next, "%instance", 9) == 0) { | 678 | } else if (strncmp(next, "%instance", 9) == 0) { |
684 | if (buffer && instance) { | 679 | lenient_strcat(buffer, instance); |
685 | strcat(buffer, instance); | ||
686 | } | ||
687 | len += instance_len; | 680 | len += instance_len; |
688 | format += 9; | 681 | format += 9; |
689 | } else if (strncmp(next, "%shell", 6) == 0) { | 682 | } else if (strncmp(next, "%shell", 6) == 0) { |
690 | if (buffer) { | 683 | lenient_strcat(buffer, shell); |
691 | strcat(buffer, shell); | ||
692 | } | ||
693 | len += shell_len; | 684 | len += shell_len; |
694 | format += 6; | 685 | format += 6; |
695 | } else { | 686 | } else { |
696 | if (buffer) { | 687 | lenient_strcat(buffer, "%"); |
697 | strcat(buffer, "%"); | ||
698 | } | ||
699 | ++format; | 688 | ++format; |
700 | ++len; | 689 | ++len; |
701 | } | 690 | } |
702 | next = strchr(format, '%'); | 691 | next = strchr(format, '%'); |
703 | } | 692 | } |
704 | if (buffer) { | 693 | lenient_strcat(buffer, format); |
705 | strcat(buffer, format); | ||
706 | } | ||
707 | len += strlen(format); | 694 | len += strlen(format); |
708 | 695 | ||
709 | return len; | 696 | return len; |
@@ -759,7 +746,6 @@ void view_update_title(struct sway_view *view, bool force) { | |||
759 | } | 746 | } |
760 | container_calculate_title_height(view->swayc); | 747 | container_calculate_title_height(view->swayc); |
761 | container_update_title_textures(view->swayc); | 748 | container_update_title_textures(view->swayc); |
762 | container_notify_child_title_changed(view->swayc->parent); | ||
763 | config_update_font_height(false); | 749 | config_update_font_height(false); |
764 | } | 750 | } |
765 | 751 | ||