From ca82f958125483a0e99c4ab82cda1b188754b32b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Sat, 22 Jun 2019 22:18:29 +0200 Subject: [PATCH] feat: added support for user-defined border widths in i3bar blocks (#3726) This change introduces support for four new properties on the i3bar protocol, namely "border_top", "border_right", "border_bottom" and "border_left". If a block is drawn with a border, these values define the width of the corresponding edge in pixels. They all default to 1 if not specified to preserve compatibility. fixes #3722 --- docs/i3bar-protocol | 16 ++++++++++++++++ i3bar/include/common.h | 4 ++++ i3bar/src/child.c | 22 ++++++++++++++++++++++ i3bar/src/xcb.c | 17 +++++++++-------- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/docs/i3bar-protocol b/docs/i3bar-protocol index 10ee795ba..76c51d806 100644 --- a/docs/i3bar-protocol +++ b/docs/i3bar-protocol @@ -141,6 +141,18 @@ background:: Overrides the background color for this particular block. border:: Overrides the border color for this particular block. +border_top:: + Defines the width (in pixels) of the top border of this block. Defaults + to 1. +border_right:: + Defines the width (in pixels) of the right border of this block. Defaults + to 1. +border_bottom:: + Defines the width (in pixels) of the bottom border of this block. Defaults + to 1. +border_left:: + Defines the width (in pixels) of the left border of this block. Defaults + to 1. 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 @@ -215,6 +227,10 @@ An example of a block which uses all possible entries follows: "color": "#00ff00", "background": "#1c1c1c", "border": "#ee0000", + "border_top": 1, + "border_right": 0, + "border_bottom": 3, + "border_left": 1, "min_width": 300, "align": "right", "urgent": false, diff --git a/i3bar/include/common.h b/i3bar/include/common.h index 77be31823..fe7444a3d 100644 --- a/i3bar/include/common.h +++ b/i3bar/include/common.h @@ -61,6 +61,10 @@ struct status_block { bool urgent; bool no_separator; + uint32_t border_top; + uint32_t border_right; + uint32_t border_bottom; + uint32_t border_left; bool pango_markup; /* The amount of pixels necessary to render a separater after the block. */ diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 549a2f701..83ee26b41 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -176,6 +176,12 @@ static int stdin_start_map(void *context) { else ctx->block.sep_block_width = logical_px(8) + separator_symbol_width; + /* By default we draw all four borders if a border is set. */ + ctx->block.border_top = 1; + ctx->block.border_right = 1; + ctx->block.border_bottom = 1; + ctx->block.border_left = 1; + return 1; } @@ -262,6 +268,22 @@ static int stdin_integer(void *context, long long val) { ctx->block.sep_block_width = (uint32_t)val; return 1; } + if (strcasecmp(ctx->last_map_key, "border_top") == 0) { + ctx->block.border_top = (uint32_t)val; + return 1; + } + if (strcasecmp(ctx->last_map_key, "border_right") == 0) { + ctx->block.border_right = (uint32_t)val; + return 1; + } + if (strcasecmp(ctx->last_map_key, "border_bottom") == 0) { + ctx->block.border_bottom = (uint32_t)val; + return 1; + } + if (strcasecmp(ctx->last_map_key, "border_left") == 0) { + ctx->block.border_left = (uint32_t)val; + return 1; + } return 1; } diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 33e13c1ba..412981bc9 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -213,7 +213,7 @@ static uint32_t predict_statusline_length(bool use_short_text) { render->width = predict_text_width(text); if (block->border) - render->width += logical_px(2); + render->width += logical_px(block->border_left + block->border_right); /* Compute offset and append for text aligment in min_width. */ if (block->min_width <= render->width) { @@ -287,8 +287,8 @@ static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focu color_t bg_color = bar_color; - int border_width = (block->border) ? logical_px(1) : 0; int full_render_width = render->width + render->x_offset + render->x_append; + int has_border = block->border ? 1 : 0; if (block->border || block->background || block->urgent) { /* Let's determine the colors first. */ color_t border_color = bar_color; @@ -310,15 +310,16 @@ static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focu /* Draw the background. */ draw_util_rectangle(&output->statusline_buffer, bg_color, - x + border_width, - logical_px(1) + border_width, - full_render_width - 2 * border_width, - bar_height - 2 * border_width - logical_px(2)); + x + has_border * logical_px(block->border_left), + logical_px(1) + has_border * logical_px(block->border_top), + full_render_width - has_border * logical_px(block->border_right + block->border_left), + bar_height - has_border * logical_px(block->border_bottom + block->border_top) - logical_px(2)); } draw_util_text(text, &output->statusline_buffer, fg_color, bg_color, - x + render->x_offset + border_width, logical_px(ws_voff_px), - render->width - 2 * border_width); + x + render->x_offset + has_border * logical_px(block->border_left), + bar_height / 2 - font.height / 2, + render->width - has_border * logical_px(block->border_left + block->border_right)); x += full_render_width; /* If this is not the last block, draw a separator. */