aboutsummaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-05-05 12:36:50 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-05-05 22:29:37 +1000
commit228c478e8d11dd14972b237574146fd0d2d6b96c (patch)
tree819dfc4d6151ebb28d7db5b862d0ac4314d82fc3 /sway/tree
parent8dae168b77173f086880db0878f0a4b34a53e8b3 (diff)
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)
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/container.c46
-rw-r--r--sway/tree/view.c142
2 files changed, 152 insertions, 36 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 9fb47020..e1be32d1 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -348,7 +348,6 @@ struct sway_container *container_view_create(struct sway_container *sibling,
swayc, title, sibling, sibling ? sibling->type : 0, sibling->name);
// Setup values
swayc->sway_view = sway_view;
- container_update_title(swayc, title);
swayc->width = 0;
swayc->height = 0;
@@ -572,7 +571,7 @@ static void update_title_texture(struct sway_container *con,
if (*texture) {
wlr_texture_destroy(*texture);
}
- if (!con->name) {
+ if (!con->formatted_title) {
return;
}
@@ -581,7 +580,8 @@ static void update_title_texture(struct sway_container *con,
int height = config->font_height * scale;
cairo_t *c = cairo_create(NULL);
- get_text_size(c, config->font, &width, NULL, scale, false, "%s", con->name);
+ get_text_size(c, config->font, &width, NULL, scale, false,
+ "%s", con->formatted_title);
cairo_destroy(c);
cairo_surface_t *surface = cairo_image_surface_create(
@@ -596,7 +596,7 @@ static void update_title_texture(struct sway_container *con,
class->text[2], class->text[3]);
cairo_move_to(cairo, 0, 0);
- pango_printf(cairo, config->font, scale, false, "%s", con->name);
+ pango_printf(cairo, config->font, scale, false, "%s", con->formatted_title);
cairo_surface_flush(surface);
unsigned char *data = cairo_image_surface_get_data(surface);
@@ -622,57 +622,31 @@ void container_update_title_textures(struct sway_container *container) {
}
void container_calculate_title_height(struct sway_container *container) {
- if (!container->name) {
+ if (!container->formatted_title) {
container->title_height = 0;
return;
}
cairo_t *cairo = cairo_create(NULL);
int height;
get_text_size(cairo, config->font, NULL, &height, 1, false,
- "%s", container->name);
+ "%s", container->formatted_title);
cairo_destroy(cairo);
container->title_height = height;
}
-static void container_notify_child_title_changed(
- struct sway_container *container) {
+void container_notify_child_title_changed(struct sway_container *container) {
if (!container || container->type != C_CONTAINER) {
return;
}
if (container->layout != L_TABBED && container->layout != L_STACKED) {
return;
}
- if (container->name) {
- free(container->name);
+ if (container->formatted_title) {
+ free(container->formatted_title);
}
// TODO: iterate children and concatenate their titles
- container->name = strdup("");
+ container->formatted_title = strdup("");
container_calculate_title_height(container);
container_update_title_textures(container);
container_notify_child_title_changed(container->parent);
}
-
-void container_update_title(struct sway_container *container,
- const char *new_title) {
- if (!new_title) {
- new_title = "";
- }
-
- if (container->name && strcmp(container->name, new_title) == 0) {
- return;
- }
-
- if (container->name) {
- free(container->name);
- }
- container->name = strdup(new_title);
- container_calculate_title_height(container);
- container_update_title_textures(container);
- container_notify_child_title_changed(container->parent);
-
- size_t prev_max_height = config->font_height;
- config_find_font_height(false);
- if (config->font_height != prev_max_height) {
- arrange_root();
- }
-}
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 <stdlib.h>
#include <wayland-server.h>
#include <wlr/render/wlr_renderer.h>
@@ -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();
+ }
+}