aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2022-10-30 22:04:05 +0100
committerMichael Stapelberg <stapelberg@users.noreply.github.com>2022-10-30 22:22:08 +0100
commit0b89d4b2a7ae84a852a707d71cf2697e55581ee7 (patch)
tree5e4bb7059a174cea797348a034aef5ff829350af
parent327bca26d87332bddb5969fe93a6a2283f50a363 (diff)
downloadi3-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/userguide43
-rw-r--r--i3bar/include/configuration.h9
-rw-r--r--i3bar/src/config.c31
-rw-r--r--i3bar/src/xcb.c28
-rw-r--r--include/config_directives.h4
-rw-r--r--include/configuration.h2
-rw-r--r--parser-specs/config.spec35
-rw-r--r--release-notes/changes/1-bar-padding1
-rw-r--r--src/config_directives.c40
-rw-r--r--src/ipc.c2
-rw-r--r--testcases/t/177-bar-config.t109
-rw-r--r--testcases/t/201-config-parser.t2
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;
}
diff --git a/src/ipc.c b/src/ipc.c
index fee012b0..0b0451f3 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -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