Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Tue, 11 Sep 2018 01:01:39 +0000 (11:01 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 11 Sep 2018 01:02:37 +0000 (11:02 +1000)
12 files changed:
1  2 
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_region_menu_pie.c
source/blender/editors/interface/interface_region_menu_popup.c
source/blender/editors/interface/interface_region_popover.c
source/blender/editors/interface/interface_region_popup.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/space_node/node_select.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_window.c

index 6821a8299ebde3a3a4a4e22ebb789ad1130a3088,0db6e2c122c30b837429dcc997cfe58de2cca4c9..0fe4b63763fff7fd4e8ef573055a498764cc18f1
@@@ -502,10 -458,15 +502,15 @@@ uiBlock *UI_block_begin(const struct bC
  void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
  void UI_block_end(const struct bContext *C, uiBlock *block);
  void UI_block_draw(const struct bContext *C, struct uiBlock *block);
 +void UI_blocklist_update_window_matrix(const struct bContext *C, const struct ListBase *lb);
 +void UI_blocklist_draw(const struct bContext *C, const struct ListBase *lb);
  void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
  
 -uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar);
 -
+ enum {
+       UI_BLOCK_THEME_STYLE_REGULAR = 0,
+       UI_BLOCK_THEME_STYLE_POPUP = 1,
+ };
+ void UI_block_theme_style_set(uiBlock *block, char theme_style);
  void UI_block_emboss_set(uiBlock *block, char dt);
  
  void UI_block_free(const struct bContext *C, uiBlock *block);
index 863e4b3762a2aa9c984ff0964cbf44b1d3202140,11691fd8365e866cd6f36a66aee325ecc335e7ed..59e1879d4f873cc2670ec11068ba65ad6b85df73
@@@ -403,15 -402,12 +403,16 @@@ struct uiBlock 
  
        int flag;
        short alignnr;
 +      /* Hints about the buttons of this block. Used to avoid iterating over
 +       * buttons to find out if some criteria is met by any. Instead, check this
 +       * criteria when adding the button and set a flag here if it's met. */
 +      short content_hints; /* eBlockContentHints */
  
        char direction;
+       char theme_style; /* UI_BLOCK_THEME_STYLE_* */
        char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
        bool auto_open;
 -      char _pad[6];
 +      char _pad[5];
        double auto_open_last;
  
        const char *lockstr;
index 56ec61c5226b897ea5797ecbab0cd49be49e2480,0000000000000000000000000000000000000000..b71152fcd1978d327b7c7af0d262dd667e469209
mode 100644,000000..100644
--- /dev/null
@@@ -1,393 -1,0 +1,394 @@@
 +/*
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + *
 + * The Original Code is Copyright (C) 2008 Blender Foundation.
 + * All rights reserved.
 + *
 + * Contributor(s): Blender Foundation
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +
 +/** \file blender/editors/interface/interface_region_popover.c
 + *  \ingroup edinterface
 + *
 + * Pop-Over Region
 + *
 + * \note This is very close to 'interface_region_menu_popup.c'
 + *
 + * We could even merge them, however menu logic is already over-loaded.
 + * PopOver's have the following differences.
 + *
 + * - UI is not constrained to a list.
 + * - Pressing a button won't close the pop-over.
 + * - Different draw style (to show this is has different behavior from a menu).
 + * - #PanelType are used instead of #MenuType.
 + * - No menu flipping support.
 + * - No moving the menu to fit the mouse cursor.
 + * - No key accelerators to access menu items
 + *   (if we add support they would work differently).
 + * - No arrow key navigation.
 + * - No menu memory.
 + * - No title.
 + */
 +
 +#include "MEM_guardedalloc.h"
 +
 +#include "DNA_userdef_types.h"
 +
 +#include "BLI_listbase.h"
 +
 +#include "BLI_rect.h"
 +#include "BLI_utildefines.h"
 +
 +#include "BKE_context.h"
 +#include "BKE_screen.h"
 +#include "BKE_report.h"
 +
 +#include "ED_screen.h"
 +
 +#include "WM_api.h"
 +#include "WM_types.h"
 +
 +
 +#include "UI_interface.h"
 +
 +#include "interface_intern.h"
 +#include "interface_regions_intern.h"
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Popup Menu with Callback or String
 + * \{ */
 +
 +struct uiPopover {
 +      uiBlock *block;
 +      uiLayout *layout;
 +      uiBut *but;
 +
 +      /* Needed for keymap removal. */
 +      wmWindow *window;
 +      wmKeyMap *keymap;
 +      struct wmEventHandler *keymap_handler;
 +
 +      uiMenuCreateFunc menu_func;
 +      void *menu_arg;
 +
 +      /* Size in pixels (ui scale applied). */
 +      int ui_size_x;
 +
 +#ifdef USE_UI_POPOVER_ONCE
 +      bool is_once;
 +#endif
 +};
 +
 +static void ui_popover_create_block(bContext *C, uiPopover *pup, int opcontext)
 +{
 +      BLI_assert(pup->ui_size_x != 0);
 +
 +      uiStyle *style = UI_style_get_dpi();
 +      pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
 +      pup->layout = UI_block_layout(
 +              pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0,
 +              pup->ui_size_x, 0, MENU_PADDING, style);
 +
 +      uiLayoutSetOperatorContext(pup->layout, opcontext);
 +
 +      if (pup->but) {
 +              if (pup->but->context) {
 +                      uiLayoutContextCopy(pup->layout, pup->but->context);
 +              }
 +      }
 +
 +      pup->block->flag |= UI_BLOCK_NO_FLIP;
 +}
 +
 +static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
 +{
 +      uiPopover *pup = arg_pup;
 +
 +      /* Create UI block and layout now if it wasn't done between begin/end. */
 +      if (!pup->layout) {
 +              ui_popover_create_block(C, pup, WM_OP_INVOKE_REGION_WIN);
 +
 +              if (pup->menu_func) {
 +                      pup->block->handle = handle;
 +                      pup->menu_func(C, pup->layout, pup->menu_arg);
 +                      pup->block->handle = NULL;
 +              }
 +
 +              pup->layout = NULL;
 +      }
 +
 +      /* Setup and resolve UI layout for block. */
 +      uiBlock *block = pup->block;
 +      int width, height;
 +
 +      UI_block_region_set(block, handle->region);
 +      UI_block_layout_resolve(block, &width, &height);
 +      UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER);
 +#ifdef USE_UI_POPOVER_ONCE
 +      if (pup->is_once) {
 +              UI_block_flag_enable(block, UI_BLOCK_POPOVER_ONCE);
 +      }
 +#endif
 +      UI_block_direction_set(block, UI_DIR_DOWN | UI_DIR_CENTER_X);
 +
 +      const int block_margin = U.widget_unit / 2;
 +
 +      if (pup->but) {
 +              /* For a header menu we set the direction automatic. */
 +              block->minbounds = BLI_rctf_size_x(&pup->but->rect);
 +              UI_block_bounds_set_normal(block, block_margin);
 +
 +              /* If menu slides out of other menu, override direction. */
 +              bool slideout = ui_block_is_menu(pup->but->block);
 +              if (slideout)
 +                      UI_block_direction_set(block, UI_DIR_RIGHT);
 +
 +              /* Store the button location for positioning the popover arrow hint. */
 +              if (!handle->refresh) {
 +                      float center[2] = {BLI_rctf_cent_x(&pup->but->rect), BLI_rctf_cent_y(&pup->but->rect)};
 +                      ui_block_to_window_fl(handle->ctx_region, pup->but->block, &center[0], &center[1]);
 +                      /* These variables aren't used for popovers, we could add new variables if there is a conflict. */
 +                      handle->prev_mx = block->mx = (int)center[0];
 +                      handle->prev_my = block->my = (int)center[1];
 +              }
 +              else {
 +                      block->mx = handle->prev_mx;
 +                      block->my = handle->prev_my;
 +              }
 +
 +              if (!slideout) {
 +                      ScrArea *sa = CTX_wm_area(C);
 +                      ARegion *ar = CTX_wm_region(C);
 +
 +                      if (ar && ar->panels.first) {
 +                              /* For regions with panels, prefer to open to top so we can
 +                               * see the values of the buttons below changing. */
 +                              UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
 +                      }
 +                      else if (sa && ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
 +                              /* Prefer popover from header to be positioned into the editor. */
 +                              if (ar && ar->regiontype == RGN_TYPE_HEADER) {
 +                                      UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
 +                              }
 +                      }
 +              }
 +
 +              /* Estimated a maximum size so we don't go offscreen for low height
 +               * areas near the bottom of the window on refreshes. */
 +              handle->max_size_y = UI_UNIT_Y * 16.0f;
 +      }
 +      else {
 +              /* Not attached to a button. */
 +              int offset[2] = {0, 0};
 +              UI_block_flag_enable(block, UI_BLOCK_LOOP);
++              UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
 +              UI_block_direction_set(block, block->direction);
 +              block->minbounds = UI_MENU_WIDTH_MIN;
 +              bool use_place_under_active = !handle->refresh;
 +
 +              if (use_place_under_active) {
 +                      uiBut *but = NULL;
 +                      for (but = block->buttons.first; but; but = but->next) {
 +                              if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
 +                                      break;
 +                              }
 +                      }
 +
 +                      if (but) {
 +                              offset[0] = -(but->rect.xmin + 0.8f * BLI_rctf_size_x(&but->rect));
 +                              offset[1] = -(but->rect.ymin + 0.5f * BLI_rctf_size_y(&but->rect));
 +                      }
 +              }
 +
 +              UI_block_bounds_set_popup(block, block_margin, offset[0], offset[1]);
 +      }
 +
 +      return block;
 +}
 +
 +static void ui_block_free_func_POPOVER(uiPopupBlockHandle *UNUSED(handle), void *arg_pup)
 +{
 +      uiPopover *pup = arg_pup;
 +      if (pup->keymap != NULL) {
 +              wmWindow *window = pup->window;
 +              WM_event_remove_keymap_handler(&window->modalhandlers, pup->keymap);
 +      }
 +      MEM_freeN(pup);
 +}
 +
 +uiPopupBlockHandle *ui_popover_panel_create(
 +        bContext *C, ARegion *butregion, uiBut *but,
 +        uiMenuCreateFunc menu_func, void *arg)
 +{
 +      /* Create popover, buttons are created from callback. */
 +      uiPopover *pup = MEM_callocN(sizeof(uiPopover), __func__);
 +      pup->but = but;
 +
 +      /* FIXME: maybe one day we want non panel popovers? */
 +      {
 +              int ui_units_x = ((PanelType *)arg)->ui_units_x;
 +              pup->ui_size_x = U.widget_unit * (ui_units_x ? ui_units_x : UI_POPOVER_WIDTH_UNITS);
 +      }
 +
 +      pup->menu_func = menu_func;
 +      pup->menu_arg = arg;
 +
 +#ifdef USE_UI_POPOVER_ONCE
 +      pup->is_once = true;
 +#endif
 +
 +      /* Create popup block. */
 +      uiPopupBlockHandle *handle;
 +      handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
 +      handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
 +      handle->can_refresh = true;
 +
 +      /* Add handlers. If attached to a button, the button will already
 +       * add a modal handler and pass on events. */
 +      if (!but) {
 +              wmWindow *window = CTX_wm_window(C);
 +              UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
 +              WM_event_add_mousemove(C);
 +              handle->popup = true;
 +      }
 +
 +      return handle;
 +}
 +
 +/** \} */
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Standard Popover Panels
 + * \{ */
 +
 +int UI_popover_panel_invoke(
 +        bContext *C, const char *idname,
 +        bool keep_open, ReportList *reports)
 +{
 +      uiLayout *layout;
 +      PanelType *pt = WM_paneltype_find(idname, true);
 +      if (pt == NULL) {
 +              BKE_reportf(reports, RPT_ERROR, "Panel \"%s\" not found", idname);
 +              return OPERATOR_CANCELLED;
 +      }
 +
 +      if (pt->poll && (pt->poll(C, pt) == false)) {
 +              /* cancel but allow event to pass through, just like operators do */
 +              return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
 +      }
 +
 +      if (keep_open) {
 +              ui_popover_panel_create(C, NULL, NULL, ui_item_paneltype_func, pt);
 +      }
 +      else {
 +              uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x);
 +              layout = UI_popover_layout(pup);
 +              UI_paneltype_draw(C, pt, layout);
 +              UI_popover_end(C, pup, NULL);
 +      }
 +
 +      return OPERATOR_INTERFACE;
 +}
 +
 +/** \} */
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Popup Menu API with begin & end
 + * \{ */
 +
 +/**
 + * Only return handler, and set optional title.
 + */
 +uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
 +{
 +      uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
 +      if (ui_size_x == 0) {
 +              ui_size_x = U.widget_unit * UI_POPOVER_WIDTH_UNITS;
 +      }
 +      pup->ui_size_x = ui_size_x;
 +
 +      /* Opertor context default same as menus, change if needed. */
 +      ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
 +
 +      /* create in advance so we can let buttons point to retval already */
 +      pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
 +
 +      return pup;
 +}
 +
 +static void popover_keymap_fn(wmKeyMap *UNUSED(keymap), wmKeyMapItem *UNUSED(kmi), void *user_data)
 +{
 +      uiPopover *pup = user_data;
 +      pup->block->handle->menuretval = UI_RETURN_OK;
 +}
 +
 +/* set the whole structure to work */
 +void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
 +{
 +      wmWindow *window = CTX_wm_window(C);
 +      /* Create popup block. No refresh support since the buttons were created
 +       * between begin/end and we have no callback to recreate them. */
 +      uiPopupBlockHandle *handle;
 +
 +      if (keymap) {
 +              /* Add so we get keymaps shown in the buttons. */
 +              UI_block_flag_enable(pup->block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS);
 +              pup->keymap = keymap;
 +              pup->keymap_handler = WM_event_add_keymap_handler_priority(&window->modalhandlers, keymap, 0);
 +              WM_event_set_keymap_handler_callback(pup->keymap_handler, popover_keymap_fn, pup);
 +      }
 +
 +      handle = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPOVER, pup);
 +      handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
 +
 +      /* Add handlers. */
 +      UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
 +      WM_event_add_mousemove(C);
 +      handle->popup = true;
 +
 +      /* Re-add so it gets priority. */
 +      if (keymap) {
 +              BLI_remlink(&window->modalhandlers, pup->keymap_handler);
 +              BLI_addhead(&window->modalhandlers, pup->keymap_handler);
 +      }
 +
 +      pup->window = window;
 +
 +      /* TODO(campbell): we may want to make this configurable.
 +       * The begin/end stype of calling popups doesn't allow to 'can_refresh' to be set.
 +       * For now close this style of popvers when accessed. */
 +      UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
 +
 +      /* panels are created flipped (from event handling pov) */
 +      pup->block->flag ^= UI_BLOCK_IS_FLIP;
 +}
 +
 +uiLayout *UI_popover_layout(uiPopover *pup)
 +{
 +      return pup->layout;
 +}
 +
 +#ifdef USE_UI_POPOVER_ONCE
 +void UI_popover_once_clear(uiPopover *pup)
 +{
 +      pup->is_once = false;
 +}
 +#endif
 +
 +/** \} */
