diff --git a/include/sway/commands.h b/include/sway/commands.h index 07730f98..f549626b 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -228,6 +228,7 @@ sway_cmd bar_cmd_unbindcode; sway_cmd bar_cmd_unbindsym; sway_cmd bar_cmd_wrap_scroll; sway_cmd bar_cmd_workspace_buttons; +sway_cmd bar_cmd_workspace_min_width; sway_cmd bar_colors_cmd_active_workspace; sway_cmd bar_colors_cmd_background; diff --git a/include/sway/config.h b/include/sway/config.h index 5ad240d3..ee1852d4 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -320,6 +320,7 @@ struct bar_config { struct side_gaps gaps; int status_padding; int status_edge_padding; + uint32_t workspace_min_width; struct { char *background; char *statusline; diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 688fa2d7..4cacd21a 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -38,6 +38,7 @@ struct swaybar_config { bool binding_mode_indicator; bool wrap_scroll; bool workspace_buttons; + uint32_t workspace_min_width; list_t *bindings; struct wl_list outputs; // config_output::link int height; diff --git a/sway/commands/bar.c b/sway/commands/bar.c index 7370910d..d42b7fc2 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c @@ -36,6 +36,7 @@ static struct cmd_handler bar_handlers[] = { { "unbindcode", bar_cmd_unbindcode }, { "unbindsym", bar_cmd_unbindsym }, { "workspace_buttons", bar_cmd_workspace_buttons }, + { "workspace_min_width", bar_cmd_workspace_min_width }, { "wrap_scroll", bar_cmd_wrap_scroll }, }; diff --git a/sway/commands/bar/workspace_min_width.c b/sway/commands/bar/workspace_min_width.c new file mode 100644 index 00000000..8d65592c --- /dev/null +++ b/sway/commands/bar/workspace_min_width.c @@ -0,0 +1,33 @@ +#include +#include +#include "config.h" +#include "sway/commands.h" +#include "sway/config.h" +#include "log.h" + +struct cmd_results *bar_cmd_workspace_min_width(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "workspace_min_width", EXPECTED_AT_LEAST, 1))) { + return error; + } + + struct bar_config *bar = config->current_bar; + + char *end; + int min_width = strtol(argv[0], &end, 10); + if (min_width < 0 || (*end != '\0' && strcasecmp(end, "px") != 0)) { + return cmd_results_new(CMD_INVALID, + "[Bar %s] Invalid minimum workspace button width value: %s", + bar->id, argv[0]); + } + + if (argc == 2 && strcasecmp(argv[1], "px") != 0) { + return cmd_results_new(CMD_INVALID, + "Expected 'workspace_min_width [px]'"); + } + + sway_log(SWAY_DEBUG, "[Bar %s] Setting minimum workspace button width to %d", + bar->id, min_width); + config->current_bar->workspace_min_width = min_width; + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/config/bar.c b/sway/config/bar.c index 1c7c13b2..767534a6 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c @@ -105,6 +105,7 @@ struct bar_config *default_bar_config(void) { bar->modifier = get_modifier_mask_by_name("Mod4"); bar->status_padding = 1; bar->status_edge_padding = 3; + bar->workspace_min_width = 0; if (!(bar->mode = strdup("dock"))) { goto cleanup; } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 9330de09..fceee84d 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1102,6 +1102,8 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { json_object_new_boolean(bar->strip_workspace_numbers)); json_object_object_add(json, "strip_workspace_name", json_object_new_boolean(bar->strip_workspace_name)); + json_object_object_add(json, "workspace_min_width", + json_object_new_int(bar->workspace_min_width)); json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator)); json_object_object_add(json, "verbose", diff --git a/sway/meson.build b/sway/meson.build index 0db45836..b65a5211 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -144,6 +144,7 @@ sway_sources = files( 'commands/bar/tray_output.c', 'commands/bar/tray_padding.c', 'commands/bar/workspace_buttons.c', + 'commands/bar/workspace_min_width.c', 'commands/bar/wrap_scroll.c', 'commands/input/accel_profile.c', diff --git a/sway/sway-bar.5.scd b/sway/sway-bar.5.scd index 78124c92..80d08449 100644 --- a/sway/sway-bar.5.scd +++ b/sway/sway-bar.5.scd @@ -138,6 +138,11 @@ runtime. *workspace_buttons* yes|no Enables or disables workspace buttons on the bar. Default is _yes_. +*workspace_min_width* [px] + Specifies the minimum width for the workspace buttons on the bar. Default is _0_. + + This setting also applies to the current binding mode indicator. + ## TRAY Swaybar provides a system tray where third-party applications may place icons. diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index 495e2e7d..018080fe 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -829,6 +829,9 @@ their value mean can be found in *sway-bar*(5): |- workspace_buttons : boolean : Whether to display the workspace buttons on the bar +|- workspace_min_width +: integer +: Minimum width in px for the workspace buttons on the bar |- binding_mode_indicator : boolean : Whether to display the current binding mode on the bar @@ -931,6 +934,7 @@ containing the _#RRGGBBAA_ representation of the color: "status_padding": 1, "status_edge_padding": 3, "workspace_buttons": true, + "workspace_min_width": 0, "binding_mode_indicator": true, "verbose": false, "pango_markup": false, diff --git a/swaybar/config.c b/swaybar/config.c index 52297310..abedaec0 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -35,6 +35,7 @@ struct swaybar_config *init_config(void) { config->binding_mode_indicator = true; config->wrap_scroll = false; config->workspace_buttons = true; + config->workspace_min_width = 0; config->bindings = create_list(); wl_list_init(&config->outputs); config->status_padding = 1; diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 6aa604eb..6bbe9408 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -270,6 +270,12 @@ static bool ipc_parse_config( config->workspace_buttons = json_object_get_boolean(workspace_buttons); } + json_object *workspace_min_width = + json_object_object_get(bar_config, "workspace_min_width"); + if (workspace_min_width) { + config->workspace_min_width = json_object_get_int(workspace_min_width); + } + json_object *wrap_scroll = json_object_object_get(bar_config, "wrap_scroll"); if (wrap_scroll) { config->wrap_scroll = json_object_get_boolean(wrap_scroll); diff --git a/swaybar/render.c b/swaybar/render.c index 3a626e1c..8f38174f 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -402,7 +402,11 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo, return 0; } - return ws_horizontal_padding * 2 + text_width + border_width * 2; + uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; + if (width < config->workspace_min_width * output->scale) { + width = config->workspace_min_width * output->scale; + } + return width; } static uint32_t predict_workspace_buttons_length(cairo_t *cairo, @@ -446,7 +450,11 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo, output->height < ideal_surface_height) { return 0; } - return text_width + ws_horizontal_padding * 2 + border_width * 2; + uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; + if (width < config->workspace_min_width * output->scale) { + width = config->workspace_min_width * output->scale; + } + return width; } static uint32_t render_status_line_i3bar(cairo_t *cairo, @@ -518,6 +526,9 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, return ideal_surface_height; } uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; + if (width < config->workspace_min_width * output->scale) { + width = config->workspace_min_width * output->scale; + } uint32_t height = output->height * output->scale; cairo_set_source_u32(cairo, config->colors.binding_mode.background); @@ -585,7 +596,10 @@ static uint32_t render_workspace_button(cairo_t *cairo, return ideal_surface_height; } - uint32_t width = ws_horizontal_padding * 2 + text_width + border_width * 2; + uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; + if (width < config->workspace_min_width * output->scale) { + width = config->workspace_min_width * output->scale; + } cairo_set_source_u32(cairo, box_colors.background); cairo_rectangle(cairo, *x, 0, width, height);