From 8e9a737f788049a4b096d6d108a33b53f6aef29a Mon Sep 17 00:00:00 2001 From: MadcowOG Date: Sat, 4 Mar 2023 00:09:57 -0800 Subject: [PATCH] Fixed oversized status bars overwriting other components. --- .gitignore | 1 + src/bar.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/main.c | 2 ++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0539dd5..ae77015 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .projectile +dwl-bar bar run compile_flags.txt diff --git a/src/bar.c b/src/bar.c index dfc8202..795003c 100644 --- a/src/bar.c +++ b/src/bar.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -9,14 +10,19 @@ #include "config.h" #include "bar.h" #include "common.h" +#include "pango/pango-font.h" +#include "pango/pango-layout.h" #include "shm.h" #include "wlr-layer-shell-unstable-v1-protocol.h" #include "xdg-shell-protocol.h" +#define ELIPSES 3 + typedef struct Font { PangoFontDescription* description; uint height; /* This is also the same as lrpad from dwm. */ + uint approx_width; } Font; typedef struct BarComponent { @@ -50,6 +56,7 @@ struct Bar { Shm* shm; }; +static char *add_elipses(const char *str, int i); static void layerSurface(void* data, zwlr_layer_surface_v1*, uint32_t serial, uint32_t width, uint32_t height); static void frame(void* data, wl_callback* callback, uint32_t callback_data); static void bar_render(Bar* bar); @@ -116,7 +123,11 @@ Font getFont(void) { if (!metrics) die("font metrics"); - Font in = {desc, PANGO_PIXELS(pango_font_metrics_get_height(metrics))}; + Font in = { + desc, + PANGO_PIXELS(pango_font_metrics_get_height(metrics)), + PANGO_PIXELS(pango_font_metrics_get_approximate_char_width(metrics)) + }; pango_font_metrics_unref(metrics); g_object_unref(fnt); @@ -125,6 +136,14 @@ Font getFont(void) { return in; } +char *add_elipses(const char *str, int i) { + char *new_str = ecalloc(i+ELIPSES+1, sizeof(char)); + new_str = strncpy(new_str, str, i*sizeof(char)); + new_str[i+1] = '\0'; + new_str = strcat(new_str, "..."); + return new_str; +} + BarComponent bar_component_create(PangoContext* context, PangoFontDescription* description) { PangoLayout* layout = pango_layout_new(context); pango_layout_set_font_description(layout, description); @@ -223,8 +242,38 @@ void bar_title_render(Bar* bar, cairo_t* painter, int* x) { if (!bar) return; - // HUH For some reason ww - x - (status width) works, but ww - x - status width doesn't? - uint titleWidth = bar->shm->width - *x - (bar_component_width(&bar->status) + bar_font.height); + // @HUH: For some reason ww - x - (status width) works, but ww - x - status width doesn't? + int titleWidth = bar->shm->width - bar->layout.x - (bar_component_width(&bar->status) + bar_font.height); + + /* If the status is larger than the title + * or + * a character can't fit in the title. + * Hopefully this helps avoid situations where the title is empty + * and renders but usually if filled wouldn't. + */ + if (titleWidth < 0 || bar_font.approx_width+bar_font.height > titleWidth) + return; + + /* If not all text fills the title component + * Then fit as much as possible. + */ + if ((bar_component_width(&bar->title) + bar_font.height) > titleWidth) { + const char *text = pango_layout_get_text(bar->title.layout); + char *newText; + int i = 0; + + for (i = strlen(text); (((i+ELIPSES)*bar_font.approx_width)+bar_font.height > titleWidth + && i >= 0); i--); + + if (i <= 0) { + pango_layout_set_text(bar->title.layout, "", -1); + } else { + // This is dumb but whatever. + newText = add_elipses(text, i); + pango_layout_set_text(bar->title.layout, newText, -1); + free(newText); + } + } bar->active ? bar_set_colorscheme(bar, schemes[Active_Scheme]) : bar_set_colorscheme(bar, schemes[InActive_Scheme]); @@ -251,6 +300,27 @@ void bar_status_render(Bar* bar, cairo_t* painter, int* x) { uint statusWidth = bar_component_width(&bar->status) + bar_font.height; + // If the status is as large or larger than the layout then fit as much as we can. + if (statusWidth > (bar->shm->width - bar->layout.x)) { + const char *text = pango_layout_get_text(bar->status.layout); + char *newText; + int i = 0; + + for (i = strlen(text); (((i+ELIPSES)*bar_font.approx_width)+bar_font.height > (bar->shm->width - bar->layout.x) + && i >= 0); i--); + + if (i <= 0) { + pango_layout_set_text(bar->title.layout, "", -1); + } else { + // This is dumb but whatever. + newText = add_elipses(text, i); + pango_layout_set_text(bar->status.layout, newText, -1); + free(newText); + } + + statusWidth = bar->shm->width - bar->layout.x; + } + bar_set_colorscheme(bar, schemes[InActive_Scheme]); if (!bar->active && status_on_active) bar_set_colorscheme(bar, (const int*[4]){ grey1, grey1 } ); diff --git a/src/main.c b/src/main.c index aa7b727..36d46ad 100644 --- a/src/main.c +++ b/src/main.c @@ -611,6 +611,8 @@ void handle_stdin(char* line) { bar_set_title(monitor->bar, title); free(title); + } else if (strcmp(command, "appid") == EQUAL) { + /* Do nothing */ } else if (strcmp(command, "floating") == EQUAL) { if (line[strlen(line)-2] == ' ') { bar_set_floating(monitor->bar, 0);