From 7ee00a012eecb613cad308da8fb257cd30a7e090 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 Jan 2026 15:23:37 +0000 Subject: [PATCH] st/oxr: Explain better what is going on with XrEventDataInteractionProfileChanged [NFC] Part-of: --- src/xrt/state_trackers/oxr/oxr_input.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/xrt/state_trackers/oxr/oxr_input.c b/src/xrt/state_trackers/oxr/oxr_input.c index dbe6dc926..66d5f896b 100644 --- a/src/xrt/state_trackers/oxr/oxr_input.c +++ b/src/xrt/state_trackers/oxr/oxr_input.c @@ -1898,12 +1898,23 @@ oxr_session_update_action_bindings(struct oxr_logger *log, struct oxr_session *s } } + /* + * This code will only send events (and update the bindings) if there + * is a profile mapped to the subaction path. Meaning it won't update + * the cache or generate events when a controller goes away, basically + * latching the interaction profile to the last active device. + */ #define POPULATE_PROFILE(X) \ - sess->X = XR_NULL_PATH; \ - if (profiles.X != NULL) { \ - sess->X = profiles.X->path; \ - oxr_event_push_XrEventDataInteractionProfileChanged(log, sess); \ - } + do { \ + XrPath path = profiles.X != NULL ? profiles.X->path : XR_NULL_PATH; \ + if (path == XR_NULL_PATH) { \ + break; /* Only update on "active" interaction profiles per sub-action path. */ \ + } \ + if (sess->X != path) { \ + sess->X = path; \ + oxr_event_push_XrEventDataInteractionProfileChanged(log, sess); \ + } \ + } while (false); OXR_FOR_EACH_VALID_SUBACTION_PATH(POPULATE_PROFILE) #undef POPULATE_PROFILE