diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-09 10:00:33 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-09 10:00:33 +0400 |
commit | 9b5a2084bc1ca8f330faeb601d2b3c65efa98f3d (patch) | |
tree | 5047c0b51307ecc6a16a3d179d2ee82e7a7ffcb6 /source | |
parent | cecbb3498b245fbf2226c967001c4ab40b1c7b87 (diff) |
avoid having dangling panel pointers in the interface, unregistering addons could leave the interface pointing to freed memory.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 25 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui.c | 7 |
3 files changed, 33 insertions, 1 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 080367c4325..16b5526ca26 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -42,6 +42,7 @@ struct ID; struct Main; struct ListBase; struct ARegion; +struct ARegionType; struct ScrArea; struct wmWindow; struct wmWindowManager; @@ -660,6 +661,7 @@ void uiDrawPanels(const struct bContext *C, struct ARegion *ar); struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open); void uiEndPanel(uiBlock *block, int width, int height); void uiScalePanels(struct ARegion *ar, float new_width); +void uiPanelClearType(struct wmWindowManager *wm, const struct ARegionType *art, const struct PanelType *type); /* Handlers * diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 9fbf2fe8898..bcd49551784 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -306,6 +306,31 @@ void uiEndPanel(uiBlock *block, int width, int height) } } +void uiPanelClearType(wmWindowManager *wm, const ARegionType *art, const PanelType *type) +{ + wmWindow *win; + for (win = wm->windows.first; win; win = win->next) { + ScrArea *sa; + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->type == art) { + uiBlock *block, *nblock = ar->uiblocks.first; + while ((block = nblock)) { + nblock = block->next; + if (block->panel) { + if (block->panel->type == type) { + uiFreeBlock(block->evil_C, block); + BLI_remlink(&ar->uiblocks, block); + } + } + } + } + } + } + } +} + static void ui_offset_panel_block(uiBlock *block) { uiStyle *style = UI_GetStyleDraw(); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 137ffecac9a..cae9673906e 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -165,8 +165,9 @@ static void panel_draw_header(const bContext *C, Panel *pnl) RNA_parameter_list_free(&list); } -static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) +static void rna_Panel_unregister(Main *bmain, StructRNA *type) { + wmWindowManager *wm; ARegionType *art; PanelType *pt = RNA_struct_blender_type_get(type); @@ -174,6 +175,10 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) return; if (!(art = region_type_find(NULL, pt->space_type, pt->region_type))) return; + + for (wm = bmain->wm.first; wm; wm = wm->id.next) { + uiPanelClearType(wm, art, pt); + } RNA_struct_free_extension(type, &pt->ext); |