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:
-rw-r--r--source/blender/editors/interface/interface_handlers.c6
-rw-r--r--source/blender/editors/interface/interface_panel.c2
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c29
-rw-r--r--source/blender/windowmanager/wm_event_system.h2
5 files changed, 30 insertions, 11 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index d3aa5bc9132..cf11effc57b 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4898,7 +4898,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
}
else {
if(button_modal_state(data->state))
- WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data);
+ WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, 1); /* 1 = postpone free */
}
}
@@ -6154,7 +6154,7 @@ static void ui_handler_remove_popup(bContext *C, void *userdata)
void UI_add_region_handlers(ListBase *handlers)
{
- WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL);
+ WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, 0);
WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL);
}
@@ -6165,7 +6165,7 @@ void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *
void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup)
{
- WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup);
+ WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, 0);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index b47194ba1b4..6677f2b1bae 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1211,7 +1211,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
MEM_freeN(data);
pa->activedata= NULL;
- WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa);
+ WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
}
else {
if(!data) {
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index dafa05fd974..1b4fff8cd13 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -173,7 +173,7 @@ struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBas
void (*remove)(struct bContext *C, void *userdata), void *userdata);
void WM_event_remove_ui_handler(ListBase *handlers,
int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
- void (*remove)(struct bContext *C, void *userdata), void *userdata);
+ void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone);
void WM_event_remove_area_handler(struct ListBase *handlers, void *area);
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 2b74d35d59e..c9e2567a45b 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1452,10 +1452,13 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
/* modal handlers can get removed in this loop, we keep the loop this way */
for(handler= handlers->first; handler; handler= nexthandler) {
+
nexthandler= handler->next;
-
- /* optional boundbox */
- if(handler_boundbox_test(handler, event)) {
+
+ /* during this loop, ui handlers for nested menus can tag multiple handlers free */
+ if(handler->flag & WM_HANDLER_DO_FREE);
+ /* optional boundbox */
+ else if(handler_boundbox_test(handler, event)) {
/* in advance to avoid access to freed event on window close */
always_pass= wm_event_always_pass(event);
@@ -1534,6 +1537,13 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
}
}
+ /* modal ui handler can be tagged to be freed */
+ if(handler->flag & WM_HANDLER_DO_FREE) {
+ BLI_remlink(handlers, handler);
+ wm_event_free_handler(handler);
+ }
+
+
/* XXX fileread case */
if(CTX_wm_window(C)==NULL)
return action;
@@ -2067,14 +2077,21 @@ wmEventHandler *WM_event_add_ui_handler(const bContext *C, ListBase *handlers, w
return handler;
}
-void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata)
+/* set "postpone" for win->modalhandlers, this is in a running for() loop in wm_handlers_do() */
+void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata, int postpone)
{
wmEventHandler *handler;
for(handler= handlers->first; handler; handler= handler->next) {
if(handler->ui_handle == func && handler->ui_remove == remove && handler->ui_userdata == userdata) {
- BLI_remlink(handlers, handler);
- wm_event_free_handler(handler);
+ /* handlers will be freed in wm_handlers_do() */
+ if(postpone) {
+ handler->flag |= WM_HANDLER_DO_FREE;
+ }
+ else {
+ BLI_remlink(handlers, handler);
+ wm_event_free_handler(handler);
+ }
break;
}
}
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 6ad9d1daede..cd110d3bc1a 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -78,6 +78,8 @@ typedef struct wmEventHandler {
/* handler flag */
/* after this handler all others are ignored */
#define WM_HANDLER_BLOCKING 1
+ /* handler tagged to be freed in wm_handlers_do() */
+#define WM_HANDLER_DO_FREE 2