diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index ba1703db895..1538b13cc62 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -699,6 +699,13 @@ ARegion *ED_area_find_region_xy_visual(const ScrArea *area, int regiontype, cons struct ARegionType *ED_area_type_hud(int space_type); void ED_area_type_hud_clear(struct wmWindowManager *wm, ScrArea *area_keep); void ED_area_type_hud_ensure(struct bContext *C, struct ScrArea *area); +/** + * Lookup the region the operation was executed in, and which should be used to redo the + * operation. The lookup is based on the region type, so it can return a different region when the + * same region type is present multiple times. + */ +ARegion *ED_area_type_hud_redo_region_find(const struct ScrArea *area, + const struct ARegion *hud_region); /** * Default key-maps, bit-flags (matches order of evaluation). diff --git a/source/blender/editors/interface/interface_region_hud.cc b/source/blender/editors/interface/interface_region_hud.cc index 3777f6ea315..3b78cfd41e4 100644 --- a/source/blender/editors/interface/interface_region_hud.cc +++ b/source/blender/editors/interface/interface_region_hud.cc @@ -385,4 +385,16 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area) region->visible = !((region->flag & RGN_FLAG_HIDDEN) || (region->flag & RGN_FLAG_TOO_SMALL)); } +ARegion *ED_area_type_hud_redo_region_find(const ScrArea *area, const ARegion *hud_region) +{ + BLI_assert(hud_region->regiontype == RGN_TYPE_HUD); + HudRegionData *hrd = static_cast(hud_region->regiondata); + + if (hrd->regionid == -1) { + return nullptr; + } + + return BKE_area_find_region_type(area, hrd->regionid); +} + /** \} */ diff --git a/source/blender/editors/undo/ed_undo.cc b/source/blender/editors/undo/ed_undo.cc index 7fcda51bc1d..d543d3eae70 100644 --- a/source/blender/editors/undo/ed_undo.cc +++ b/source/blender/editors/undo/ed_undo.cc @@ -668,14 +668,21 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op) if (op) { CLOG_INFO(&LOG, 1, "idname='%s'", op->type->idname); wmWindowManager *wm = CTX_wm_manager(C); + const ScrArea *area = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); /* keep in sync with logic in view3d_panel_operator_redo() */ ARegion *region_orig = CTX_wm_region(C); - ARegion *region_win = BKE_area_find_region_active_win(CTX_wm_area(C)); + /* If the redo is called from a HUD, this knows about the region type the operator was + * initially called in, so attempt to restore that. */ + ARegion *redo_region_from_hud = (region_orig->regiontype == RGN_TYPE_HUD) ? + ED_area_type_hud_redo_region_find(area, region_orig) : + nullptr; + ARegion *region_repeat = redo_region_from_hud ? redo_region_from_hud : + BKE_area_find_region_active_win(area); - if (region_win) { - CTX_wm_region_set(C, region_win); + if (region_repeat) { + CTX_wm_region_set(C, region_repeat); } if (WM_operator_repeat_check(C, op) && WM_operator_poll(C, op->type) &&