diff options
author | Michael Stapelberg <michael@stapelberg.de> | 2022-10-30 22:04:05 +0100 |
---|---|---|
committer | Michael Stapelberg <stapelberg@users.noreply.github.com> | 2022-10-30 22:22:08 +0100 |
commit | 0b89d4b2a7ae84a852a707d71cf2697e55581ee7 (patch) | |
tree | 5e4bb7059a174cea797348a034aef5ff829350af | |
parent | 327bca26d87332bddb5969fe93a6a2283f50a363 (diff) | |
download | i3-0b89d4b2a7ae84a852a707d71cf2697e55581ee7.tar.gz i3-0b89d4b2a7ae84a852a707d71cf2697e55581ee7.zip |
implement bar { padding } config directive
related to https://github.com/i3/i3/issues/3724
related to https://github.com/i3/i3/pull/4288
fixes https://github.com/i3/i3/issues/3721
-rw-r--r-- | docs/userguide | 43 | ||||
-rw-r--r-- | i3bar/include/configuration.h | 9 | ||||
-rw-r--r-- | i3bar/src/config.c | 31 | ||||
-rw-r--r-- | i3bar/src/xcb.c | 28 | ||||
-rw-r--r-- | include/config_directives.h | 4 | ||||
-rw-r--r-- | include/configuration.h | 2 | ||||
-rw-r--r-- | parser-specs/config.spec | 35 | ||||
-rw-r--r-- | release-notes/changes/1-bar-padding | 1 | ||||
-rw-r--r-- | src/config_directives.c | 40 | ||||
-rw-r--r-- | src/ipc.c | 2 | ||||
-rw-r--r-- | testcases/t/177-bar-config.t | 109 | ||||
-rw-r--r-- | testcases/t/201-config-parser.t | 2 |
12 files changed, 296 insertions, 10 deletions
diff --git a/docs/userguide b/docs/userguide index 29c0cd44..b25fad05 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1980,6 +1980,49 @@ while +#000000FF+ will be a fully opaque black (the same as +#000000+). Please note that due to the way the tray specification works, enabling this flag will cause all tray icons to have a transparent background. +[[i3bar_padding]] +=== Padding + +To make i3bar higher (without increasing the font size), and/or add padding to +the left and right side of i3bar, you can use the +padding+ directive: + +*Syntax*: +-------------------------------------- +bar { + # 2px left/right and 2px top/bottom padding + padding 2px + + # 2px top/bottom padding, no left/right padding + padding 2px 0 + + # 2px top padding, no left/right padding, 4px bottom padding + padding 2px 0 4px + + # four value syntax + padding top[px] right[px] bottom[px] left[px] +} +-------------------------------------- + +*Examples*: +-------------------------------------- +bar { + # 2px left/right and 2px top/bottom padding + padding 2px + + # 2px top/bottom padding, no left/right padding + padding 2px 0 + + # 2px top padding, no left/right padding, 4px bottom padding + padding 2px 0 4px + + # 2px top padding, 6px right padding, 4px bottom padding, 1px left padding + padding 2px 6px 4px 1px +} +-------------------------------------- + +Note: As a convenience for users who migrate from i3-gaps to i3, the +height+ +directive from i3-gaps is supported by i3, but should be changed to +padding+. + [[list_of_commands]] == List of commands diff --git a/i3bar/include/configuration.h b/i3bar/include/configuration.h index 346d5b26..24079c5d 100644 --- a/i3bar/include/configuration.h +++ b/i3bar/include/configuration.h @@ -38,12 +38,21 @@ typedef struct tray_output_t { TAILQ_ENTRY(tray_output_t) tray_outputs; } tray_output_t; +/* Matches i3/include/data.h */ +struct Rect { + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +}; + typedef struct config_t { uint32_t modifier; TAILQ_HEAD(bindings_head, binding_t) bindings; position_t position; bool verbose; uint32_t bar_height; + struct Rect padding; bool transparency; struct xcb_color_strings_t colors; bool disable_binding_mode_indicator; diff --git a/i3bar/src/config.c b/i3bar/src/config.c index efc2f514..ccea937d 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -19,6 +19,7 @@ config_t config; static char *cur_key; static bool parsing_bindings; static bool parsing_tray_outputs; +static bool parsing_padding; /* * Parse a key. @@ -38,12 +39,17 @@ static int config_map_key_cb(void *params_, const unsigned char *keyVal, size_t parsing_tray_outputs = true; } + if (strcmp(cur_key, "padding") == 0) { + parsing_padding = true; + } + return 1; } static int config_end_array_cb(void *params_) { parsing_bindings = false; parsing_tray_outputs = false; + parsing_padding = false; return 1; } @@ -329,8 +335,31 @@ static int config_integer_cb(void *params_, long long val) { return 0; } + if (parsing_padding) { + if (strcmp(cur_key, "x") == 0) { + DLOG("padding.x = %lld\n", val); + config.padding.x = (uint32_t)val; + return 1; + } + if (strcmp(cur_key, "y") == 0) { + DLOG("padding.y = %lld\n", val); + config.padding.y = (uint32_t)val; + return 1; + } + if (strcmp(cur_key, "width") == 0) { + DLOG("padding.width = %lld\n", val); + config.padding.width = (uint32_t)val; + return 1; + } + if (strcmp(cur_key, "height") == 0) { + DLOG("padding.height = %lld\n", val); + config.padding.height = (uint32_t)val; + return 1; + } + } + if (!strcmp(cur_key, "bar_height")) { - DLOG("bar_height = %lld", val); + DLOG("bar_height = %lld\n", val); config.bar_height = (uint32_t)val; return 1; } diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 7010f90c..0cda125c 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -59,7 +59,7 @@ xcb_visualtype_t *visual_type; uint8_t depth; xcb_colormap_t colormap; -/* Overall height of the size */ +/* Overall height of the bar */ int bar_height; /* These are only relevant for XKB, which we only need for grabbing modifiers */ @@ -1357,13 +1357,24 @@ void init_xcb_late(char *fontname) { DLOG("Calculated font-height: %d\n", font.height); /* - * If the bar height was explicitly set, use it. Otherwise, calculate it - * based on the font size. + * If the bar height was explicitly set (but padding was not set), use + * it. Otherwise, calculate it based on the font size. */ - if (config.bar_height <= 0) - bar_height = font.height + 2 * logical_px(ws_voff_px); - else - bar_height = config.bar_height; + const int default_px = font.height + 2 * logical_px(ws_voff_px); + int padding_scaled = + logical_px(config.padding.y) + + logical_px(config.padding.height); + if (config.bar_height > 0 && + config.padding.x == 0 && + config.padding.y == 0 && + config.padding.width == 0 && + config.padding.height == 0) { + padding_scaled = config.bar_height - default_px; + DLOG("setting padding_scaled=%d based on bar_height=%d\n", padding_scaled, config.bar_height); + } else { + DLOG("padding: x=%d, y=%d -> padding_scaled=%d\n", config.padding.x, config.padding.y, padding_scaled); + } + bar_height = default_px + padding_scaled; icon_size = bar_height - 2 * logical_px(config.tray_padding); if (config.separator_symbol) @@ -2006,7 +2017,7 @@ void draw_bars(bool unhide) { i3_output *outputs_walk; SLIST_FOREACH (outputs_walk, outputs, slist) { - int workspace_width = 0; + int workspace_width = logical_px(config.padding.x); if (!outputs_walk->active) { DLOG("Output %s inactive, skipping...\n", outputs_walk->name); @@ -2090,6 +2101,7 @@ void draw_bars(bool unhide) { int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width); int x_dest = outputs_walk->rect.w - tray_width - logical_px((tray_width > 0) * sb_hoff_px) - visible_statusline_width; + x_dest -= logical_px(config.padding.width); draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text); draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0, diff --git a/include/config_directives.h b/include/config_directives.h index a1fc57be..1cc0340f 100644 --- a/include/config_directives.h +++ b/include/config_directives.h @@ -86,6 +86,10 @@ CFGFUN(bar_id, const char *bar_id); CFGFUN(bar_output, const char *output); CFGFUN(bar_verbose, const char *verbose); CFGFUN(bar_height, const long height); +CFGFUN(bar_padding_one, const long all); +CFGFUN(bar_padding_two, const long top_and_bottom, const long right_and_left); +CFGFUN(bar_padding_three, const long top, const long right_and_left, const long bottom); +CFGFUN(bar_padding_four, const long top, const long right, const long bottom, const long left); CFGFUN(bar_modifier, const char *modifiers); CFGFUN(bar_wheel_up_cmd, const char *command); CFGFUN(bar_wheel_down_cmd, const char *command); diff --git a/include/configuration.h b/include/configuration.h index b184a7b1..5eae5f87 100644 --- a/include/configuration.h +++ b/include/configuration.h @@ -358,6 +358,8 @@ struct Barconfig { /** Defines the height of the bar in pixels. */ uint32_t bar_height; + struct Rect padding; + struct bar_colors { char *background; char *statusline; diff --git a/parser-specs/config.spec b/parser-specs/config.spec index 846b6a26..e8ea2f9d 100644 --- a/parser-specs/config.spec +++ b/parser-specs/config.spec @@ -511,6 +511,7 @@ state BAR: 'strip_workspace_name' -> BAR_STRIP_WORKSPACE_NAME 'verbose' -> BAR_VERBOSE 'height' -> BAR_HEIGHT + 'padding' -> BAR_PADDING 'colors' -> BAR_COLORS_BRACE '}' -> call cfg_bar_finish(); INITIAL @@ -638,6 +639,40 @@ state BAR_HEIGHT: value = number -> call cfg_bar_height(&value); BAR +state BAR_PADDING: + top_or_all = number + -> BAR_PADDING_TOP + +state BAR_PADDING_TOP: + 'px' + -> + right_or_right_and_left = number + -> BAR_PADDING_RIGHT + end + -> call cfg_bar_padding_one(&top_or_all); BAR + +state BAR_PADDING_RIGHT: + 'px' + -> + bottom = number + -> BAR_PADDING_BOTTOM + end + -> call cfg_bar_padding_two(&top_or_all, &right_or_right_and_left); BAR + +state BAR_PADDING_BOTTOM: + 'px' + -> + left = number + -> BAR_PADDING_LEFT + end + -> call cfg_bar_padding_three(&top_or_all, &right_or_right_and_left, &bottom); BAR + +state BAR_PADDING_LEFT: + 'px' + -> + end + -> call cfg_bar_padding_four(&top_or_all, &right_or_right_and_left, &bottom, &left); BAR + state BAR_COLORS_BRACE: end -> diff --git a/release-notes/changes/1-bar-padding b/release-notes/changes/1-bar-padding new file mode 100644 index 00000000..212e9d1a --- /dev/null +++ b/release-notes/changes/1-bar-padding @@ -0,0 +1 @@ +i3bar: bar { padding } config directive now implemented (supports bar { height } from i3-gaps) diff --git a/src/config_directives.c b/src/config_directives.c index 361399b9..ae68685b 100644 --- a/src/config_directives.c +++ b/src/config_directives.c @@ -617,6 +617,46 @@ CFGFUN(bar_height, const long height) { current_bar->bar_height = (uint32_t)height; } +static void dlog_padding(void) { + DLOG("padding now: x=%d, y=%d, w=%d, h=%d\n", + current_bar->padding.x, + current_bar->padding.y, + current_bar->padding.width, + current_bar->padding.height); +} + +CFGFUN(bar_padding_one, const long all) { + current_bar->padding.x = (uint32_t)all; + current_bar->padding.y = (uint32_t)all; + current_bar->padding.width = (uint32_t)all; + current_bar->padding.height = (uint32_t)all; + dlog_padding(); +} + +CFGFUN(bar_padding_two, const long top_and_bottom, const long right_and_left) { + current_bar->padding.x = (uint32_t)right_and_left; + current_bar->padding.y = (uint32_t)top_and_bottom; + current_bar->padding.width = (uint32_t)right_and_left; + current_bar->padding.height = (uint32_t)top_and_bottom; + dlog_padding(); +} + +CFGFUN(bar_padding_three, const long top, const long right_and_left, const long bottom) { + current_bar->padding.x = (uint32_t)right_and_left; + current_bar->padding.y = (uint32_t)top; + current_bar->padding.width = (uint32_t)right_and_left; + current_bar->padding.height = (uint32_t)bottom; + dlog_padding(); +} + +CFGFUN(bar_padding_four, const long top, const long right, const long bottom, const long left) { + current_bar->padding.x = (uint32_t)left; + current_bar->padding.y = (uint32_t)top; + current_bar->padding.width = (uint32_t)right; + current_bar->padding.height = (uint32_t)bottom; + dlog_padding(); +} + CFGFUN(bar_modifier, const char *modifiers) { current_bar->modifier = modifiers ? event_state_from_str(modifiers) : XCB_NONE; } @@ -802,6 +802,8 @@ static void dump_bar_config(yajl_gen gen, Barconfig *config) { y(integer, config->bar_height); } + dump_rect(gen, "padding", config->padding); + if (config->separator_symbol) { ystr("separator_symbol"); ystr(config->separator_symbol); diff --git a/testcases/t/177-bar-config.t b/testcases/t/177-bar-config.t index 27a3d23e..278fd596 100644 --- a/testcases/t/177-bar-config.t +++ b/testcases/t/177-bar-config.t @@ -124,6 +124,9 @@ bar { # old syntax for compatibility with i3-gaps height 50 + # new syntax: top right bottom left + # y width height x + padding 4px 2px 4px 2px } EOT @@ -149,6 +152,13 @@ is($bar_config->{tray_padding}, 0, 'tray_padding ok'); is($bar_config->{font}, 'Terminus', 'font ok'); is($bar_config->{socket_path}, '/tmp/foobar', 'socket_path ok'); is($bar_config->{bar_height}, 50, 'bar_height ok'); +is_deeply($bar_config->{padding}, + { + x => 2, + y => 4, + width => 2, + height => 4, + }, 'padding ok'); is_deeply($bar_config->{colors}, { background => '#ff0000', @@ -176,6 +186,105 @@ is_deeply($bar_config->{colors}, exit_gracefully($pid); ##################################################################### +# validate one-value padding directive +##################################################################### + +$config = <<EOT; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +bar { + # all padding is 25px + padding 25px +} +EOT + +$pid = launch_with_config($config); + +$i3 = i3(get_socket_path(0)); +$bars = $i3->get_bar_config()->recv; +is(@$bars, 1, 'one bar configured'); + +$bar_id = shift @$bars; + +$bar_config = $i3->get_bar_config($bar_id)->recv; +is_deeply($bar_config->{padding}, + { + x => 25, + y => 25, + width => 25, + height => 25, + }, 'padding ok'); + +exit_gracefully($pid); + +##################################################################### +# validate two-value padding directive +##################################################################### + +$config = <<EOT; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +bar { + # top and bottom padding is 25px, right and left padding is 50px + padding 25px 50px +} +EOT + +$pid = launch_with_config($config); + +$i3 = i3(get_socket_path(0)); +$bars = $i3->get_bar_config()->recv; +is(@$bars, 1, 'one bar configured'); + +$bar_id = shift @$bars; + +$bar_config = $i3->get_bar_config($bar_id)->recv; +is_deeply($bar_config->{padding}, + { + x => 50, + y => 25, + width => 50, + height => 25, + }, 'padding ok'); + +exit_gracefully($pid); + +##################################################################### +# validate three-value padding directive +##################################################################### + +$config = <<EOT; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +bar { + # top padding is 25px, right and left padding is 50px, bottom padding is 75px + padding 25px 50px 75px +} +EOT + +$pid = launch_with_config($config); + +$i3 = i3(get_socket_path(0)); +$bars = $i3->get_bar_config()->recv; +is(@$bars, 1, 'one bar configured'); + +$bar_id = shift @$bars; + +$bar_config = $i3->get_bar_config($bar_id)->recv; +is_deeply($bar_config->{padding}, + { + x => 50, + y => 25, + width => 50, + height => 75, + }, 'padding ok'); + +exit_gracefully($pid); + +##################################################################### # ensure that multiple bars get different IDs ##################################################################### diff --git a/testcases/t/201-config-parser.t b/testcases/t/201-config-parser.t index 7d81b17e..3ab18483 100644 --- a/testcases/t/201-config-parser.t +++ b/testcases/t/201-config-parser.t @@ -773,7 +773,7 @@ EOT $expected = <<'EOT'; cfg_bar_start() cfg_bar_output(LVDS-1) -ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'binding_mode_indicator', 'workspace_buttons', 'workspace_min_width', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'height', 'colors', '}' +ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'binding_mode_indicator', 'workspace_buttons', 'workspace_min_width', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'height', 'padding', 'colors', '}' ERROR: CONFIG: (in file <stdin>) ERROR: CONFIG: Line 1: bar { ERROR: CONFIG: Line 2: output LVDS-1 |