[Bf-blender-cvs] [57d0e4969d4] master: Fix crash using 'activate_init' in popup menus

Campbell Barton noreply at git.blender.org
Thu Feb 13 07:08:27 CET 2020


Commit: 57d0e4969d45a503102ee91329c695fe86977c02
Author: Campbell Barton
Date:   Thu Feb 13 16:18:11 2020 +1100
Branches: master
https://developer.blender.org/rB57d0e4969d45a503102ee91329c695fe86977c02

Fix crash using 'activate_init' in popup menus

Reported in T71112

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 3089d980f06..5bed153e995 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -723,6 +723,11 @@ void UI_but_drawflag_disable(uiBut *but, int flag);
 void UI_but_type_set_menu_from_pulldown(uiBut *but);
 
 /* special button case, only draw it when used actively, for outliner etc */
+bool UI_but_active_only_ex(const struct bContext *C,
+                           struct ARegion *ar,
+                           uiBlock *block,
+                           uiBut *but,
+                           bool remove_on_failure);
 bool UI_but_active_only(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but);
 bool UI_block_active_only_flagged_buttons(const struct bContext *C,
                                           struct ARegion *ar,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 8af8fdb06a1..a7eec8d42cd 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -849,7 +849,8 @@ static bool ui_but_update_from_old_block(const bContext *C,
 /* needed for temporarily rename buttons, such as in outliner or file-select,
  * they should keep calling uiDefButs to keep them alive */
 /* returns 0 when button removed */
-bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
+bool UI_but_active_only_ex(
+    const bContext *C, ARegion *ar, uiBlock *block, uiBut *but, const bool remove_on_failure)
 {
   uiBlock *oldblock;
   uiBut *oldbut;
@@ -873,27 +874,44 @@ bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *b
     ui_but_activate_event((bContext *)C, ar, but);
   }
   else if ((found == true) && (isactive == false)) {
-    BLI_remlink(&block->buttons, but);
-    ui_but_free(C, but);
+    if (remove_on_failure) {
+      BLI_remlink(&block->buttons, but);
+      ui_but_free(C, but);
+    }
     return false;
   }
 
   return true;
 }
 
+bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
+{
+  return UI_but_active_only_ex(C, ar, block, but, true);
+}
+
 bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *ar, uiBlock *block)
 {
   bool done = false;
   for (uiBut *but = block->buttons.first; but; but = but->next) {
-    if (!done && ui_but_is_editable(but)) {
-      if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
-        if (UI_but_active_only(C, ar, block, but)) {
+    if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
+      but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
+      if (ui_but_is_editable(but)) {
+        if (UI_but_active_only_ex(C, ar, block, but, false)) {
           done = true;
+          break;
         }
       }
     }
-    but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
   }
+
+  if (done) {
+    /* Run this in a second pass since it's possible activating the button
+     * removes the buttons being looped over. */
+    for (uiBut *but = block->buttons.first; but; but = but->next) {
+      but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
+    }
+  }
+
   return done;
 }



More information about the Bf-blender-cvs mailing list