[Bf-blender-cvs] [8f69c914080] master: Fix T93410: Crash hiding a region from Python used by a popover

Campbell Barton noreply at git.blender.org
Thu Dec 2 06:09:30 CET 2021


Commit: 8f69c914080a7fe9555f7126362f08c368a8069d
Author: Campbell Barton
Date:   Thu Dec 2 15:46:14 2021 +1100
Branches: master
https://developer.blender.org/rB8f69c914080a7fe9555f7126362f08c368a8069d

Fix T93410: Crash hiding a region from Python used by a popover

Close all active buttons when hiding a region as this can be called
from Python a popover is open from that region.

Failure to do this causes the popover to read from the freed button.

Also rename UI_screen_free_active_but to
UI_screen_free_active_but_highlight since it only frees highlighted
buttons.

===================================================================

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_ops.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/screen/screen_edit.c

===================================================================

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 1dbb486ad72..023a1a64daf 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -735,7 +735,9 @@ void UI_block_set_search_only(uiBlock *block, bool search_only);
 void UI_block_free(const struct bContext *C, uiBlock *block);
 void UI_blocklist_free(const struct bContext *C, struct ARegion *region);
 void UI_blocklist_free_inactive(const struct bContext *C, struct ARegion *region);
-void UI_screen_free_active_but(const struct bContext *C, struct bScreen *screen);
+
+void UI_screen_free_active_but_highlight(const struct bContext *C, struct bScreen *screen);
+void UI_region_free_active_but_all(struct bContext *context, struct ARegion *region);
 
 void UI_block_region_set(uiBlock *block, struct ARegion *region);
 
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fe540c3624c..14df5ec68ac 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -439,11 +439,11 @@ typedef struct uiHandleButtonData {
   float ungrab_mval[2];
 #endif
 
-  /* menu open (watch UI_screen_free_active_but) */
+  /* Menu open, see: #UI_screen_free_active_but_highlight. */
   uiPopupBlockHandle *menu;
   int menuretval;
 
-  /* search box (watch UI_screen_free_active_but) */
+  /* Search box see: #UI_screen_free_active_but_highlight. */
   ARegion *searchbox;
 #ifdef USE_KEYNAV_LIMIT
   struct uiKeyNavLock searchbox_keynav_state;
@@ -11674,8 +11674,20 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
 /** \name Public Utilities
  * \{ */
 
+void UI_region_free_active_but_all(bContext *C, ARegion *region)
+{
+  LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+    LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
+      if (but->active == NULL) {
+        continue;
+      }
+      ui_but_active_free(C, but);
+    }
+  }
+}
+
 /* is called by notifier */
-void UI_screen_free_active_but(const bContext *C, bScreen *screen)
+void UI_screen_free_active_but_highlight(const bContext *C, bScreen *screen)
 {
   wmWindow *win = CTX_wm_window(C);
 
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index e1fd7386408..03422e8f520 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1408,7 +1408,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
     int ret;
 
     /* needed else the active button does not get tested */
-    UI_screen_free_active_but(C, CTX_wm_screen(C));
+    UI_screen_free_active_but_highlight(C, CTX_wm_screen(C));
 
     // printf("%s: begin\n", __func__);
 
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 0190e7b7cee..dc7cbb96e96 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -2119,6 +2119,12 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg
 {
   if (region->flag & RGN_FLAG_HIDDEN) {
     WM_event_remove_handlers(C, &region->handlers);
+    /* Needed to close any open pop-overs which would otherwise remain open,
+     * crashing on attempting to refresh. See: T93410.
+     *
+     * When #ED_area_init frees buttons via #UI_blocklist_free a NULL context
+     * is passed, causing the free not to remove menus or their handlers. */
+    UI_region_free_active_but_all(C, region);
   }
 
   ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), area);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 3c8fb2e7446..92151ea01b3 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -955,7 +955,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
        * because it can undo setting the right button as active due
        * to delayed notifier handling. */
       if (C) {
-        UI_screen_free_active_but(C, screen);
+        UI_screen_free_active_but_highlight(C, screen);
       }
     }
   }



More information about the Bf-blender-cvs mailing list