diff options
-rw-r--r-- | source/blender/editors/space_script/script_edit.c | 16 | ||||
-rw-r--r-- | source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c | 56 | ||||
-rw-r--r-- | source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h | 7 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 22 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 176 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 19 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operator_type.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 27 |
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); |