From a0add1ba7342bf17672fbfd2cdb3f87390c69b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Thu, 22 Oct 2015 16:11:08 +0200 Subject: [PATCH] Added background and border keys to the i3bar protocol. This patch adds two new status block keys, background and border, which define the respective colors for the status block. If not specified, the current behavior is kept, e.g., no background / border will be drawn. If the status block is marked urgent, the urgent color is prioritized. fixes #2022 --- docs/i3bar-protocol | 6 ++++++ i3bar/include/common.h | 2 ++ i3bar/src/child.c | 10 +++++++++ i3bar/src/xcb.c | 46 +++++++++++++++++++++++++++++++----------- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/docs/i3bar-protocol b/docs/i3bar-protocol index 6cb04bf6..3ae14453 100644 --- a/docs/i3bar-protocol +++ b/docs/i3bar-protocol @@ -136,6 +136,10 @@ color:: when it is associated. Colors are specified in hex (like in HTML), starting with a leading hash sign. For example, +#ff0000+ means red. +background:: + Overrides the background color for this particular block. +border:: + Overrides the border color for this particular block. min_width:: The minimum width (in pixels) of the block. If the content of the +full_text+ key take less space than the specified min_width, the block @@ -207,6 +211,8 @@ An example of a block which uses all possible entries follows: "full_text": "E: 10.0.0.1 (1000 Mbit/s)", "short_text": "10.0.0.1", "color": "#00ff00", + "background": "#1c1c1c", + "border": "#ee0000", "min_width": 300, "align": "right", "urgent": false, diff --git a/i3bar/include/common.h b/i3bar/include/common.h index 4d2dbd35..7ab3441f 100644 --- a/i3bar/include/common.h +++ b/i3bar/include/common.h @@ -38,6 +38,8 @@ struct status_block { i3String *short_text; char *color; + char *background; + char *border; /* min_width can be specified either as a numeric value (in pixels) or as a * string. For strings, we set min_width to the measured text width of diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 2b10be49..3570dde9 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -75,6 +75,8 @@ static void clear_statusline(struct statusline_head *head, bool free_resources) FREE(first->name); FREE(first->instance); FREE(first->min_width_str); + FREE(first->background); + FREE(first->border); } TAILQ_REMOVE(head, first, blocks); @@ -205,6 +207,14 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) { sasprintf(&(ctx->block.color), "%.*s", len, val); return 1; } + if (strcasecmp(ctx->last_map_key, "background") == 0) { + sasprintf(&(ctx->block.background), "%.*s", len, val); + return 1; + } + if (strcasecmp(ctx->last_map_key, "border") == 0) { + sasprintf(&(ctx->block.border), "%.*s", len, val); + return 1; + } if (strcasecmp(ctx->last_map_key, "markup") == 0) { ctx->block.pango_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango"))); return 1; diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 63b9863a..989b06c7 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -208,6 +208,9 @@ void refresh_statusline(bool use_short_text) { continue; block->width = predict_text_width(block->full_text); + /* Add padding for the border if we have to draw it. */ + if (block->border) + block->width += logical_px(2); /* Compute offset and append for text aligment in min_width. */ if (block->min_width <= block->width) { @@ -250,24 +253,43 @@ void refresh_statusline(bool use_short_text) { TAILQ_FOREACH(block, &statusline_head, blocks) { if (i3string_get_num_bytes(block->full_text) == 0) continue; - color_t fg_color; - /* If this block is urgent, draw it with the defined color and border. */ - if (block->urgent) { - fg_color = colors.urgent_ws_fg; + color_t fg_color = (block->color ? draw_util_hex_to_color(block->color) : colors.bar_fg); + int border_width = (block->border) ? logical_px(1) : 0; + if (block->border || block->background || block->urgent) { + if (block->urgent) + fg_color = colors.urgent_ws_fg; - /* Draw the background */ - draw_util_rectangle(&statusline_surface, colors.urgent_ws_bg, - x - logical_px(2), - logical_px(1), - block->width + logical_px(4), + /* Let's determine the colors first. */ + color_t border_color = colors.bar_bg; + color_t bg_color = colors.bar_bg; + if (block->urgent) { + border_color = colors.urgent_ws_border; + bg_color = colors.urgent_ws_bg; + } else { + if (block->border) + border_color = draw_util_hex_to_color(block->border); + + if (block->background) + bg_color = draw_util_hex_to_color(block->background); + } + + /* Draw the border. */ + draw_util_rectangle(&statusline_surface, border_color, + x, logical_px(1), + block->width + block->x_offset + block->x_append, bar_height - logical_px(2)); - } else { - fg_color = (block->color ? draw_util_hex_to_color(block->color) : colors.bar_fg); + + /* Draw the background. */ + draw_util_rectangle(&statusline_surface, bg_color, + x + border_width, + logical_px(1) + border_width, + block->width + block->x_offset + block->x_append - 2 * border_width, + bar_height - 2 * border_width - logical_px(2)); } draw_util_text(block->full_text, &statusline_surface, fg_color, colors.bar_bg, - x + block->x_offset, logical_px(ws_voff_px), block->width); + x + block->x_offset + border_width, logical_px(ws_voff_px), block->width - 2 * border_width); x += block->width + block->sep_block_width + block->x_offset + block->x_append; /* If this is not the last block, draw a separator. */