diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 84fee9ff34c..9e3722777ba 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -282,7 +282,7 @@ void wm_event_do_notifiers(bContext *C) /* XXX context in notifiers? */ CTX_wm_window_set(C, win); - /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name+2, note->category); */ + /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name + 2, note->category); */ ED_screen_do_listen(C, note); for (ar = win->screen->regionbase.first; ar; ar = ar->next) { @@ -453,6 +453,22 @@ static void wm_operator_print(bContext *C, wmOperator *op) MEM_freeN(buf); } +/** + * Sets the active region for this space from the context. + * + * \see #BKE_area_find_region_active_win + */ +void WM_operator_region_active_win_set(bContext *C) +{ + ScrArea *sa = CTX_wm_area(C); + if (sa) { + ARegion *ar = CTX_wm_region(C); + if (ar && ar->regiontype == RGN_TYPE_WINDOW) { + sa->region_active_win = BLI_findindex(&sa->regionbase, ar); + } + } +} + /* for debugging only, getting inspecting events manually is tedious */ #ifndef NDEBUG @@ -573,10 +589,13 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat) MEM_freeN(buf); } - if (wm_operator_register_check(wm, op->type)) + if (wm_operator_register_check(wm, op->type)) { wm_operator_register(C, op); - else + WM_operator_region_active_win_set(C); + } + else { WM_operator_free(op); + } } } @@ -1045,7 +1064,14 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA } if (!(ar && ar->regiontype == type) && area) { - ARegion *ar1 = BKE_area_find_region_type(area, type); + ARegion *ar1; + if (type == RGN_TYPE_WINDOW) { + ar1 = BKE_area_find_region_active_win(area); + } + else { + ar1 = BKE_area_find_region_type(area, type); + } + if (ar1) CTX_wm_region_set(C, ar1); } @@ -1357,8 +1383,8 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve } else { /* modal keymap checking returns handled events fine, but all hardcoded modal - handling typically swallows all events (OPERATOR_RUNNING_MODAL). - This bypass just disables support for double clicks in hardcoded modal handlers */ + * handling typically swallows all events (OPERATOR_RUNNING_MODAL). + * This bypass just disables support for double clicks in hardcoded modal handlers */ if (event->val == KM_DBL_CLICK) { event->prevval = event->val; event->val = KM_PRESS; @@ -1417,20 +1443,10 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand if (ot->flag & OPTYPE_UNDO) wm->op_undo_depth--; - /* putting back screen context, reval can pass trough after modal failures! */ - if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) { - CTX_wm_area_set(C, area); - CTX_wm_region_set(C, region); - } - else { - /* this special cases is for areas and regions that get removed */ - CTX_wm_area_set(C, NULL); - CTX_wm_region_set(C, NULL); - } - if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) wm_operator_reports(C, op, retval, FALSE); + /* important to run 'wm_operator_finished' before NULLing the context members */ if (retval & OPERATOR_FINISHED) { wm_operator_finished(C, op, 0); handler->op = NULL; @@ -1440,6 +1456,17 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand handler->op = NULL; } + /* putting back screen context, reval can pass trough after modal failures! */ + if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) { + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + } + else { + /* this special cases is for areas and regions that get removed */ + CTX_wm_area_set(C, NULL); + CTX_wm_region_set(C, NULL); + } + /* remove modal handler, operator itself should have been canceled and freed */ if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) { WM_cursor_grab_disable(CTX_wm_window(C), NULL); |