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:
authorPeter Kim <pk15950@gmail.com>2021-10-05 09:55:57 +0300
committerPeter Kim <pk15950@gmail.com>2021-10-05 10:05:12 +0300
commit08511b1c3de0338314940397083adaba4e9cf492 (patch)
tree879ddffecd08dd9315847fdcffb0b2d76cee8637 /source/blender/windowmanager/intern/wm_event_system.c
parent300403a38b8ed7f0f84125ca9a82264757ae704a (diff)
XR: Add runtime window area for XR events
This adds an offscreen View3D window area for the VR view in order to execute XR events/operators in the proper context. The area is created as runtime data before XR events are dispatched and set as the active area during XR event handling. Since the area is runtime-only, it will not be saved in files and since the area is offscreen, it will not interfere with regular window areas. The area is removed with the rest of the XR runtime data on exit, file read, or when stopping the VR session. Note: This also adds internal types (EVT_DATA_XR, EVT_XR_ACTION) and structs (wmXrActionData) for XR events. Reviewed By: Severin Differential Revision: https://developer.blender.org/D12472
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index cc0a13e96af..c92208c4818 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3461,6 +3461,70 @@ 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
+/**
+ * Special handling for XR events.
+ *
+ * Although XR events are added to regular window queues, they are handled in an "offscreen area"
+ * context that is owned entirely by XR runtime data and not tied to a window.
+ */
+static void wm_event_handle_xrevent(bContext *C,
+ wmWindowManager *wm,
+ wmWindow *win,
+ wmEvent *event)
+{
+ ScrArea *area = WM_xr_session_area_get(&wm->xr);
+ if (!area) {
+ return;
+ }
+ BLI_assert(area->spacetype == SPACE_VIEW3D && area->spacedata.first);
+
+ /* Find a valid region for XR operator execution and modal handling. */
+ ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+ if (!region) {
+ return;
+ }
+ BLI_assert(WM_region_use_viewport(area, region)); /* For operators using GPU-based selection. */
+
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+
+ int action = wm_handlers_do(C, event, &win->modalhandlers);
+
+ if ((action & WM_HANDLER_BREAK) == 0) {
+ wmXrActionData *actiondata = event->customdata;
+ if (actiondata->ot->modal && 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) {
+ /* 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);
+ }
+ }
+ }
+ }
+
+ CTX_wm_region_set(C, NULL);
+ 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)
@@ -3558,6 +3622,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, 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)) {
@@ -5110,6 +5184,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 */
+
/** \} */
/* -------------------------------------------------------------------- */