diff --git a/src/bfu/menu.c b/src/bfu/menu.c index d0bb1497..0f114114 100644 --- a/src/bfu/menu.c +++ b/src/bfu/menu.c @@ -61,6 +61,7 @@ static int m_submenu_len = sizeof(m_submenu) - 1; static window_handler_T menu_handler; static window_handler_T mainmenu_handler; static void display_mainmenu(struct terminal *term, struct menu *menu); +static void set_menu_selection(struct menu *menu, int pos); static inline int @@ -266,7 +267,7 @@ count_menu_size(struct terminal *term, struct menu *menu) static void scroll_menu(struct menu *menu, int steps, int wrap) { - int height, scr_i, pos, start; + int pos, start; int s = steps ? steps/abs(steps) : 1; /* Selectable item search direction. */ if (menu->size <= 0) { @@ -314,6 +315,20 @@ no_item: select_item: if (!mi_is_selectable(&menu->items[pos])) goto no_item; + set_menu_selection(menu, pos); +} + +/* Set menu->selected = pos, and adjust menu->first if needed. + * This neither redraws the menu nor runs the item's action. + * The caller must ensure that menu->items[pos] is selectable. */ +static void +set_menu_selection(struct menu *menu, int pos) +{ + int height, scr_i; + + assert(pos >= 0 && pos < menu->size); + assert(mi_is_selectable(&menu->items[pos])); + if_assert_failed return; menu->selected = pos; @@ -654,7 +669,8 @@ search_menu_item(struct menu_item *item, unsigned char *buffer, { unsigned char *text, *match; - if (!mi_has_left_text(item)) return 0; + /* set_menu_selection asserts selectability. */ + if (!mi_has_left_text(item) || !mi_is_selectable(item)) return 0; text = mi_text_translate(item) ? _(item->text, term) : item->text; @@ -716,7 +732,7 @@ menu_search_handler(struct input_line *line, int action_id) struct menu_item *item = &menu->items[pos]; if (search_menu_item(item, buffer, term)) { - scroll_menu(menu, pos - menu->selected, 0); + set_menu_selection(menu, pos); display_menu(term, menu); return INPUT_LINE_PROCEED; }