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/makesrna/intern/rna_wm.c5
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm.c25
-rw-r--r--source/blender/windowmanager/wm_event_system.h17
4 files changed, 37 insertions, 11 deletions
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index c0fb2a7238f..0c1c5d8f64a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -853,8 +853,11 @@ static void rna_Operator_unregister(struct Main *bmain, StructRNA *type)
/* update while blender is running */
wm = bmain->wm.first;
- if (wm)
+ if (wm) {
WM_operator_stack_clear(wm);
+
+ WM_operator_handlers_clear(wm, ot);
+ }
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
RNA_struct_free_extension(type, &ot->ext);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 1b8bf29d92a..bea54154e47 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -202,6 +202,7 @@ int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, con
/* operator api */
void WM_operator_free (struct wmOperator *op);
void WM_operator_stack_clear(struct wmWindowManager *wm);
+void WM_operator_handlers_clear(wmWindowManager *wm, struct wmOperatorType *ot);
struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
struct GHashIterator *WM_operatortype_iter(void);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 53e67e91bd2..a01f7301ec2 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -149,6 +149,31 @@ void WM_operator_stack_clear(wmWindowManager *wm)
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
}
+/**
+ * This function is needed in the case when an addon id disabled
+ * while a modal operator it defined is running.
+ */
+void WM_operator_handlers_clear(wmWindowManager *wm, wmOperatorType *ot)
+{
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ ListBase *lb[2] = {&win->handlers, &win->modalhandlers};
+ wmEventHandler *handler;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ for (handler = lb[i]->first; handler; handler = handler->next) {
+ if (handler->op && handler->op->type == ot) {
+ /* don't run op->cancel because it needs the context,
+ * assume whoever unregisters the operator will cleanup */
+ handler->flag |= WM_HANDLER_DO_FREE;
+ WM_operator_free(handler->op);
+ handler->op = NULL;
+ }
+ }
+ }
+ }
+}
/* ************ uiListType handling ************** */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 2fbfdc41bce..d12e1d47fa0 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -45,7 +45,8 @@ struct ARegion;
typedef struct wmEventHandler {
struct wmEventHandler *next, *prev;
- int type, flag; /* type default=0, rest is custom */
+ int type; /* WM_HANDLER_DEFAULT, ... */
+ int flag; /* WM_HANDLER_BLOCKING, ... */
/* keymap handler */
wmKeyMap *keymap; /* pointer to builtin/custom keymaps */
@@ -72,21 +73,17 @@ typedef struct wmEventHandler {
} 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
-
-
-
/* custom types for handlers, for signalling, freeing */
enum {
WM_HANDLER_DEFAULT,
WM_HANDLER_FILESELECT
};
+/* handler flag */
+enum {
+ WM_HANDLER_BLOCKING = 1, /* after this handler all others are ignored */
+ WM_HANDLER_DO_FREE = 2 /* handler tagged to be freed in wm_handlers_do() */
+};
/* wm_event_system.c */
void wm_event_free_all (wmWindow *win);