diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 120 |
1 files changed, 117 insertions, 3 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 537d5264ba9..f025fd43b49 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -83,6 +83,7 @@ #include "wm.h" #include "wm_event_system.h" #include "wm_event_types.h" +#include "wm_surface.h" #include "wm_window.h" #include "DEG_depsgraph.h" @@ -1341,7 +1342,19 @@ static int wm_operator_invoke(bContext *C, ot->idname); } - if (op->type->invoke && event) { + if (op->type->invoke_3d && event && (event->type == EVT_XR_ACTION)) { + if (op->type->flag & OPTYPE_UNDO) { + wm->op_undo_depth++; + } + + retval = op->type->invoke_3d(C, op, event); + OPERATOR_RETVAL_CHECK(retval); + + if (op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm) { + wm->op_undo_depth--; + } + } + else if (op->type->invoke && event) { wm_region_mouse_co(C, event); if (op->type->flag & OPTYPE_UNDO) { @@ -2227,7 +2240,7 @@ static int wm_handler_operator_call(bContext *C, * nothing to do in this case. */ } - else if (ot->modal) { + else if (ot->modal || ot->modal_3d) { /* We set context to where modal handler came from. */ wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -2245,7 +2258,15 @@ static int wm_handler_operator_call(bContext *C, } /* Warning, after this call all context data and 'event' may be freed. see check below. */ - retval = ot->modal(C, op, event); + if (ot->modal_3d && event->type == EVT_XR_ACTION) { + retval = ot->modal_3d(C, op, event); + } + else if (ot->modal) { + retval = ot->modal(C, op, event); + } + else { + /* Pass through. An "XR operator" (only modal_3d) received a non-XR event.*/ + } OPERATOR_RETVAL_CHECK(retval); if (ot->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm) { @@ -3434,6 +3455,71 @@ static void wm_event_free_and_remove_from_queue_if_valid(wmEvent *event) * Handle events for all windows, run from the #WM_main event loop. * \{ */ +#ifdef WITH_XR_OPENXR +static void wm_event_handle_xrevent( + bContext *C, wmWindowManager *wm, wmWindow *win, bScreen *screen, wmEvent *event) +{ + int action = 0; + + /* Find a valid region for XR operator execution and modal handling. */ + ED_screen_areas_iter (win, screen, area) { + CTX_wm_area_set(C, area); + if (!CTX_wm_view3d(C)) { + continue; + } + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (!WM_region_use_viewport(area, region)) { + continue; + } + CTX_wm_region_set(C, region); + + action |= wm_handlers_do(C, event, &win->modalhandlers); + + if ((action & WM_HANDLER_BREAK) == 0) { + wmXrActionData *actiondata = event->customdata; + if ((actiondata->ot->modal || actiondata->ot->modal_3d) && event->val == KM_RELEASE) { + /* Don't execute modal operators on release. */ + } + else { + PointerRNA properties = {.type = actiondata->ot->srna, + .data = actiondata->op_properties}; + if (actiondata->ot->invoke || actiondata->ot->invoke_3d) { + /* Invoke operator, either executing operator or transferring responsibility to window + * modal handlers. */ + wm_operator_invoke(C, + actiondata->ot, + event, + actiondata->op_properties ? &properties : NULL, + NULL, + false, + false); + } + else { + /* Execute operator. */ + wmOperator *op = wm_operator_create( + wm, actiondata->ot, actiondata->op_properties ? &properties : NULL, NULL); + if ((WM_operator_call(C, op) & OPERATOR_HANDLED) == 0) { + WM_operator_free(op); + } + } + } + action |= WM_HANDLER_BREAK; + } + + CTX_wm_region_set(C, NULL); + break; + } + + if (action & WM_HANDLER_BREAK) { + break; + } + } + + CTX_wm_area_set(C, NULL); +} +#endif /* WITH_XR_OPENXR */ + /* Called in main loop. */ /* Goes over entire hierarchy: events -> window -> screen -> area -> region. */ void wm_event_do_handlers(bContext *C) @@ -3531,6 +3617,16 @@ void wm_event_do_handlers(bContext *C) CTX_wm_window_set(C, win); +#ifdef WITH_XR_OPENXR + if (event->type == EVT_XR_ACTION) { + wm_event_handle_xrevent(C, wm, win, screen, event); + BLI_remlink(&win->event_queue, event); + wm_event_free(event); + /* Skip mouse event handling below, which is unnecessary for XR events. */ + continue; + } +#endif + /* Clear tool-tip on mouse move. */ if (screen->tool_tip && screen->tool_tip->exit_on_event) { if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { @@ -5083,6 +5179,24 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void #endif } +#ifdef WITH_XR_OPENXR +void wm_event_add_xrevent(wmWindow *win, wmXrActionData *actiondata, short val) +{ + BLI_assert(val == KM_PRESS || val == KM_RELEASE); + + wmEvent event = { + .type = EVT_XR_ACTION, + .val = val, + .is_repeat = false, + .custom = EVT_DATA_XR, + .customdata = actiondata, + .customdatafree = 1, + }; + + wm_event_add(win, &event); +} +#endif /* WITH_XR_OPENXR */ + /** \} */ /* -------------------------------------------------------------------- */ |