From 228c478e8d11dd14972b237574146fd0d2d6b96c Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 5 May 2018 12:36:50 +1000 Subject: Implement title_format This implements the title_format command, with a new placeholder %shell which gets substituted with the view type (xwayland, xdg_shell_v6 or wl_shell). Example config: for_window [title=".*"] title_format %title (class=%class instance=%instance shell=%shell) --- sway/tree/view.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'sway/tree/view.c') diff --git a/sway/tree/view.c b/sway/tree/view.c index 84962306..4a01f096 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include @@ -67,6 +68,18 @@ const char *view_get_instance(struct sway_view *view) { return NULL; } +const char *view_get_type(struct sway_view *view) { + switch(view->type) { + case SWAY_VIEW_WL_SHELL: + return "wl_shell"; + case SWAY_VIEW_XDG_SHELL_V6: + return "xdg_shell_v6"; + case SWAY_VIEW_XWAYLAND: + return "xwayland"; + } + return "unknown"; +} + void view_configure(struct sway_view *view, double ox, double oy, int width, int height) { if (view->impl->configure) { @@ -348,6 +361,11 @@ void view_unmap(struct sway_view *view) { view->swayc = NULL; view->surface = NULL; + if (view->title_format) { + free(view->title_format); + view->title_format = NULL; + } + if (parent->type == C_OUTPUT) { arrange_output(parent); } else { @@ -475,3 +493,127 @@ void view_child_destroy(struct sway_view_child *child) { free(child); } } + +static char *parse_title_format(struct sway_view *view) { + if (!view->title_format || strcmp(view->title_format, "%title") == 0) { + return strdup(view_get_title(view)); + } + const char *title = view_get_title(view); + const char *class = view_get_class(view); + const char *instance = view_get_instance(view); + const char *shell = view_get_type(view); + size_t title_len = title ? strlen(title) : 0; + size_t class_len = class ? strlen(class) : 0; + size_t instance_len = instance ? strlen(instance) : 0; + size_t shell_len = shell ? strlen(shell) : 0; + + // First, determine the length + size_t len = 0; + char *format = view->title_format; + char *next = strchr(format, '%'); + while (next) { + len += next - format; + format = next; + + if (strncmp(next, "%title", 6) == 0) { + len += title_len; + format += 6; + } else if (strncmp(next, "%class", 6) == 0) { + len += class_len; + format += 6; + } else if (strncmp(next, "%instance", 9) == 0) { + len += instance_len; + format += 9; + } else if (strncmp(next, "%shell", 6) == 0) { + len += shell_len; + format += 6; + } else { + ++format; + ++len; + } + next = strchr(format, '%'); + } + len += strlen(format); + + char *buffer = calloc(len + 1, 1); + if (!sway_assert(buffer, "Unable to allocate title string")) { + return NULL; + } + + // Now build the title + format = view->title_format; + next = strchr(format, '%'); + while (next) { + // Copy everything up to the % + strncat(buffer, format, next - format); + format = next; + + if (strncmp(next, "%title", 6) == 0) { + if (title) { + strcat(buffer, title); + } + format += 6; + } else if (strncmp(next, "%class", 6) == 0) { + if (class) { + strcat(buffer, class); + } + format += 6; + } else if (strncmp(next, "%instance", 9) == 0) { + if (instance) { + strcat(buffer, instance); + } + format += 9; + } else if (strncmp(next, "%shell", 6) == 0) { + strcat(buffer, shell); + format += 6; + } else { + strcat(buffer, "%"); + ++format; + } + next = strchr(format, '%'); + } + strcat(buffer, format); + + return buffer; +} + +void view_update_title(struct sway_view *view, bool force) { + if (!view->swayc) { + return; + } + const char *title = view_get_title(view); + + if (!force) { + if (title && view->swayc->name && strcmp(title, view->swayc->name) == 0) { + return; + } + if (!title && !view->swayc->name) { + return; + } + } + + if (title) { + if (view->swayc->name) { + free(view->swayc->name); + } + if (view->swayc->formatted_title) { + free(view->swayc->formatted_title); + } + view->swayc->name = strdup(title); + view->swayc->formatted_title = parse_title_format(view); + } else { + free(view->swayc->name); + free(view->swayc->formatted_title); + view->swayc->name = NULL; + view->swayc->formatted_title = NULL; + } + container_calculate_title_height(view->swayc); + container_update_title_textures(view->swayc); + container_notify_child_title_changed(view->swayc->parent); + + size_t prev_max_height = config->font_height; + config_find_font_height(false); + if (config->font_height != prev_max_height) { + arrange_root(); + } +} -- cgit v1.2.3 From da7d6642d3d970da5579066f26d83fbd0873c6f4 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 5 May 2018 18:18:54 +1000 Subject: Refactor parse_title_format() --- sway/tree/view.c | 93 +++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) (limited to 'sway/tree/view.c') diff --git a/sway/tree/view.c b/sway/tree/view.c index 4a01f096..386144f6 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -494,9 +494,17 @@ void view_child_destroy(struct sway_view_child *child) { } } -static char *parse_title_format(struct sway_view *view) { +/** + * 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 strdup(view_get_title(view)); + const char *title = view_get_title(view); + if (buffer) { + strcpy(buffer, title); + } + return strlen(title); } const char *title = view_get_title(view); const char *class = view_get_class(view); @@ -507,74 +515,56 @@ static char *parse_title_format(struct sway_view *view) { size_t instance_len = instance ? strlen(instance) : 0; size_t shell_len = shell ? strlen(shell) : 0; - // First, determine the length size_t len = 0; char *format = view->title_format; char *next = strchr(format, '%'); while (next) { - len += next - format; - format = next; - - if (strncmp(next, "%title", 6) == 0) { - len += title_len; - format += 6; - } else if (strncmp(next, "%class", 6) == 0) { - len += class_len; - format += 6; - } else if (strncmp(next, "%instance", 9) == 0) { - len += instance_len; - format += 9; - } else if (strncmp(next, "%shell", 6) == 0) { - len += shell_len; - format += 6; - } else { - ++format; - ++len; + if (buffer) { + // Copy everything up to the % + strncat(buffer, format, next - format); } - next = strchr(format, '%'); - } - len += strlen(format); - - char *buffer = calloc(len + 1, 1); - if (!sway_assert(buffer, "Unable to allocate title string")) { - return NULL; - } - - // Now build the title - format = view->title_format; - next = strchr(format, '%'); - while (next) { - // Copy everything up to the % - strncat(buffer, format, next - format); + len += next - format; format = next; if (strncmp(next, "%title", 6) == 0) { - if (title) { + if (buffer && title) { strcat(buffer, title); } + len += title_len; format += 6; } else if (strncmp(next, "%class", 6) == 0) { - if (class) { + if (buffer && class) { strcat(buffer, class); } + len += class_len; format += 6; } else if (strncmp(next, "%instance", 9) == 0) { - if (instance) { + if (buffer && instance) { strcat(buffer, instance); } + len += instance_len; format += 9; } else if (strncmp(next, "%shell", 6) == 0) { - strcat(buffer, shell); + if (buffer) { + strcat(buffer, shell); + } + len += shell_len; format += 6; } else { - strcat(buffer, "%"); + if (buffer) { + strcat(buffer, "%"); + } ++format; + ++len; } next = strchr(format, '%'); } - strcat(buffer, format); + if (buffer) { + strcat(buffer, format); + } + len += strlen(format); - return buffer; + return len; } void view_update_title(struct sway_view *view, bool force) { @@ -592,18 +582,19 @@ void view_update_title(struct sway_view *view, bool force) { } } + free(view->swayc->name); + free(view->swayc->formatted_title); if (title) { - if (view->swayc->name) { - free(view->swayc->name); - } - if (view->swayc->formatted_title) { - free(view->swayc->formatted_title); + size_t len = parse_title_format(view, NULL); + char *buffer = calloc(len + 1, 1); + if (!sway_assert(buffer, "Unable to allocate title string")) { + return; } + parse_title_format(view, buffer); + view->swayc->name = strdup(title); - view->swayc->formatted_title = parse_title_format(view); + view->swayc->formatted_title = buffer; } else { - free(view->swayc->name); - free(view->swayc->formatted_title); view->swayc->name = NULL; view->swayc->formatted_title = NULL; } -- cgit v1.2.3 From 5d6d24e71aabc026c99ac736c788fa8103658c42 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 5 May 2018 18:25:31 +1000 Subject: Move code for re-arranging after font height change into a common place --- sway/tree/view.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'sway/tree/view.c') diff --git a/sway/tree/view.c b/sway/tree/view.c index 386144f6..851348d8 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -601,10 +601,5 @@ 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); - - size_t prev_max_height = config->font_height; - config_find_font_height(false); - if (config->font_height != prev_max_height) { - arrange_root(); - } + config_update_font_height(false); } -- cgit v1.2.3 From 936226845fc08ee64b6914b233d901ae92994206 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 5 May 2018 18:28:35 +1000 Subject: Add extra check for view title being NULL --- sway/tree/view.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/tree/view.c') diff --git a/sway/tree/view.c b/sway/tree/view.c index 851348d8..fe944466 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -501,10 +501,10 @@ void view_child_destroy(struct sway_view_child *child) { static size_t parse_title_format(struct sway_view *view, char *buffer) { if (!view->title_format || strcmp(view->title_format, "%title") == 0) { const char *title = view_get_title(view); - if (buffer) { + if (buffer && title) { strcpy(buffer, title); } - return strlen(title); + return title ? strlen(title) : 0; } const char *title = view_get_title(view); const char *class = view_get_class(view); -- cgit v1.2.3