commit be840f730e747a24106c8366ecb89e6b982cfa38
parent 980a4e02113789d0cca94aa023557c6f6e87ec73
Author: Norbert Bolanowski <bolanowski.n@gmail.com>
Date: Mon, 2 Sep 2024 20:02:42 +0200
move title_format to container
Diffstat:
5 files changed, 102 insertions(+), 89 deletions(-)
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
@@ -102,6 +102,8 @@ struct sway_container {
char *title; // The view's title (unformatted)
char *formatted_title; // The title displayed in the title bar
int title_width;
+
+ char *title_format;
enum sway_container_layout prev_split_layout;
@@ -183,6 +185,8 @@ void container_update_title_bar(struct sway_container *container);
void container_update_marks(struct sway_container *container);
+size_t parse_title_format(struct sway_container *container, char *buffer);
+
size_t container_build_representation(enum sway_container_layout layout,
list_t *children, char *buffer);
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
@@ -80,8 +80,6 @@ struct sway_view {
// Used when changing a view from tiled to floating.
int natural_width, natural_height;
- char *title_format;
-
bool using_csd;
struct timespec urgent;
diff --git a/sway/commands/title_format.c b/sway/commands/title_format.c
@@ -1,3 +1,4 @@
+#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
@@ -11,16 +12,19 @@ struct cmd_results *cmd_title_format(int argc, char **argv) {
return error;
}
struct sway_container *container = config->handler_context.container;
- if (!container || !container->view) {
+ if (!container) {
return cmd_results_new(CMD_INVALID,
- "Only views can have a title_format");
+ "Only valid containers can have a title_format");
}
- struct sway_view *view = container->view;
char *format = join_args(argv, argc);
- if (view->title_format) {
- free(view->title_format);
+ if (container->title_format) {
+ free(container->title_format);
+ }
+ container->title_format = format;
+ if (container->view) {
+ view_update_title(container->view, true);
+ } else {
+ container_update_representation(container);
}
- view->title_format = format;
- view_update_title(view, true);
return cmd_results_new(CMD_SUCCESS, NULL);
}
diff --git a/sway/tree/container.c b/sway/tree/container.c
@@ -22,6 +22,7 @@
#include "sway/tree/workspace.h"
#include "sway/xdg_decoration.h"
#include "list.h"
+#include "pango.h"
#include "log.h"
#include "stringop.h"
@@ -499,6 +500,7 @@ void container_destroy(struct sway_container *con) {
}
free(con->title);
free(con->formatted_title);
+ free(con->title_format);
list_free(con->pending.children);
list_free(con->current.children);
@@ -645,6 +647,87 @@ bool container_has_ancestor(struct sway_container *descendant,
return false;
}
+static char *escape_pango_markup(const char *buffer) {
+ size_t length = escape_markup_text(buffer, NULL);
+ char *escaped_title = calloc(length + 1, sizeof(char));
+ escape_markup_text(buffer, escaped_title);
+ return escaped_title;
+}
+
+static size_t append_prop(char *buffer, const char *value) {
+ if (!value) {
+ return 0;
+ }
+ // If using pango_markup in font, we need to escape all markup chars
+ // from values to make sure tags are not inserted by clients
+ if (config->pango_markup) {
+ char *escaped_value = escape_pango_markup(value);
+ lenient_strcat(buffer, escaped_value);
+ size_t len = strlen(escaped_value);
+ free(escaped_value);
+ return len;
+ } else {
+ lenient_strcat(buffer, value);
+ return strlen(value);
+ }
+}
+
+/**
+ * Calculate and return the length of the formatted title.
+ * If buffer is not NULL, also populate the buffer with the formatted title.
+ */
+size_t parse_title_format(struct sway_container *container, char *buffer) {
+ if (!container->title_format || strcmp(container->title_format, "%title") == 0) {
+ if (container->view) {
+ return append_prop(buffer, view_get_title(container->view));
+ } else {
+ return container_build_representation(container->pending.layout, container->pending.children, buffer);
+ }
+ }
+
+ size_t len = 0;
+ char *format = container->title_format;
+ char *next = strchr(format, '%');
+ while (next) {
+ // Copy everything up to the %
+ lenient_strncat(buffer, format, next - format);
+ len += next - format;
+ format = next;
+
+ if (strncmp(next, "%title", 6) == 0) {
+ if (container->view) {
+ len += append_prop(buffer, view_get_title(container->view));
+ } else {
+ len += container_build_representation(container->pending.layout, container->pending.children, buffer);
+ }
+ format += 6;
+ } else if (container->view) {
+ if (strncmp(next, "%app_id", 7) == 0) {
+ len += append_prop(buffer, view_get_app_id(container->view));
+ format += 7;
+ } else if (strncmp(next, "%class", 6) == 0) {
+ len += append_prop(buffer, view_get_class(container->view));
+ format += 6;
+ } else if (strncmp(next, "%instance", 9) == 0) {
+ len += append_prop(buffer, view_get_instance(container->view));
+ format += 9;
+ } else if (strncmp(next, "%shell", 6) == 0) {
+ len += append_prop(buffer, view_get_shell(container->view));
+ format += 6;
+ }
+ } else {
+ lenient_strcat(buffer, "%");
+ ++format;
+ ++len;
+ }
+ next = strchr(format, '%');
+ }
+ lenient_strcat(buffer, format);
+ len += strlen(format);
+
+ return len;
+}
+
/**
* Calculate and return the length of the tree representation.
* An example tree representation is: V[Terminal, Firefox]
@@ -700,16 +783,14 @@ size_t container_build_representation(enum sway_container_layout layout,
void container_update_representation(struct sway_container *con) {
if (!con->view) {
- size_t len = container_build_representation(con->pending.layout,
- con->pending.children, NULL);
+ size_t len = parse_title_format(con, NULL);
free(con->formatted_title);
con->formatted_title = calloc(len + 1, sizeof(char));
if (!sway_assert(con->formatted_title,
"Unable to allocate title string")) {
return;
}
- container_build_representation(con->pending.layout, con->pending.children,
- con->formatted_title);
+ parse_title_format(con, con->formatted_title);
if (con->title_bar.title_text) {
sway_text_node_set_text(con->title_bar.title_text, con->formatted_title);
diff --git a/sway/tree/view.c b/sway/tree/view.c
@@ -34,7 +34,6 @@
#include "sway/tree/workspace.h"
#include "sway/config.h"
#include "sway/xdg_decoration.h"
-#include "pango.h"
#include "stringop.h"
bool view_init(struct sway_view *view, enum sway_view_type type,
@@ -81,8 +80,6 @@ void view_destroy(struct sway_view *view) {
view_assign_ctx(view, NULL);
wlr_scene_node_destroy(&view->scene_tree->node);
- free(view->title_format);
-
if (view->impl->destroy) {
view->impl->destroy(view);
} else {
@@ -991,77 +988,6 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
return NULL;
}
-static char *escape_pango_markup(const char *buffer) {
- size_t length = escape_markup_text(buffer, NULL);
- char *escaped_title = calloc(length + 1, sizeof(char));
- escape_markup_text(buffer, escaped_title);
- return escaped_title;
-}
-
-static size_t append_prop(char *buffer, const char *value) {
- if (!value) {
- return 0;
- }
- // If using pango_markup in font, we need to escape all markup chars
- // from values to make sure tags are not inserted by clients
- if (config->pango_markup) {
- char *escaped_value = escape_pango_markup(value);
- lenient_strcat(buffer, escaped_value);
- size_t len = strlen(escaped_value);
- free(escaped_value);
- return len;
- } else {
- lenient_strcat(buffer, value);
- return strlen(value);
- }
-}
-
-/**
- * Calculate and return the length of the formatted title.
- * If buffer is not NULL, also populate the buffer with the formatted title.
- */
-static size_t parse_title_format(struct sway_view *view, char *buffer) {
- if (!view->title_format || strcmp(view->title_format, "%title") == 0) {
- return append_prop(buffer, view_get_title(view));
- }
-
- size_t len = 0;
- char *format = view->title_format;
- char *next = strchr(format, '%');
- while (next) {
- // Copy everything up to the %
- lenient_strncat(buffer, format, next - format);
- len += next - format;
- format = next;
-
- if (strncmp(next, "%title", 6) == 0) {
- len += append_prop(buffer, view_get_title(view));
- format += 6;
- } else if (strncmp(next, "%app_id", 7) == 0) {
- len += append_prop(buffer, view_get_app_id(view));
- format += 7;
- } else if (strncmp(next, "%class", 6) == 0) {
- len += append_prop(buffer, view_get_class(view));
- format += 6;
- } else if (strncmp(next, "%instance", 9) == 0) {
- len += append_prop(buffer, view_get_instance(view));
- format += 9;
- } else if (strncmp(next, "%shell", 6) == 0) {
- len += append_prop(buffer, view_get_shell(view));
- format += 6;
- } else {
- lenient_strcat(buffer, "%");
- ++format;
- ++len;
- }
- next = strchr(format, '%');
- }
- lenient_strcat(buffer, format);
- len += strlen(format);
-
- return len;
-}
-
void view_update_app_id(struct sway_view *view) {
const char *app_id = view_get_app_id(view);
@@ -1090,7 +1016,7 @@ void view_update_title(struct sway_view *view, bool force) {
free(view->container->title);
free(view->container->formatted_title);
- size_t len = parse_title_format(view, NULL);
+ size_t len = parse_title_format(view->container, NULL);
if (len) {
char *buffer = calloc(len + 1, sizeof(char));
@@ -1098,7 +1024,7 @@ void view_update_title(struct sway_view *view, bool force) {
return;
}
- parse_title_format(view, buffer);
+ parse_title_format(view->container, buffer);
view->container->formatted_title = buffer;
} else {
view->container->formatted_title = NULL;