From fc19355327a09ca7083193faf9f04babdd59c0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20C=C3=B4rte-Real?= Date: Sat, 17 Aug 2019 20:59:07 +0100 Subject: [PATCH] Ellipsize titles that are too large in the bar When titles were very large they would overlap the status line. Ellipsize the title to get it to fit. --- common/pango.c | 30 ++++++++++++++++++++++++++++++ include/pango.h | 2 ++ swaybar/render.c | 14 ++++++-------- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/common/pango.c b/common/pango.c index fc3d06886..67395c9a9 100644 --- a/common/pango.c +++ b/common/pango.c @@ -136,3 +136,33 @@ void pango_printf(cairo_t *cairo, const char *font, g_object_unref(layout); free(buf); } + +void pango_printf_ellipsized(cairo_t *cairo, const char *font, + double scale, bool markup, int max_width, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + // Add one since vsnprintf excludes null terminator. + int length = vsnprintf(NULL, 0, fmt, args) + 1; + va_end(args); + + char *buf = malloc(length); + if (buf == NULL) { + sway_log(SWAY_ERROR, "Failed to allocate memory"); + return; + } + va_start(args, fmt); + vsnprintf(buf, length, fmt, args); + va_end(args); + + PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup); + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); + pango_layout_set_width(layout, pango_units_from_double(max_width)); + cairo_font_options_t *fo = cairo_font_options_create(); + cairo_get_font_options(cairo, fo); + pango_cairo_context_set_font_options(pango_layout_get_context(layout), fo); + cairo_font_options_destroy(fo); + pango_cairo_update_layout(cairo, layout); + pango_cairo_show_layout(cairo, layout); + g_object_unref(layout); + free(buf); +} diff --git a/include/pango.h b/include/pango.h index 6ab83c167..d58847375 100644 --- a/include/pango.h +++ b/include/pango.h @@ -19,5 +19,7 @@ void get_text_size(cairo_t *cairo, const char *font, int *width, int *height, int *baseline, double scale, bool markup, const char *fmt, ...); void pango_printf(cairo_t *cairo, const char *font, double scale, bool markup, const char *fmt, ...); +void pango_printf_ellipsized(cairo_t *cairo, const char *font, + double scale, bool markup, int max_width, const char *fmt, ...); #endif diff --git a/swaybar/render.c b/swaybar/render.c index 89f139b0b..2df7ae51c 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -537,7 +537,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, } static uint32_t render_window_title(cairo_t *cairo, - struct swaybar_output *output, double x) { + struct swaybar_output *output, double x, double max_x) { const char *title = output->bar->config->title; if (!title) { return 0; @@ -561,17 +561,14 @@ static uint32_t render_window_title(cairo_t *cairo, return ideal_surface_height; } uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; - + uint32_t max_width = fmin(width, max_x - x); uint32_t height = output->height * output->scale; - cairo_set_source_u32(cairo, config->colors.background); - cairo_rectangle(cairo, x, 0, width, height); - cairo_fill(cairo); double text_y = height / 2.0 - text_height / 2.0; cairo_set_source_u32(cairo, config->colors.statusline); cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); - pango_printf(cairo, config->font, output->scale, - output->bar->mode_pango_markup, "%s", title); + pango_printf_ellipsized(cairo, config->font, output->scale, + output->bar->mode_pango_markup, max_width, "%s", title); return output->height; } @@ -686,6 +683,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { uint32_t h = render_status_line(cairo, output, &x); max_height = h > max_height ? h : max_height; } + double max_x = x; x = 0; if (config->workspace_buttons) { struct swaybar_workspace *ws; @@ -700,7 +698,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { } if (config->window_title) { - uint32_t h = render_window_title(cairo, output, x); + uint32_t h = render_window_title(cairo, output, x, max_x); max_height = h > max_height ? h : max_height; }