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. */