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>2019-02-19 07:18:56 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-02-19 08:17:21 +0300
commitf88ea20285891d516c91c976239f95994f73abf3 (patch)
treeef07c2513dcfc688d9c6cdd2fa8aa2fdf8b98d32
parenteae2942474fa06b369b3fc6ebdeddad90ca38d43 (diff)
WM: move operator handler to it's own type
-rw-r--r--source/blender/editors/space_script/script_edit.c16
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c56
-rw-r--r--source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h7
-rw-r--r--source/blender/windowmanager/intern/wm.c22
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c176
-rw-r--r--source/blender/windowmanager/intern/wm_files.c19
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c6
-rw-r--r--source/blender/windowmanager/wm_event_system.h27
8 files changed, 185 insertions, 144 deletions
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index 9b5f3d634c9..4b5cd6b7166 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -88,13 +89,14 @@ static bool script_test_modal_operators(bContext *C)
wm = CTX_wm_manager(C);
for (win = wm->windows.first; win; win = win->next) {
- wmEventHandler *handler;
-
- for (handler = win->modalhandlers.first; handler; handler = handler->next) {
- if (handler->op) {
- wmOperatorType *ot = handler->op->type;
- if (ot->ext.srna) {
- return true;
+ LISTBASE_FOREACH (wmEventHandler *, handler_base, &win->modalhandlers) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->op != NULL) {
+ wmOperatorType *ot = handler->op->type;
+ if (ot->ext.srna) {
+ return true;
+ }
}
}
}
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 8b6be7bb624..b1e35943b6c 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -690,21 +690,21 @@ void WM_gizmomap_add_handlers(ARegion *ar, wmGizmoMap *gzmap)
}
void wm_gizmomaps_handled_modal_update(
- bContext *C, wmEvent *event, wmEventHandler *handler)
+ bContext *C, wmEvent *event, wmEventHandler_Op *handler)
{
const bool modal_running = (handler->op != NULL);
/* happens on render or when joining areas */
- if (!handler->op_region || !handler->op_region->gizmo_map) {
+ if (!handler->context.region || !handler->context.region->gizmo_map) {
return;
}
- wmGizmoMap *gzmap = handler->op_region->gizmo_map;
+ wmGizmoMap *gzmap = handler->context.region->gizmo_map;
wmGizmo *gz = wm_gizmomap_modal_get(gzmap);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- wm_gizmomap_handler_context(C, handler);
+ wm_gizmomap_handler_context_op(C, handler);
/* regular update for running operator */
if (modal_running) {
@@ -830,41 +830,41 @@ bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, const int action)
* Prepare context for gizmo handling (but only if area/region is
* part of screen). Version of #wm_handler_op_context for gizmos.
*/
-void wm_gizmomap_handler_context(bContext *C, wmEventHandler *handler)
+void wm_gizmomap_handler_context_op(bContext *C, wmEventHandler_Op *handler)
{
bScreen *screen = CTX_wm_screen(C);
if (screen) {
- if (handler->op_area == NULL) {
- /* do nothing in this context */
+ ScrArea *sa;
+
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa == handler->context.area) {
+ break;
+ }
+ }
+ if (sa == NULL) {
+ /* when changing screen layouts with running modal handlers (like render display), this
+ * is not an error to print */
+ printf("internal error: modal gizmo-map handler has invalid area\n");
}
else {
- ScrArea *sa;
-
- for (sa = screen->areabase.first; sa; sa = sa->next)
- if (sa == handler->op_area)
+ ARegion *ar;
+ CTX_wm_area_set(C, sa);
+ for (ar = sa->regionbase.first; ar; ar = ar->next)
+ if (ar == handler->context.region)
break;
- if (sa == NULL) {
- /* when changing screen layouts with running modal handlers (like render display), this
- * is not an error to print */
- if (handler->type != WM_HANDLER_TYPE_GIZMO) {
- printf("internal error: modal gizmo-map handler has invalid area\n");
- }
- }
- else {
- ARegion *ar;
- CTX_wm_area_set(C, sa);
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar == handler->op_region)
- break;
- /* XXX no warning print here, after full-area and back regions are remade */
- if (ar)
- CTX_wm_region_set(C, ar);
- }
+ /* XXX no warning print here, after full-area and back regions are remade */
+ if (ar)
+ CTX_wm_region_set(C, ar);
}
}
}
+void wm_gizmomap_handler_context_gizmo(bContext *UNUSED(C), wmEventHandler_Gizmo *UNUSED(handler))
+{
+ /* pass */
+}
+
bool WM_gizmomap_cursor_set(const wmGizmoMap *gzmap, wmWindow *win)
{
wmGizmo *gz = gzmap->gzmap_context.highlight;
diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
index 4a0e8f21bcb..c7a6b816dd6 100644
--- a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
+++ b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
@@ -33,6 +33,8 @@
#define __WM_GIZMO_WMAPI_H__
struct wmEventHandler;
+struct wmEventHandler_Gizmo;
+struct wmEventHandler_Op;
struct wmGizmoMap;
struct wmOperator;
struct wmOperatorType;
@@ -65,8 +67,9 @@ void wm_gizmomap_remove(struct wmGizmoMap *gzmap);
void wm_gizmos_keymap(struct wmKeyConfig *keyconf);
void wm_gizmomaps_handled_modal_update(
- bContext *C, struct wmEvent *event, struct wmEventHandler *handler);
-void wm_gizmomap_handler_context(bContext *C, struct wmEventHandler *handler);
+ bContext *C, struct wmEvent *event, struct wmEventHandler_Op *handler);
+void wm_gizmomap_handler_context_op(bContext *C, struct wmEventHandler_Op *handler);
+void wm_gizmomap_handler_context_gizmo(bContext *C, struct wmEventHandler_Gizmo *handler);
struct wmGizmo *wm_gizmomap_highlight_find(
struct wmGizmoMap *gzmap, bContext *C, const struct wmEvent *event,
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index ce309284ff0..72b906ce853 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -197,17 +197,17 @@ 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;
+ for (int i = 0; i < ARRAY_SIZE(lb); i++) {
+ for (wmEventHandler *handler_base = lb[i]->first; handler_base; handler_base = handler_base->next) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ 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->base.flag |= WM_HANDLER_DO_FREE;
+ WM_operator_free(handler->op);
+ handler->op = NULL;
+ }
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index c47247b794d..95dcae9ef48 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1681,19 +1681,19 @@ void wm_event_free_handler(wmEventHandler *handler)
}
/* only set context when area/region is part of screen */
-static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wmEvent *event)
+static void wm_handler_op_context(bContext *C, wmEventHandler_Op *handler, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
if (screen && handler->op) {
- if (handler->op_area == NULL)
+ if (handler->context.area == NULL)
CTX_wm_area_set(C, NULL);
else {
ScrArea *sa = NULL;
ED_screen_areas_iter(win, screen, sa_iter) {
- if (sa_iter == handler->op_area) {
+ if (sa_iter == handler->context.area) {
sa = sa_iter;
break;
}
@@ -1712,9 +1712,9 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm
CTX_wm_area_set(C, sa);
if (op && (op->flag & OP_IS_MODAL_CURSOR_REGION)) {
- ar = BKE_area_find_region_xy(sa, handler->op_region_type, event->x, event->y);
+ ar = BKE_area_find_region_xy(sa, handler->context.region_type, event->x, event->y);
if (ar) {
- handler->op_region = ar;
+ handler->context.region = ar;
}
}
else {
@@ -1723,7 +1723,7 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm
if (ar == NULL) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar == handler->op_region) {
+ if (ar == handler->context.region) {
break;
}
}
@@ -1745,28 +1745,33 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
/* C is zero on freeing database, modal handlers then already were freed */
while ((handler_base = BLI_pophead(handlers))) {
- if (handler_base->op) {
- wmWindow *win = CTX_wm_window(C);
- if (handler_base->op->type->cancel) {
- ScrArea *area = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->op) {
+ wmWindow *win = CTX_wm_window(C);
+ if (handler->op->type->cancel) {
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
- wm_handler_op_context(C, handler_base, win->eventstate);
+ wm_handler_op_context(C, handler, win->eventstate);
- if (handler_base->op->type->flag & OPTYPE_UNDO)
- wm->op_undo_depth++;
+ if (handler->op->type->flag & OPTYPE_UNDO) {
+ wm->op_undo_depth++;
+ }
- handler_base->op->type->cancel(C, handler_base->op);
+ handler->op->type->cancel(C, handler->op);
- if (handler_base->op->type->flag & OPTYPE_UNDO)
- wm->op_undo_depth--;
+ if (handler->op->type->flag & OPTYPE_UNDO) {
+ wm->op_undo_depth--;
+ }
- CTX_wm_area_set(C, area);
- CTX_wm_region_set(C, region);
- }
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+ }
- WM_cursor_grab_disable(win, NULL);
- WM_operator_free(handler_base->op);
+ WM_cursor_grab_disable(win, NULL);
+ WM_operator_free(handler->op);
+ }
}
else if (handler_base->type == WM_HANDLER_TYPE_UI) {
wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base;
@@ -1958,13 +1963,17 @@ static void wm_event_modalmap_end(wmEvent *event, bool dbl_click_disabled)
}
/* Warning: this function removes a modal handler, when finished */
-static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler,
- wmEvent *event, PointerRNA *properties)
+static int wm_handler_operator_call(
+ bContext *C, ListBase *handlers, wmEventHandler *handler_base,
+ wmEvent *event, PointerRNA *properties)
{
int retval = OPERATOR_PASS_THROUGH;
/* derived, modal or blocking operator */
- if (handler->op) {
+ if ((handler_base->type == WM_HANDLER_TYPE_OP) &&
+ (((wmEventHandler_Op *)handler_base)->op != NULL))
+ {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
wmOperator *op = handler->op;
wmOperatorType *ot = op->type;
@@ -2045,7 +2054,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
WM_cursor_grab_disable(CTX_wm_window(C), NULL);
BLI_remlink(handlers, handler);
- wm_event_free_handler(handler);
+ wm_event_free_handler(&handler->base);
/* prevent silly errors from operator users */
//retval &= ~OPERATOR_PASS_THROUGH;
@@ -2062,11 +2071,11 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (ot && wm_operator_check_locked_interface(C, ot)) {
bool use_last_properties = true;
PointerRNA tool_properties = {{0}};
- const bool is_tool = (handler->keymap_tool != NULL);
+ const bool is_tool = (handler_base->keymap_tool != NULL);
const bool use_tool_properties = is_tool;
if (use_tool_properties) {
- WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot);
+ WM_toolsystem_ref_properties_init_for_keymap(handler_base->keymap_tool, &tool_properties, properties, ot);
properties = &tool_properties;
use_last_properties = false;
}
@@ -2080,7 +2089,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
/* Link gizmo if 'WM_GIZMOGROUPTYPE_TOOL_INIT' is set. */
if (retval & OPERATOR_FINISHED) {
if (is_tool) {
- bToolRef_Runtime *tref_rt = handler->keymap_tool->runtime;
+ bToolRef_Runtime *tref_rt = handler_base->keymap_tool->runtime;
if (tref_rt->gizmo_group[0]) {
const char *idname = tref_rt->gizmo_group;
wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
@@ -2120,7 +2129,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
}
/* fileselect handlers are only in the window queue, so it's safe to switch screens or area types */
-static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHandler *handler, int val)
+static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHandler_Op *handler, int val)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile;
@@ -2134,12 +2143,12 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
/* sa can be null when window A is active, but mouse is over window B
* in this case, open file select in original window A. Also don't
* use global areas. */
- if (handler->op_area == NULL || ED_area_is_global(handler->op_area)) {
+ if (handler->context.area == NULL || ED_area_is_global(handler->context.area)) {
bScreen *screen = CTX_wm_screen(C);
sa = (ScrArea *)screen->areabase.first;
}
else {
- sa = handler->op_area;
+ sa = handler->context.area;
}
if (sa->full) {
@@ -2270,7 +2279,7 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_area_set(C, NULL);
- wm_event_free_handler(handler);
+ wm_event_free_handler(&handler->base);
action = WM_HANDLER_BREAK;
break;
@@ -2280,7 +2289,8 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
return action;
}
-static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, const wmEvent *event)
+static int wm_handler_fileselect_call(
+ bContext *C, ListBase *handlers, wmEventHandler_Op *handler, const wmEvent *event)
{
int action = WM_HANDLER_CONTINUE;
@@ -2413,10 +2423,13 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
action |= wm_handler_ui_call(C, handler_ui, event, always_pass);
}
}
- else if (handler->op_is_fileselect) {
+ else if ((handler->type == WM_HANDLER_TYPE_OP) &&
+ ((wmEventHandler_Op *)handler)->is_fileselect)
+ {
+ wmEventHandler_Op *handler_op = (wmEventHandler_Op *)handler;
if (!wm->is_interface_locked) {
/* screen context changes here */
- action |= wm_handler_fileselect_call(C, handlers, handler, event);
+ action |= wm_handler_fileselect_call(C, handlers, handler_op, event);
}
}
else if (handler->dropboxes) {
@@ -2475,7 +2488,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
WM_gizmomap_tag_refresh(handler_gz->gizmo_map);
}
- wm_gizmomap_handler_context(C, handler);
+ wm_gizmomap_handler_context_gizmo(C, handler_gz);
wm_region_mouse_co(C, event);
/* handle gizmo highlighting */
@@ -2540,8 +2553,6 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
if (wm_eventmatch(event, kmi)) {
struct wmEventHandler_KeymapFn keymap_callback = handler->keymap_callback;
- wmOperator *op = handler->op;
-
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
/* weak, but allows interactive callback to not use rawkey */
@@ -2550,9 +2561,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
CTX_wm_gizmo_group_set(C, gzgroup);
/* handler->op is called later, we want keymap op to be triggered here */
- handler->op = NULL;
action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
- handler->op = op;
CTX_wm_gizmo_group_set(C, NULL);
@@ -2599,10 +2608,6 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
/* restore the area */
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
-
- if (handler->op) {
- action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
- }
}
else {
/* modal, swallows all */
@@ -3231,7 +3236,6 @@ void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval
*/
void WM_event_add_fileselect(bContext *C, wmOperator *op)
{
- wmEventHandler *handler, *handlernext;
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -3239,10 +3243,16 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
UI_popup_handlers_remove_all(C, &win->modalhandlers);
/* only allow 1 file selector open per window */
- for (handler = win->modalhandlers.first; handler; handler = handlernext) {
- handlernext = handler->next;
-
- if (handler->op_is_fileselect) {
+ for (wmEventHandler *handler_base = win->modalhandlers.first, *handler_base_next;
+ handler_base;
+ handler_base = handler_base_next)
+ {
+ handler_base_next = handler_base->next;
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->is_fileselect == false) {
+ continue;
+ }
bScreen *screen = CTX_wm_screen(C);
bool cancel_handler = true;
@@ -3267,12 +3277,13 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
}
}
- handler = MEM_callocN(sizeof(wmEventHandler), "fileselect handler");
+ wmEventHandler_Op *handler = MEM_callocN(sizeof(*handler), __func__);
+ handler->base.type = WM_HANDLER_TYPE_OP;
- handler->op_is_fileselect = true;
+ handler->is_fileselect = true;
handler->op = op;
- handler->op_area = CTX_wm_area(C);
- handler->op_region = CTX_wm_region(C);
+ handler->context.area = CTX_wm_area(C);
+ handler->context.region = CTX_wm_region(C);
BLI_addhead(&win->modalhandlers, handler);
@@ -3295,7 +3306,8 @@ static void WM_event_set_handler_flag(wmEventHandler *handler, int flag)
wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
- wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "event modal handler");
+ wmEventHandler_Op *handler = MEM_callocN(sizeof(*handler), __func__);
+ handler->base.type = WM_HANDLER_TYPE_OP;
wmWindow *win = CTX_wm_window(C);
/* operator was part of macro */
@@ -3305,12 +3317,13 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
/* mother macro opm becomes the macro element */
handler->op->opm = op;
}
- else
+ else {
handler->op = op;
+ }
- handler->op_area = CTX_wm_area(C); /* means frozen screen context for modal handlers! */
- handler->op_region = CTX_wm_region(C);
- handler->op_region_type = handler->op_region ? handler->op_region->regiontype : -1;
+ handler->context.area = CTX_wm_area(C); /* means frozen screen context for modal handlers! */
+ handler->context.region = CTX_wm_region(C);
+ handler->context.region_type = handler->context.region ? handler->context.region->regiontype : -1;
BLI_addhead(&win->modalhandlers, handler);
@@ -3318,7 +3331,7 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
WM_window_status_area_tag_redraw(win);
}
- return handler;
+ return &handler->base;
}
/**
@@ -3327,10 +3340,13 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
*/
void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
{
- for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
- /* fileselect handler is quite special... it needs to keep old area stored in handler, so don't change it */
- if ((handler->op_area == old_area) && (handler->op_is_fileselect == false)) {
- handler->op_area = new_area;
+ for (wmEventHandler *handler_base = win->modalhandlers.first; handler_base; handler_base = handler_base->next) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ /* fileselect handler is quite special... it needs to keep old area stored in handler, so don't change it */
+ if ((handler->context.area == old_area) && (handler->is_fileselect == false)) {
+ handler->context.area = new_area;
+ }
}
}
}
@@ -3341,10 +3357,13 @@ void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area,
*/
void WM_event_modal_handler_region_replace(wmWindow *win, const ARegion *old_region, ARegion *new_region)
{
- for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
- if (handler->op_region == old_region) {
- handler->op_region = new_region;
- handler->op_region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
+ for (wmEventHandler *handler_base = win->modalhandlers.first; handler_base; handler_base = handler_base->next) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->context.region == old_region) {
+ handler->context.region = new_region;
+ handler->context.region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
+ }
}
}
}
@@ -3875,7 +3894,7 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
/* let's skip windows having modal handlers now */
/* potential XXX ugly... I wouldn't have added a modalhandlers list (introduced in rev 23331, ton) */
for (handler = win->modalhandlers.first; handler; handler = handler->next) {
- if ((handler->type == WM_HANDLER_TYPE_UI) || handler->op) {
+ if (ELEM(handler->type, WM_HANDLER_TYPE_UI, WM_HANDLER_TYPE_OP)) {
return NULL;
}
}
@@ -4728,14 +4747,17 @@ bool WM_window_modal_keymap_status_draw(
{
wmKeyMap *keymap = NULL;
wmOperator *op = NULL;
- for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
- if (handler->op) {
- /* 'handler->keymap' could be checked too, seems not to be used. */
- wmKeyMap *keymap_test = handler->op->type->modalkeymap;
- if (keymap_test && keymap_test->modal_items) {
- keymap = keymap_test;
- op = handler->op;
- break;
+ for (wmEventHandler *handler_base = win->modalhandlers.first; handler_base; handler_base = handler_base->next) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->op != NULL) {
+ /* 'handler->keymap' could be checked too, seems not to be used. */
+ wmKeyMap *keymap_test = handler->op->type->modalkeymap;
+ if (keymap_test && keymap_test->modal_items) {
+ keymap = keymap_test;
+ op = handler->op;
+ break;
+ }
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index c3326d4ffd2..670c6604dd0 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -1393,21 +1393,22 @@ void WM_autosave_init(wmWindowManager *wm)
void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(wt))
{
- wmWindow *win;
- wmEventHandler *handler;
char filepath[FILE_MAX];
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
/* if a modal operator is running, don't autosave, but try again in 10 seconds */
- for (win = wm->windows.first; win; win = win->next) {
- for (handler = win->modalhandlers.first; handler; handler = handler->next) {
- if (handler->op) {
- wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0);
- if (G.debug) {
- printf("Skipping auto-save, modal operator running, retrying in ten seconds...\n");
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ for (wmEventHandler *handler_base = win->modalhandlers.first; handler_base; handler_base = handler_base->next) {
+ if (handler_base->type == WM_HANDLER_TYPE_OP) {
+ wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
+ if (handler->op) {
+ wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0);
+ if (G.debug) {
+ printf("Skipping auto-save, modal operator running, retrying in ten seconds...\n");
+ }
+ return;
}
- return;
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 7e0481ba5eb..860e0bc6288 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -409,12 +409,12 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* if new operator is modal and also added its own handler */
if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
wmWindow *win = CTX_wm_window(C);
- wmEventHandler *handler;
+ wmEventHandler_Op *handler;
- handler = BLI_findptr(&win->modalhandlers, op, offsetof(wmEventHandler, op));
+ handler = BLI_findptr(&win->modalhandlers, op, offsetof(wmEventHandler_Op, op));
if (handler) {
BLI_remlink(&win->modalhandlers, handler);
- wm_event_free_handler(handler);
+ wm_event_free_handler(&handler->base);
}
/* if operator is blocking, grab cursor
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 3e9793521ae..5346ec516ee 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -45,6 +45,7 @@ enum eWM_EventHandlerType {
WM_HANDLER_TYPE_DEFAULT,
WM_HANDLER_TYPE_GIZMO,
WM_HANDLER_TYPE_UI,
+ WM_HANDLER_TYPE_OP,
};
typedef struct wmEventHandler {
@@ -61,13 +62,6 @@ typedef struct wmEventHandler {
struct bToolRef *keymap_tool;
- /* modal operator handler */
- bool op_is_fileselect;
- wmOperator *op; /* for derived/modal handlers */
- struct ScrArea *op_area; /* for derived/modal handlers */
- struct ARegion *op_region; /* for derived/modal handlers */
- short op_region_type; /* for derived/modal handlers */
-
/* drop box handler */
ListBase *dropboxes;
@@ -97,6 +91,25 @@ typedef struct wmEventHandler_UI {
} context;
} wmEventHandler_UI;
+/** #WM_HANDLER_TYPE_OP */
+typedef struct wmEventHandler_Op {
+ wmEventHandler base;
+
+ /** Operator can be NULL. */
+ wmOperator *op;
+
+ /** Hack, special case for file-select. */
+ bool is_fileselect;
+
+ /** Store context for this handler for derived/modal handlers. */
+ struct {
+ struct ScrArea *area;
+ struct ARegion *region;
+ short region_type;
+ } context;
+} wmEventHandler_Op;
+
+
/* wm_event_system.c */
void wm_event_free_all (wmWindow *win);
void wm_event_free (wmEvent *event);