Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-02-13 08:18:11 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-02-13 09:02:52 +0300
commit57d0e4969d45a503102ee91329c695fe86977c02 (patch)
treedf350e4355b8de67646eebf3c20c62d9f969921f /source/blender/editors
parent60066b0b80f68e8cfc696998bd2cdffaffbe4f4b (diff)
Fix crash using 'activate_init' in popup menus
Reported in T71112
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/UI_interface.h5
-rw-r--r--source/blender/editors/interface/interface.c32
2 files changed, 30 insertions, 7 deletions
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;
}