Page MenuHome
Paste P1267

Example of possible fix for T73565
ActivePublic

Authored by Campbell Barton (campbellbarton) on Feb 21 2020, 2:26 AM.
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index e3d95bb660f..85871c4fb05 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -953,6 +953,9 @@ void CTX_wm_region_set(bContext *C, ARegion *region)
void CTX_wm_menu_set(bContext *C, ARegion *menu)
{
+ if (menu) {
+ BLI_assert(menu->regiontype == RGN_TYPE_TEMPORARY);
+ }
C->wm.menu = menu;
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 7332f3ee776..437e290883e 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -8221,18 +8221,65 @@ static uiBut *ui_context_button_active(ARegion *ar, bool (*but_check_cb)(uiBut *
return but_found;
}
+/**
+ * Fine the parent non-popup menu.
+ *
+ * \param menu_region: Typically the result of #CTX_wm_menu.
+ */
+static ARegion *ui_context_menu_find_parent(ARegion *menu_region)
+{
+ while (menu_region) {
+ uiBlock *block = menu_region->uiblocks.first;
+ if (block == NULL) {
+ break;
+ }
+ if (!ui_block_is_menu(block)) {
+ return menu_region;
+ }
+ /* Find the menu that opened this. */
+ if (block->handle != NULL) {
+ menu_region = block->handle->ctx_menu;
+ }
+ }
+ return NULL;
+}
+
static bool ui_context_rna_button_active_test(uiBut *but)
{
return (but->rnapoin.data != NULL);
}
static uiBut *ui_context_rna_button_active(const bContext *C)
{
- return ui_context_button_active(CTX_wm_region(C), ui_context_rna_button_active_test);
+ ARegion *ar_active = CTX_wm_menu(C);
+ ARegion *ar_array[] = {ui_context_menu_find_parent(ar_active), CTX_wm_region(C)};
+ uiBut *but = NULL;
+ for (int i = 0; i < ARRAY_SIZE(ar_array); i++) {
+ but = ui_context_button_active(ar_array[i], ui_context_rna_button_active_test);
+ if (but) {
+ break;
+ }
+ }
+ if (but) {
+ printf("Found button %s\n", but->drawstr);
+ }
+ return but;
}
uiBut *UI_context_active_but_get(const struct bContext *C)
{
- return ui_context_button_active(CTX_wm_region(C), NULL);
+ ARegion *ar_active = CTX_wm_menu(C);
+ ARegion *ar_array[] = {ui_context_menu_find_parent(ar_active), CTX_wm_region(C)};
+ uiBut *but = NULL;
+ for (int i = 0; i < ARRAY_SIZE(ar_array); i++) {
+ but = ui_context_button_active(ar_array[i], NULL);
+ if (but) {
+ break;
+ }
+ }
+ if (but) {
+ printf("Button found: '%s'\n", but->drawstr);
+ }
+ return but;
}
uiBut *UI_region_active_but_get(ARegion *ar)
@@ -9360,6 +9407,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
if (but) {
ScrArea *ctx_area = CTX_wm_area(C);
ARegion *ctx_region = CTX_wm_region(C);
+ ARegion *ctx_menu = CTX_wm_menu(C);
if (menu->ctx_area) {
CTX_wm_area_set(C, menu->ctx_area);
@@ -9367,6 +9415,9 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
if (menu->ctx_region) {
CTX_wm_region_set(C, menu->ctx_region);
}
+ if (menu->ctx_menu) {
+ CTX_wm_menu_set(C, menu->ctx_menu);
+ }
retval = ui_handle_button_event(C, event, but);
@@ -9376,6 +9427,9 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
if (menu->ctx_region) {
CTX_wm_region_set(C, ctx_region);
}
+ if (menu->ctx_menu) {
+ CTX_wm_menu_set(C, ctx_menu);
+ }
}
else {
retval = ui_handle_button_over(C, event, ar);
@@ -10448,8 +10502,11 @@ static int ui_handle_menus_recursive(bContext *C,
inside = BLI_rctf_isect_pt(&block->rect, mx, my);
}
+ ARegion *menu_region = CTX_wm_menu(C);
+ CTX_wm_menu_set(C, submenu->region);
retval = ui_handle_menus_recursive(
C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
+ CTX_wm_menu_set(C, menu_region);
}
}
@@ -10655,7 +10712,9 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
if (data->menu) {
+ CTX_wm_menu_set(C, data->menu->region);
retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false, false);
+ CTX_wm_menu_set(C, menu_region);
}
/* handle events for the activated button */
@@ -10779,6 +10838,8 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
}
}
+ CTX_wm_region_set(C, menu_region);
+
/* delayed apply callbacks */
ui_apply_but_funcs_after(C);
@@ -10791,8 +10852,6 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
}
}
- CTX_wm_region_set(C, menu_region);
-
return retval;
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 3fe2750e070..786d6474632 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -592,6 +592,7 @@ struct uiPopupBlockHandle {
struct wmOperatorType *optype;
ScrArea *ctx_area;
ARegion *ctx_region;
+ ARegion *ctx_menu;
int opcontext;
/* return values */
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 867ac652505..840c8f5744f 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -373,11 +373,13 @@ static void ui_block_region_refresh(const bContext *C, ARegion *ar)
{
ScrArea *ctx_area = CTX_wm_area(C);
ARegion *ctx_region = CTX_wm_region(C);
+ ARegion *ctx_menu = CTX_wm_menu(C);
uiBlock *block;
if (ar->do_draw & RGN_REFRESH_UI) {
ScrArea *handle_ctx_area;
ARegion *handle_ctx_region;
+ ARegion *handle_ctx_menu;
uiBlock *block_next;
ar->do_draw &= ~RGN_REFRESH_UI;
@@ -388,6 +390,7 @@ static void ui_block_region_refresh(const bContext *C, ARegion *ar)
if (handle->can_refresh) {
handle_ctx_area = handle->ctx_area;
handle_ctx_region = handle->ctx_region;
+ handle_ctx_menu = handle->ctx_menu;
if (handle_ctx_area) {
CTX_wm_area_set((bContext *)C, handle_ctx_area);
@@ -395,6 +398,9 @@ static void ui_block_region_refresh(const bContext *C, ARegion *ar)
if (handle_ctx_region) {
CTX_wm_region_set((bContext *)C, handle_ctx_region);
}
+ if (handle_ctx_menu) {
+ CTX_wm_menu_set((bContext *)C, handle_ctx_menu);
+ }
uiBut *but = handle->popup_create_vars.but;
ARegion *butregion = handle->popup_create_vars.butregion;
@@ -405,6 +411,7 @@ static void ui_block_region_refresh(const bContext *C, ARegion *ar)
CTX_wm_area_set((bContext *)C, ctx_area);
CTX_wm_region_set((bContext *)C, ctx_region);
+ CTX_wm_menu_set((bContext *)C, ctx_menu);
}
static void ui_block_region_draw(const bContext *C, ARegion *ar)
@@ -575,7 +582,9 @@ uiBlock *ui_popup_block_refresh(bContext *C,
{
const int margin = UI_POPUP_MARGIN;
wmWindow *window = CTX_wm_window(C);
+ ARegion *menu_region = CTX_wm_menu(C);
ARegion *ar = handle->region;
+ CTX_wm_menu_set(C, handle->ctx_menu);
uiBlockCreateFunc create_func = handle->popup_create_vars.create_func;
uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
@@ -766,6 +775,8 @@ uiBlock *ui_popup_block_refresh(bContext *C,
window->eventstate = event_back;
#endif
+ CTX_wm_menu_set(C, menu_region);
+
return block;
}
@@ -797,6 +808,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
/* store context for operator */
handle->ctx_area = CTX_wm_area(C);
handle->ctx_region = CTX_wm_region(C);
+ handle->ctx_menu = CTX_wm_menu(C);
/* store vars to refresh popup (RGN_REFRESH_UI) */
handle->popup_create_vars.create_func = create_func;