diff --git a/client/common/common.c b/client/common/common.c index 179a0cc..ececbaf 100644 --- a/client/common/common.c +++ b/client/common/common.c @@ -182,6 +182,7 @@ usage(FILE *out, const char *name) " -T, --no-touch ignore touch events.\n" " -K, --no-keyboard ignore keyboard events.\n" " --binding use alternative key bindings. Available options: vim\n" + " --fixed-height prevent the display from changing height on filter.\n" " --scrollbar display scrollbar. (none (default), always, autohide)\n" " --counter display a matched/total items counter. (none (default), always)\n" " --accept-single immediately return if there is only one item.\n" @@ -271,6 +272,7 @@ do_getopt(struct client *client, int *argc, char **argv[]) { "index", required_argument, 0, 'I' }, { "prefix", required_argument, 0, 'P' }, { "password", no_argument, 0, 'x' }, + { "fixed-height", no_argument, 0, 0x090 }, { "scrollbar", required_argument, 0, 0x100 }, { "counter", required_argument, 0, 0x10a }, { "accept-single",no_argument, 0, 0x11a }, @@ -361,6 +363,9 @@ do_getopt(struct client *client, int *argc, char **argv[]) case 'I': client->selected = strtol(optarg, NULL, 10); break; + case 0x090: + client->fixed_height = true; + break; case 0x100: client->scrollbar = (!strcmp(optarg, "none") ? BM_SCROLLBAR_NONE : (!strcmp(optarg, "always") ? BM_SCROLLBAR_ALWAYS : (!strcmp(optarg, "autohide") ? BM_SCROLLBAR_AUTOHIDE : BM_SCROLLBAR_NONE))); break; @@ -547,6 +552,7 @@ menu_with_options(struct client *client) bm_menu_set_wrap(menu, client->wrap); bm_menu_set_monitor(menu, client->monitor); bm_menu_set_monitor_name(menu, client->monitor_name); + bm_menu_set_fixed_height(menu, client->fixed_height); bm_menu_set_scrollbar(menu, client->scrollbar); bm_menu_set_counter(menu, client->counter); bm_menu_set_panel_overlap(menu, !client->no_overlap); diff --git a/client/common/common.h b/client/common/common.h index 357401c..98c9b4c 100644 --- a/client/common/common.h +++ b/client/common/common.h @@ -27,6 +27,7 @@ struct client { bool center; bool grab; bool wrap; + bool fixed_height; bool counter; bool accept_single; bool ifne; diff --git a/lib/bemenu.h b/lib/bemenu.h index ec3303a..2679f37 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -689,6 +689,24 @@ BM_PUBLIC const char* bm_menu_get_color(const struct bm_menu *menu, enum bm_colo */ BM_PUBLIC void bm_menu_set_scrollbar(struct bm_menu *menu, enum bm_scrollbar_mode mode); +/** + * Set fixed height mode of the bar. + * + * @param menu bm_menu to set the fixed height for. + * @param mode to be set. + */ + +BM_PUBLIC void bm_menu_set_fixed_height(struct bm_menu *menu, bool mode); + +/** + * Get the fixed height mode of the bar. + * + * @param menu bm_menu to get the fixed height from. + * @return current fixed height mode + */ + +BM_PUBLIC bool bm_menu_get_fixed_height(struct bm_menu *menu); + /** * Return current scrollbar display mode. * diff --git a/lib/internal.h b/lib/internal.h index 56a4860..bc5e653 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -352,6 +352,11 @@ struct bm_menu { */ enum bm_filter_mode filter_mode; + /** + * Current fixed height mode. + */ + bool fixed_height; + /** * Current Scrollbar display mode. */ diff --git a/lib/menu.c b/lib/menu.c index 2279ce5..909b5fe 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -434,6 +434,18 @@ char* bm_menu_get_color(const struct bm_menu *menu, enum bm_color color) return menu->colors[color].hex; } +void +bm_menu_set_fixed_height(struct bm_menu *menu, bool mode) +{ + menu->fixed_height = mode; +} + +bool +bm_menu_get_fixed_height(struct bm_menu *menu) +{ + return menu->fixed_height; +} + void bm_menu_set_scrollbar(struct bm_menu *menu, enum bm_scrollbar_mode mode) { diff --git a/lib/renderers/cairo_renderer.h b/lib/renderers/cairo_renderer.h index 520419b..e021b53 100644 --- a/lib/renderers/cairo_renderer.h +++ b/lib/renderers/cairo_renderer.h @@ -297,7 +297,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s uint32_t border_radius = menu->border_radius; uint32_t total_item_count = menu->items.count; - uint32_t filtered_item_count = (menu->filter ? menu->filtered.count : total_item_count); + uint32_t filtered_item_count; + bm_menu_get_filtered_items(menu, &filtered_item_count); cairo_set_source_rgba(cairo->cr, 0, 0, 0, 0); cairo_rectangle(cairo->cr, 0, 0, width, height); @@ -371,8 +372,16 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s uint32_t posy = titleh; const uint32_t page = (menu->index / lines) * lines; - for (uint32_t l = 0, i = page; l < lines && i < count && posy < max_height; ++i, ++l) { - bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); + + for (uint32_t l = 0, i = page; l < lines && posy < max_height; ++i, ++l) { + if (!menu->fixed_height && i >= count) { + continue; + } + + bool highlighted = false; + if (i < count) { + highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); + } if (highlighted) { if (menu->event_feedback) { @@ -382,18 +391,22 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_BG, &paint.bg); } - } else if (bm_menu_item_is_selected(menu, items[i])) { + } else if (i < count && bm_menu_item_is_selected(menu, items[i])) { bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_BG, &paint.bg); - } else if (i % 2 == 1) { + } else if (i < count && i % 2 == 1) { bm_cairo_color_from_menu_color(menu, BM_COLOR_ALTERNATE_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_ALTERNATE_BG, &paint.bg); } else { bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg); } + + char *line_str = ""; + if (i < count) { + line_str = bm_cairo_entry_message(items[i]->text, highlighted, menu->event_feedback, i, count); + } - char *line_str = bm_cairo_entry_message(items[i]->text, highlighted, menu->event_feedback, i, count); if (menu->prefix && highlighted) { paint.pos = (struct pos){ spacing_x + border_size, posy+vpadding + border_size }; paint.box = (struct box){ 4, 0, vpadding, -vpadding, width - paint.pos.x, height };