aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-05-25 21:07:59 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-05-25 21:07:59 +1000
commitdb38b9bbf3cce4083c538209a7ce5ef1a1cf5f3f (patch)
tree3ee9f0c2bf76907b2854bf6ba2be8ab124b74fb9
parent3c77f066a532efd3df0f2072d02fa4353b4a4511 (diff)
Clean up container title functions
* Add and use lenient_strcat and lenient_strncat functions * Rename `concatenate_child_titles` function as that's no longer what it does * Rename `container_notify_child_title_changed` because we only need to notify that the tree structure has changed, not titles * Don't notify parents when a child changes its title * Update ancestor titles when changing a container's layout * Eg. create nested tabs and change the inner container to stacking * No need to store tree presentation in both container->name and formatted_title
-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.c12
-rw-r--r--sway/tree/view.c34
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) {
*end = '\0';
}
+char *lenient_strcat(char *dest, const char *src) {
+ if (dest && src) {
+ return strcat(dest, src);
+ }
+ return dest;
+}
+
+char *lenient_strncat(char *dest, const char *src, size_t len) {
+ if (dest && src) {
+ return strncat(dest, src, len);
+ }
+ return dest;
+}
+
// strcmp that also handles null pointers.
int lenient_strcmp(char *a, char *b) {
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 @@
#ifndef _SWAY_STRINGOP_H
#define _SWAY_STRINGOP_H
+#include <stdlib.h>
#include "list.h"
#if !HAVE_DECL_SETENV
@@ -14,6 +15,10 @@ char *strip_whitespace(char *str);
char *strip_comments(char *str);
void strip_quotes(char *str);
+// strcat that does nothing if dest or src is NULL
+char *lenient_strcat(char *dest, const char *src);
+char *lenient_strncat(char *dest, const char *src, size_t len);
+
// strcmp that also handles null pointers.
int lenient_strcmp(char *a, char *b);
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);
*/
void container_calculate_title_height(struct sway_container *container);
-void container_notify_child_title_changed(struct sway_container *container);
+/**
+ * Notify a container that a tree modification has changed in its children,
+ * so the container can update its tree representation.
+ */
+void container_notify_subtree_changed(struct sway_container *container);
/**
* 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) {
}
}
+ container_notify_subtree_changed(parent);
arrange_children_of(parent);
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 @@
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "log.h"
+#include "stringop.h"
static list_t *bfs_queue;
@@ -774,42 +775,36 @@ void container_calculate_title_height(struct sway_container *container) {
}
/**
- * Calculate and return the length of the concatenated child titles.
- * An example concatenated title is: V[Terminal, Firefox]
- * If buffer is not NULL, also populate the buffer with the concatenated title.
+ * Calculate and return the length of the tree representation.
+ * An example tree representation is: V[Terminal, Firefox]
+ * If buffer is not NULL, also populate the buffer with the representation.
*/
-static size_t concatenate_child_titles(struct sway_container *parent,
- char *buffer) {
- size_t len = 2; // V[
- if (buffer) {
- switch (parent->layout) {
- case L_VERT:
- strcpy(buffer, "V[");
- break;
- case L_HORIZ:
- strcpy(buffer, "H[");
- break;
- case L_TABBED:
- strcpy(buffer, "T[");
- break;
- case L_STACKED:
- strcpy(buffer, "S[");
- break;
- case L_FLOATING:
- strcpy(buffer, "F[");
- break;
- case L_NONE:
- strcpy(buffer, "D[");
- break;
- }
+static size_t get_tree_representation(struct sway_container *parent, char *buffer) {
+ size_t len = 2;
+ switch (parent->layout) {
+ case L_VERT:
+ lenient_strcat(buffer, "V[");
+ break;
+ case L_HORIZ:
+ lenient_strcat(buffer, "H[");
+ break;
+ case L_TABBED:
+ lenient_strcat(buffer, "T[");
+ break;
+ case L_STACKED:
+ lenient_strcat(buffer, "S[");
+ break;
+ case L_FLOATING:
+ lenient_strcat(buffer, "F[");
+ break;
+ case L_NONE:
+ lenient_strcat(buffer, "D[");
+ break;
}
-
for (int i = 0; i < parent->children->length; ++i) {
if (i != 0) {
- len += 1;
- if (buffer) {
- strcat(buffer, " ");
- }
+ ++len;
+ lenient_strcat(buffer, " ");
}
struct sway_container *child = parent->children->items[i];
const char *identifier = NULL;
@@ -819,48 +814,39 @@ static size_t concatenate_child_titles(struct sway_container *parent,
identifier = view_get_app_id(child->sway_view);
}
} else {
- identifier = child->name;
+ identifier = child->formatted_title;
}
if (identifier) {
len += strlen(identifier);
- if (buffer) {
- strcat(buffer, identifier);
- }
+ lenient_strcat(buffer, identifier);
} else {
len += 6;
- if (buffer) {
- strcat(buffer, "(null)");
- }
+ lenient_strcat(buffer, "(null)");
}
}
-
- len += 1;
- if (buffer) {
- strcat(buffer, "]");
- }
+ ++len;
+ lenient_strcat(buffer, "]");
return len;
}
-void container_notify_child_title_changed(struct sway_container *container) {
+void container_notify_subtree_changed(struct sway_container *container) {
if (!container || container->type != C_CONTAINER) {
return;
}
- if (container->formatted_title) {
- free(container->formatted_title);
- }
+ free(container->formatted_title);
+ container->formatted_title = NULL;
- size_t len = concatenate_child_titles(container, NULL);
+ size_t len = get_tree_representation(container, NULL);
char *buffer = calloc(len + 1, sizeof(char));
if (!sway_assert(buffer, "Unable to allocate title string")) {
return;
}
- concatenate_child_titles(container, buffer);
+ get_tree_representation(container, buffer);
- container->name = buffer;
container->formatted_title = buffer;
container_calculate_title_height(container);
container_update_title_textures(container);
- container_notify_child_title_changed(container->parent);
+ container_notify_subtree_changed(container->parent);
}
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) {
}
}
child->parent = NULL;
- container_notify_child_title_changed(parent);
+ container_notify_subtree_changed(parent);
return parent;
}
@@ -184,8 +184,8 @@ void container_move_to(struct sway_container *container,
container_sort_workspaces(new_parent);
seat_set_focus(seat, new_parent);
}
- container_notify_child_title_changed(old_parent);
- container_notify_child_title_changed(new_parent);
+ container_notify_subtree_changed(old_parent);
+ container_notify_subtree_changed(new_parent);
if (old_parent) {
if (old_parent->type == C_OUTPUT) {
arrange_output(old_parent);
@@ -497,8 +497,8 @@ void container_move(struct sway_container *container,
}
}
- container_notify_child_title_changed(old_parent);
- container_notify_child_title_changed(container->parent);
+ container_notify_subtree_changed(old_parent);
+ container_notify_subtree_changed(container->parent);
if (old_parent) {
seat_set_focus(config->handler_context.seat, old_parent);
@@ -847,7 +847,7 @@ struct sway_container *container_split(struct sway_container *child,
container_add_child(cont, child);
}
- container_notify_child_title_changed(cont);
+ container_notify_subtree_changed(cont);
return cont;
}
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 @@
#include "sway/tree/workspace.h"
#include "sway/config.h"
#include "pango.h"
+#include "stringop.h"
void view_init(struct sway_view *view, enum sway_view_type type,
const struct sway_view_impl *impl) {
@@ -470,7 +471,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
input_manager_set_focus(input_manager, cont);
view_update_title(view, false);
- container_notify_child_title_changed(view->swayc->parent);
+ container_notify_subtree_changed(view->swayc->parent);
view_execute_criteria(view);
container_damage_whole(cont);
@@ -661,49 +662,35 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) {
char *format = view->title_format;
char *next = strchr(format, '%');
while (next) {
- if (buffer) {
- // Copy everything up to the %
- strncat(buffer, format, next - format);
- }
+ // Copy everything up to the %
+ lenient_strncat(buffer, format, next - format);
len += next - format;
format = next;
if (strncmp(next, "%title", 6) == 0) {
- if (buffer && title) {
- strcat(buffer, title);
- }
+ lenient_strcat(buffer, title);
len += title_len;
format += 6;
} else if (strncmp(next, "%class", 6) == 0) {
- if (buffer && class) {
- strcat(buffer, class);
- }
+ lenient_strcat(buffer, class);
len += class_len;
format += 6;
} else if (strncmp(next, "%instance", 9) == 0) {
- if (buffer && instance) {
- strcat(buffer, instance);
- }
+ lenient_strcat(buffer, instance);
len += instance_len;
format += 9;
} else if (strncmp(next, "%shell", 6) == 0) {
- if (buffer) {
- strcat(buffer, shell);
- }
+ lenient_strcat(buffer, shell);
len += shell_len;
format += 6;
} else {
- if (buffer) {
- strcat(buffer, "%");
- }
+ lenient_strcat(buffer, "%");
++format;
++len;
}
next = strchr(format, '%');
}
- if (buffer) {
- strcat(buffer, format);
- }
+ lenient_strcat(buffer, format);
len += strlen(format);
return len;
@@ -759,7 +746,6 @@ void view_update_title(struct sway_view *view, bool force) {
}
container_calculate_title_height(view->swayc);
container_update_title_textures(view->swayc);
- container_notify_child_title_changed(view->swayc->parent);
config_update_font_height(false);
}