diff options
-rw-r--r-- | source/blender/editors/interface/interface_template_search_menu.c | 459 |
1 files changed, 304 insertions, 155 deletions
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 3d07da083e8..c256923e7fd 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -64,6 +64,12 @@ /* Unicode arrow. */ #define MENU_SEP "\xe2\x96\xb6" +struct MenuSearch_Context { + int space_type_ui_index; + ScrArea *area; + ARegion *region; +}; + struct MenuSearch_Parent { struct MenuSearch_Parent *parent; MenuType *parent_mt; @@ -107,6 +113,12 @@ struct MenuSearch_Item { int enum_value; } rna; }; + + /** + * Set when we need each menu item to be able to set it's own context. + * may be NULL. + */ + struct MenuSearch_Context *wm_context; }; struct MenuSearch_Data { @@ -143,7 +155,8 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d MemArena *memarena, struct MenuType *mt, const char *drawstr_submenu, - uiBut *but) + uiBut *but, + struct MenuSearch_Context *wm_context) { struct MenuSearch_Item *item = NULL; if (but->optype != NULL) { @@ -187,6 +200,9 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d item->state = (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT)); item->mt = mt; item->drawstr_submenu = drawstr_submenu ? strdup_memarena(memarena, drawstr_submenu) : NULL; + + item->wm_context = wm_context; + BLI_addtail(&data->items, item); return true; } @@ -289,6 +305,8 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d item->drawwstr_full = strdup_memarena(memarena, uiname); + item->wm_context = NULL; + BLI_addtail(&operator_items, item); } } @@ -304,10 +322,8 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d * - Look-up pre-defined editor-menus. * - Look-up key-map items which call menus. */ -static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, - wmWindow *win, - ScrArea *area, - ARegion *region) +static struct MenuSearch_Data *menu_items_from_ui_create( + bContext *C, wmWindow *win, ScrArea *area_init, ARegion *region_init, bool include_all_areas) { MemArena *memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); /** Map (#MenuType to #MenuSearch_Parent) */ @@ -344,17 +360,113 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, } } - /* Populate menus from the editors, - * note that we could create a fake header, draw the header and extract the menus - * from the buttons, however this is quite involved and can be avoided as by convention - * each space-type has a single root-menu that headers use. */ - { - const char *idname_array[] = { - "TOPBAR_MT_editor_menus", - /* Optional second menu for the space-type. */ - NULL, - }; - int idname_array_len = 1; + /* Collect contexts, one for each 'ui_type'. */ + struct MenuSearch_Context *wm_contexts = NULL; + + const EnumPropertyItem *space_type_ui_items = NULL; + int space_type_ui_items_len; + bool space_type_ui_items_free = false; + + /* Types match, cycle the subtype. */ + + if (include_all_areas) { + /* First create arrays for ui_type. */ + PropertyRNA *prop_ui_type; + { + PointerRNA ptr; + RNA_pointer_create(NULL, &RNA_Area, NULL, &ptr); + prop_ui_type = RNA_struct_find_property(&ptr, "ui_type"); + RNA_property_enum_items(C, + &ptr, + prop_ui_type, + &space_type_ui_items, + &space_type_ui_items_len, + &space_type_ui_items_free); + + wm_contexts = BLI_memarena_alloc(memarena, sizeof(*wm_contexts) * space_type_ui_items_len); + + for (int i = 0; i < space_type_ui_items_len; i++) { + wm_contexts[i].space_type_ui_index = -1; + wm_contexts[i].area = NULL; + wm_contexts[i].region = NULL; + } + } + + bScreen *screen = WM_window_get_active_screen(win); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); + if (region != NULL) { + PointerRNA ptr; + RNA_pointer_create(&screen->id, &RNA_Area, area, &ptr); + const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type); + + int space_type_ui_index = RNA_enum_from_value(space_type_ui_items, space_type_ui); + if (space_type_ui_index == -1) { + continue; + } + + if (wm_contexts[space_type_ui_index].space_type_ui_index != -1) { + ScrArea *area_best = wm_contexts[area->spacetype].area; + const uint value_best = (uint)area_best->winx * (uint)area_best->winy; + const uint value_test = (uint)area->winx * (uint)area->winy; + if (value_best > value_test) { + continue; + } + } + + wm_contexts[space_type_ui_index].space_type_ui_index = space_type_ui_index; + wm_contexts[space_type_ui_index].area = area; + wm_contexts[space_type_ui_index].region = region; + } + } + } + + GHashIterator iter; + + for (int space_type_ui_index = -1; space_type_ui_index < space_type_ui_items_len; + space_type_ui_index += 1) { + + ScrArea *area = NULL; + ARegion *region = NULL; + struct MenuSearch_Context *wm_context = NULL; + + if (include_all_areas) { + if (space_type_ui_index == -1) { + /* First run without any context, to populate the top-bar without. */ + wm_context = NULL; + area = NULL; + region = NULL; + } + else { + wm_context = &wm_contexts[space_type_ui_index]; + if (wm_context->space_type_ui_index == -1) { + continue; + } + + area = wm_context->area; + region = wm_context->region; + + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + } + } + else { + area = area_init; + region = region_init; + } + + /* Populate menus from the editors, + * note that we could create a fake header, draw the header and extract the menus + * from the buttons, however this is quite involved and can be avoided as by convention + * each space-type has a single root-menu that headers use. */ + { + const char *idname_array[2] = {NULL}; + int idname_array_len = 0; + + /* Use negative for global (no area) context, populate the top-bar. */ + if (space_type_ui_index == -1) { + idname_array[idname_array_len++] = "TOPBAR_MT_editor_menus"; + } #define SPACE_MENU_MAP(space_type, menu_id) \ case space_type: \ @@ -364,177 +476,180 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, case space_type: \ break - if (area != NULL) { - switch (area->spacetype) { - SPACE_MENU_MAP(SPACE_VIEW3D, "VIEW3D_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_GRAPH, "GRAPH_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_OUTLINER, "OUTLINER_MT_editor_menus"); - SPACE_MENU_NOP(SPACE_PROPERTIES); - SPACE_MENU_MAP(SPACE_FILE, "FILE_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_IMAGE, "IMAGE_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_INFO, "INFO_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_SEQ, "SEQUENCER_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_TEXT, "TEXT_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_ACTION, "DOPESHEET_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_NLA, "NLA_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_NODE, "NODE_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_CONSOLE, "CONSOLE_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_USERPREF, "USERPREF_MT_editor_menus"); - SPACE_MENU_MAP(SPACE_CLIP, - (((const SpaceClip *)area->spacedata.first)->mode == SC_MODE_TRACKING) ? - "CLIP_MT_tracking_editor_menus" : - "CLIP_MT_masking_editor_menus"); - SPACE_MENU_NOP(SPACE_TOPBAR); - SPACE_MENU_NOP(SPACE_STATUSBAR); - default: - printf("Unknown space type '%d'\n", area->spacetype); + if (area != NULL) { + switch (area->spacetype) { + SPACE_MENU_MAP(SPACE_VIEW3D, "VIEW3D_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_GRAPH, "GRAPH_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_OUTLINER, "OUTLINER_MT_editor_menus"); + SPACE_MENU_NOP(SPACE_PROPERTIES); + SPACE_MENU_MAP(SPACE_FILE, "FILE_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_IMAGE, "IMAGE_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_INFO, "INFO_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_SEQ, "SEQUENCER_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_TEXT, "TEXT_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_ACTION, "DOPESHEET_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_NLA, "NLA_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_NODE, "NODE_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_CONSOLE, "CONSOLE_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_USERPREF, "USERPREF_MT_editor_menus"); + SPACE_MENU_MAP(SPACE_CLIP, + (((const SpaceClip *)area->spacedata.first)->mode == SC_MODE_TRACKING) ? + "CLIP_MT_tracking_editor_menus" : + "CLIP_MT_masking_editor_menus"); + SPACE_MENU_NOP(SPACE_TOPBAR); + SPACE_MENU_NOP(SPACE_STATUSBAR); + default: + printf("Unknown space type '%d'\n", area->spacetype); + } } - } - for (int i = 0; i < idname_array_len; i++) { - MenuType *mt = WM_menutype_find(idname_array[i], false); - if (mt != NULL) { - BLI_linklist_prepend(&menu_stack, mt); - BLI_gset_add(menu_tagged, mt); + for (int i = 0; i < idname_array_len; i++) { + MenuType *mt = WM_menutype_find(idname_array[i], false); + if (mt != NULL) { + /* Check if this exists because of 'include_all_areas'. */ + if (BLI_gset_add(menu_tagged, mt)) { + BLI_linklist_prepend(&menu_stack, mt); + } + } } } - } #undef SPACE_MENU_MAP #undef SPACE_MENU_NOP - bool has_keymap_menu_items = false; + bool has_keymap_menu_items = false; - GHashIterator iter; + while (menu_stack != NULL) { + MenuType *mt = BLI_linklist_pop(&menu_stack); + if (!WM_menutype_poll(C, mt)) { + continue; + } - while (menu_stack != NULL) { - MenuType *mt = BLI_linklist_pop(&menu_stack); - if (!WM_menutype_poll(C, mt)) { - continue; - } + uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); + uiLayout *layout = UI_block_layout( + block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style); - uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); - uiLayout *layout = UI_block_layout( - block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style); + UI_block_flag_enable(block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS); - UI_block_flag_enable(block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS); + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); + UI_menutype_draw(C, mt, layout); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - UI_menutype_draw(C, mt, layout); + UI_block_end(C, block); - UI_block_end(C, block); + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { + MenuType *mt_from_but = NULL; + /* Support menu titles with dynamic from initial labels + * (used by edit-mesh context menu). */ + if (but->type == UI_BTYPE_LABEL) { - LISTBASE_FOREACH (uiBut *, but, &block->buttons) { - MenuType *mt_from_but = NULL; - /* Support menu titles with dynamic from initial labels - * (used by edit-mesh context menu). */ - if (but->type == UI_BTYPE_LABEL) { + /* Check if the label is the title. */ + uiBut *but_test = but->prev; + while (but_test && but_test->type == UI_BTYPE_SEPR) { + but_test = but_test->prev; + } - /* Check if the label is the title. */ - uiBut *but_test = but->prev; - while (but_test && but_test->type == UI_BTYPE_SEPR) { - but_test = but_test->prev; + if (but_test == NULL) { + BLI_ghash_insert( + menu_display_name_map, mt, (void *)strdup_memarena(memarena, but->drawstr)); + } } - - if (but_test == NULL) { - BLI_ghash_insert( - menu_display_name_map, mt, (void *)strdup_memarena(memarena, but->drawstr)); + else if (menu_items_from_ui_create_item_from_button( + data, memarena, mt, NULL, but, wm_context)) { + /* pass */ } - } - else if (menu_items_from_ui_create_item_from_button(data, memarena, mt, NULL, but)) { - /* pass */ - } - else if ((mt_from_but = UI_but_menutype_get(but))) { + else if ((mt_from_but = UI_but_menutype_get(but))) { - if (BLI_gset_add(menu_tagged, mt_from_but)) { - BLI_linklist_prepend(&menu_stack, mt_from_but); - } + if (BLI_gset_add(menu_tagged, mt_from_but)) { + BLI_linklist_prepend(&menu_stack, mt_from_but); + } - if (!BLI_ghash_haskey(menu_parent_map, mt_from_but)) { - struct MenuSearch_Parent *menu_parent = BLI_memarena_calloc(memarena, - sizeof(*menu_parent)); - /* Use brackets for menu key shortcuts, - * converting "Text|Some-Shortcut" to "Text (Some-Shortcut)". - * This is needed so we don't right align sub-menu contents - * we only want to do that for the last menu item, not the path that leads to it. - */ - const char *drawstr_sep = but->flag & UI_BUT_HAS_SEP_CHAR ? - strrchr(but->drawstr, UI_SEP_CHAR) : - NULL; - bool drawstr_is_empty = false; - if (drawstr_sep != NULL) { - BLI_assert(BLI_dynstr_get_len(dyn_str) == 0); - /* Detect empty string, fallback to menu name. */ - const char *drawstr = but->drawstr; - int drawstr_len = drawstr_sep - but->drawstr; - if (UNLIKELY(drawstr_len == 0)) { - drawstr = CTX_IFACE_(mt_from_but->translation_context, mt_from_but->label); - drawstr_len = strlen(drawstr); - if (drawstr[0] == '\0') { - drawstr_is_empty = true; + if (!BLI_ghash_haskey(menu_parent_map, mt_from_but)) { + struct MenuSearch_Parent *menu_parent = BLI_memarena_calloc(memarena, + sizeof(*menu_parent)); + /* Use brackets for menu key shortcuts, + * converting "Text|Some-Shortcut" to "Text (Some-Shortcut)". + * This is needed so we don't right align sub-menu contents + * we only want to do that for the last menu item, not the path that leads to it. + */ + const char *drawstr_sep = but->flag & UI_BUT_HAS_SEP_CHAR ? + strrchr(but->drawstr, UI_SEP_CHAR) : + NULL; + bool drawstr_is_empty = false; + if (drawstr_sep != NULL) { + BLI_assert(BLI_dynstr_get_len(dyn_str) == 0); + /* Detect empty string, fallback to menu name. */ + const char *drawstr = but->drawstr; + int drawstr_len = drawstr_sep - but->drawstr; + if (UNLIKELY(drawstr_len == 0)) { + drawstr = CTX_IFACE_(mt_from_but->translation_context, mt_from_but->label); + drawstr_len = strlen(drawstr); + if (drawstr[0] == '\0') { + drawstr_is_empty = true; + } } + BLI_dynstr_nappend(dyn_str, drawstr, drawstr_len); + BLI_dynstr_appendf(dyn_str, " (%s)", drawstr_sep + 1); + menu_parent->drawstr = strdup_memarena_from_dynstr(memarena, dyn_str); + BLI_dynstr_clear(dyn_str); } - BLI_dynstr_nappend(dyn_str, drawstr, drawstr_len); - BLI_dynstr_appendf(dyn_str, " (%s)", drawstr_sep + 1); - menu_parent->drawstr = strdup_memarena_from_dynstr(memarena, dyn_str); - BLI_dynstr_clear(dyn_str); - } - else { - const char *drawstr = but->drawstr; - if (UNLIKELY(drawstr[0] == '\0')) { - drawstr = CTX_IFACE_(mt_from_but->translation_context, mt_from_but->label); - if (drawstr[0] == '\0') { - drawstr_is_empty = true; + else { + const char *drawstr = but->drawstr; + if (UNLIKELY(drawstr[0] == '\0')) { + drawstr = CTX_IFACE_(mt_from_but->translation_context, mt_from_but->label); + if (drawstr[0] == '\0') { + drawstr_is_empty = true; + } } + menu_parent->drawstr = strdup_memarena(memarena, drawstr); } - menu_parent->drawstr = strdup_memarena(memarena, drawstr); - } - menu_parent->parent_mt = mt; - BLI_ghash_insert(menu_parent_map, mt_from_but, menu_parent); + menu_parent->parent_mt = mt; + BLI_ghash_insert(menu_parent_map, mt_from_but, menu_parent); - if (drawstr_is_empty) { - printf("Warning: '%s' menu has empty 'bl_label'.\n", mt_from_but->idname); + if (drawstr_is_empty) { + printf("Warning: '%s' menu has empty 'bl_label'.\n", mt_from_but->idname); + } } } - } - else if (but->menu_create_func != NULL) { - /* A non 'MenuType' menu button. */ + else if (but->menu_create_func != NULL) { + /* A non 'MenuType' menu button. */ - /* Only expand one level deep, this is mainly for expanding operator menus. */ - const char *drawstr_submenu = but->drawstr; + /* Only expand one level deep, this is mainly for expanding operator menus. */ + const char *drawstr_submenu = but->drawstr; - /* +1 to avoid overlap with the current 'block'. */ - uiBlock *sub_block = UI_block_begin(C, region, __func__ + 1, UI_EMBOSS); - uiLayout *sub_layout = UI_block_layout( - sub_block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style); + /* +1 to avoid overlap with the current 'block'. */ + uiBlock *sub_block = UI_block_begin(C, region, __func__ + 1, UI_EMBOSS); + uiLayout *sub_layout = UI_block_layout( + sub_block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style); - UI_block_flag_enable(sub_block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS); + UI_block_flag_enable(sub_block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS); - uiLayoutSetOperatorContext(sub_layout, WM_OP_INVOKE_REGION_WIN); + uiLayoutSetOperatorContext(sub_layout, WM_OP_INVOKE_REGION_WIN); - but->menu_create_func(C, sub_layout, but->poin); + but->menu_create_func(C, sub_layout, but->poin); - UI_block_end(C, sub_block); + UI_block_end(C, sub_block); - LISTBASE_FOREACH (uiBut *, sub_but, &sub_block->buttons) { - menu_items_from_ui_create_item_from_button(data, memarena, mt, drawstr_submenu, sub_but); - } + LISTBASE_FOREACH (uiBut *, sub_but, &sub_block->buttons) { + menu_items_from_ui_create_item_from_button( + data, memarena, mt, drawstr_submenu, sub_but, wm_context); + } - if (region) { - BLI_remlink(®ion->uiblocks, sub_block); + if (region) { + BLI_remlink(®ion->uiblocks, sub_block); + } + UI_block_free(NULL, sub_block); } - UI_block_free(NULL, sub_block); } - } - if (region) { - BLI_remlink(®ion->uiblocks, block); - } - UI_block_free(NULL, block); - - /* Add key-map items as a second pass, - * so all menus are accessed from the header & top-bar before key shortcuts are expanded. */ - if ((menu_stack == NULL) && (has_keymap_menu_items == false)) { - has_keymap_menu_items = true; - menu_types_add_from_keymap_items( - C, win, area, region, &menu_stack, menu_to_kmi, menu_tagged); + if (region) { + BLI_remlink(®ion->uiblocks, block); + } + UI_block_free(NULL, block); + + /* Add key-map items as a second pass, + * so all menus are accessed from the header & top-bar before key shortcuts are expanded. */ + if ((menu_stack == NULL) && (has_keymap_menu_items == false)) { + has_keymap_menu_items = true; + menu_types_add_from_keymap_items( + C, win, area, region, &menu_stack, menu_to_kmi, menu_tagged); + } } } @@ -552,6 +667,17 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, /* Set names as full paths. */ LISTBASE_FOREACH (struct MenuSearch_Item *, item, &data->items) { + BLI_assert(BLI_dynstr_get_len(dyn_str) == 0); + + if (include_all_areas) { + BLI_dynstr_appendf( + dyn_str, + "%s: ", + (item->wm_context != NULL) ? + space_type_ui_items[item->wm_context->space_type_ui_index].name : + CTX_IFACE_(RNA_property_translation_context(prop_ui_type), "Top Bar")); + } + if (item->menu_parent != NULL) { struct MenuSearch_Parent *menu_parent = item->menu_parent; menu_parent->temp_child = NULL; @@ -559,7 +685,6 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, menu_parent->parent->temp_child = menu_parent; menu_parent = menu_parent->parent; } - BLI_assert(BLI_dynstr_get_len(dyn_str) == 0); while (menu_parent) { BLI_dynstr_append(dyn_str, menu_parent->drawstr); BLI_dynstr_append(dyn_str, " " MENU_SEP " "); @@ -567,7 +692,6 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, } } else { - BLI_assert(BLI_dynstr_get_len(dyn_str) == 0); const char *drawstr = BLI_ghash_lookup(menu_display_name_map, item->mt); if (drawstr == NULL) { drawstr = CTX_IFACE_(item->mt->translation_context, item->mt->label); @@ -611,6 +735,15 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C, data->memarena = memarena; + if (include_all_areas) { + CTX_wm_area_set(C, area_init); + CTX_wm_region_set(C, region_init); + + if (space_type_ui_items_free) { + MEM_freeN((void *)space_type_ui_items); + } + } + if (U.flag & USER_DEVELOPER_UI) { menu_items_from_all_operators(C, data); } @@ -650,6 +783,14 @@ static void menu_call_fn(bContext *C, void *UNUSED(arg1), void *arg2) return; } + ScrArea *area_prev = CTX_wm_area(C); + ARegion *region_prev = CTX_wm_region(C); + + if (item->wm_context != NULL) { + CTX_wm_area_set(C, item->wm_context->area); + CTX_wm_region_set(C, item->wm_context->region); + } + switch (item->type) { case MENU_SEARCH_TYPE_OP: { CTX_store_set(C, item->op.context); @@ -687,6 +828,11 @@ static void menu_call_fn(bContext *C, void *UNUSED(arg1), void *arg2) break; } } + + if (item->wm_context != NULL) { + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, region_prev); + } } static void menu_search_cb(const bContext *UNUSED(C), @@ -731,7 +877,10 @@ void UI_but_func_menu_search(uiBut *but) wmWindow *win = CTX_wm_window(C); ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - struct MenuSearch_Data *data = menu_items_from_ui_create(C, win, area, region); + /* When run from top-bar scan all areas in the current window. */ + bool include_all_areas = (area && (area->spacetype == SPACE_TOPBAR)); + struct MenuSearch_Data *data = menu_items_from_ui_create( + C, win, area, region, include_all_areas); UI_but_func_search_set(but, ui_searchbox_create_menu, menu_search_cb, |