index 0b7dd753ae19d08808fa77babdcabf33db4c71d9,d9be0abfb78f28f5f7875ed1207ebbec34661337..a72d1df019a82bf07d5e04f0c4e20e684507ef64
@@@ -107,127 -96,6 +107,128 @@@ void UI_template_fix_linking(void
  {
  }
  
 +/**
 + * Add a block button for the search menu for templateID and templateSearch.
 + */
 +static void template_add_button_search_menu(
 +        const bContext *C, uiLayout *layout, uiBlock *block,
 +        PointerRNA *ptr, PropertyRNA *prop,
 +        uiBlockCreateFunc block_func, void *block_argN, const char * const tip,
 +        const bool use_previews, const bool editable, const bool live_icon)
 +{
 +      PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
 +      ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
 +      const ID *idfrom = ptr->id.data;
 +      const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
 +      uiBut *but;
 +
 +      if (use_previews) {
 +              ARegion *region = CTX_wm_region(C);
 +              ScrArea *area = CTX_wm_area(C);
 +              /* XXX ugly top-bar exception */
 +              const bool use_big_size = (region->regiontype != RGN_TYPE_HEADER) && (area->spacetype != SPACE_TOPBAR); /* silly check, could be more generic */
 +              /* Ugly exception for screens here, drawing their preview in icon size looks ugly/useless */
 +              const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
 +              const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
 +              const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
 +
 +              but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
 +              if (use_preview_icon) {
 +                      int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
 +                      ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
 +              }
 +              else {
 +                      ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
 +                      UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
 +              }
 +
 +              if ((idfrom && idfrom->lib) || !editable)
 +                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +              if (use_big_size) {
 +                      uiLayoutRow(layout, true);
 +              }
 +      }
 +      else {
 +              but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
 +
 +              if (live_icon) {
 +                      int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
 +                      ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
 +              }
 +              else {
 +                      ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
 +              }
 +              if (id) {
 +                      /* default dragging of icon for id browse buttons */
 +                      UI_but_drag_set_id(but, id);
 +              }
 +              UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
 +
 +              if ((idfrom && idfrom->lib) || !editable)
 +                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +      }
 +}
 +
 +static uiBlock *template_common_search_menu(
 +        const bContext *C, ARegion *region,
 +        uiButSearchFunc search_func, void *search_arg,
 +        uiButHandleFunc handle_func, void *active_item,
 +        const int preview_rows, const int preview_cols,
 +        float scale)
 +{
 +      static char search[256];
 +      wmWindow *win = CTX_wm_window(C);
 +      uiBlock *block;
 +      uiBut *but;
 +
 +      /* clear initial search string, then all items show */
 +      search[0] = 0;
 +
 +      block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
 +      UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
++      UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
 +
 +      /* preview thumbnails */
 +      if (preview_rows > 0 && preview_cols > 0) {
 +              const int w = 4 * U.widget_unit * preview_cols * scale;
 +              const int h = 5 * U.widget_unit * preview_rows * scale;
 +
 +              /* fake button, it holds space for search items */
 +              uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
 +
 +              but = uiDefSearchBut(
 +                      block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
 +                      preview_rows, preview_cols, "");
 +      }
 +      /* list view */
 +      else {
 +              const int searchbox_width  = UI_searchbox_size_x();
 +              const int searchbox_height = UI_searchbox_size_y();
 +
 +              /* fake button, it holds space for search items */
 +              uiDefBut(
 +                      block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height,
 +                      NULL, 0, 0, 0, 0, NULL);
 +              but = uiDefSearchBut(
 +                      block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0,
 +                      searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
 +      }
 +      UI_but_func_search_set(
 +              but, ui_searchbox_create_generic, search_func,
 +              search_arg, handle_func, active_item);
 +
 +
 +      UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
 +      UI_block_direction_set(block, UI_DIR_DOWN);
 +
 +      /* give search-field focus */
 +      UI_but_focus_on_enter_event(win, but);
 +      /* this type of search menu requires undo */
 +      but->flag |= UI_BUT_UNDO;
 +
 +      return block;
 +}
 +
  /********************** Header Template *************************/
  
  void uiTemplateHeader(uiLayout *layout, bContext *C)
index 2296c3bc39ddfa4fbb956ef36b49d1684a8d903e,be7bba23c906678bfc22f217e1e03200fb45cfa6..004cdeb8d53209e5f814cdbbe7a324f8677c9d22
@@@ -4134,14 -3785,11 +4134,15 @@@ void ui_draw_but(const bContext *C, ARe
  
                        case UI_BTYPE_SEARCH_MENU:
                                wt = widget_type(UI_WTYPE_NAME);
-                               if (but->block->flag & UI_BLOCK_LOOP)
+                               if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
                                        wt->wcol_theme = &btheme->tui.wcol_menu_back;
+                               }
                                break;
  
 +                      case UI_BTYPE_TAB:
 +                              wt = widget_type(UI_WTYPE_TAB);
 +                              break;
 +
                        case UI_BTYPE_BUT_TOGGLE:
                        case UI_BTYPE_TOGGLE:
                        case UI_BTYPE_TOGGLE_N:
index 8061211c0b005ac20cacb0b46baeb9b348a163e3,4438bd1595fb709f2098823e94dbdf919423f6d7..dfe2a5407b195533c793795cda6701c98917f24f
@@@ -785,9 -767,10 +785,10 @@@ static uiBlock *wm_enum_search_menu(bCo
  
        block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
        UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+       UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
  
        search[0] = '\0';
 +      BLI_assert(search_menu->use_previews || (search_menu->prv_cols == 0 && search_menu->prv_rows == 0));
  #if 0 /* ok, this isn't so easy... */
        uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
  #endif