WM: move operator handler to it's own type
authorCampbell Barton <ideasman42@gmail.com>
Tue, 19 Feb 2019 04:18:56 +0000 (15:18 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 19 Feb 2019 05:17:21 +0000 (16:17 +1100)
source/blender/editors/space_script/script_edit.c
source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_operator_type.c
source/blender/windowmanager/wm_event_system.h

index 9b5f3d634c9c977ef9b20710af6954fa98e8a294..4b5cd6b71668fe6c87848d602e94701117e0d4bc 100644 (file)
@@ -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;
+                                       }
                                }
                        }
                }
index 8b6be7bb624befd384b004c4c88b29308f3f1e1a..b1e35943b6c19070f4fe623ecef031ccf5160c95 100644 (file)
@@ -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;
index 4a0e8f21bcb6787f9a39eaf25de648782299d0a9..c7a6b816dd651d57adf687d6f990cea20f8ba92e 100644 (file)
@@ -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,
index ce309284ff045ebe6758be9a7a053e4b7a278a50..72b906ce853d03e7265bd8a37eb84ba3acd10e53 100644 (file)
@@ -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;
+                                       }
                                }
                        }
                }
index c47247b794d06a15af920eac00d4e44d1661cdc1..95dcae9ef489249e0ff490299ba665c50bbf3791 100644 (file)
@@ -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;
+                               }
                        }
                }
        }
index c3326d4ffd2cb97456148ebbb4bef832f93841bb..670c6604dd0843d180e30475092d2740770fb61c 100644 (file)
@@ -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;
                        }
                }
        }
index 7e0481ba5eb013c480ac072d1a627a136638b46d..860e0bc6288a6e5165c86f455fc93e88eb05eefa 100644 (file)
@@ -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
index 3e9793521aeb0f704a2d0c205004fd05eac04c81..5346ec516ee51a0c62cae39b817a14a53e667337 100644 (file)
@@ -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);