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:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c120
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 */
+
/** \} */
/* -------------------------------------------------------------------- */