11// Copyright (c) Mixed Reality Toolkit Contributors
22// Licensed under the BSD 3-Clause
33
4- using System . Collections . Generic ;
5- using Unity . XR . CoreUtils . Bindings . Variables ;
64using UnityEngine ;
75using UnityEngine . InputSystem ;
86
@@ -16,22 +14,26 @@ public sealed class MRTKInputFocusManager : MonoBehaviour
1614 [ SerializeField , Tooltip ( "A set of input actions to enable/disable according to the app's focus state." ) ]
1715 private InputActionReference [ ] inputActionReferences ;
1816
19- /// <summary>
20- /// Whether the current XrSession has focus or not, stored as a bindable variable that can be subscribed to for value changes.
21- /// </summary>
22- /// <remarks>Always <see langword="true"/> in the editor.</remarks>
23- public static IReadOnlyBindableVariable < bool > XrSessionHasFocus => xrSessionHasFocus ;
24- private static readonly BindableVariable < bool > xrSessionHasFocus = new ( Application . isEditor ) ;
17+ private void OnEnable ( )
18+ {
19+ MRTKFocusFeature . XrSessionFocused . SubscribeAndUpdate ( OnXrSessionFocus ) ;
20+ }
21+
22+ private void OnDisable ( )
23+ {
24+ MRTKFocusFeature . XrSessionFocused . Unsubscribe ( OnXrSessionFocus ) ;
25+ }
2526
2627 /// <summary>
27- /// We want to ensure we're focused for input, as some runtimes continue reporting "tracked" while pose updates are paused.
28- /// This is allowed, per-spec, as a "should": "Runtimes should make input actions inactive while the application is unfocused,
29- /// and applications should react to an inactive input action by skipping rendering of that action's input avatar
30- /// (depictions of hands or other tracked objects controlled by the user)."
28+ /// Sent when the XrSession gains or loses focus.
3129 /// </summary>
32- private void OnFocusChange ( bool focus )
30+ /// <param name="focus"><see langword="true"/> if the XrSession has focus, else <see langword="false"/>.</param>
31+ private void OnXrSessionFocus ( bool focus )
3332 {
34- xrSessionHasFocus . Value = focus ;
33+ // We want to ensure we're focused for input visualization, as some runtimes continue reporting "tracked" while pose updates are paused.
34+ // This is allowed, per-spec, as a "should": "Runtimes should make input actions inactive while the application is unfocused,
35+ // and applications should react to an inactive input action by skipping rendering of that action's input avatar
36+ // (depictions of hands or other tracked objects controlled by the user)."
3537
3638 foreach ( InputActionReference reference in inputActionReferences )
3739 {
@@ -45,59 +47,5 @@ private void OnFocusChange(bool focus)
4547 }
4648 }
4749 }
48-
49- #if SNAPDRAGON_SPACES_PRESENT
50- private static readonly List < Qualcomm . Snapdragon . Spaces . SpacesOpenXRFeature > featureList = new ( ) ;
51- private static int lastSessionState = - 1 ;
52- private Qualcomm . Snapdragon . Spaces . SpacesOpenXRFeature spacesOpenXRFeature = null ;
53-
54- private void Update ( )
55- {
56- if ( spacesOpenXRFeature == null )
57- {
58- int count = UnityEngine . XR . OpenXR . OpenXRSettings . Instance . GetFeatures ( featureList ) ;
59- for ( int i = 0 ; i < count ; i ++ )
60- {
61- Qualcomm . Snapdragon . Spaces . SpacesOpenXRFeature feature = featureList [ i ] ;
62- if ( feature != null && feature . enabled )
63- {
64- spacesOpenXRFeature = feature ;
65- break ;
66- }
67- }
68- }
69-
70- // XrSessionState maps better to this behavior than OnApplicationFocus but isn't
71- // easily available in Unity. For now, only the Snapdragon Spaces plugin provides it.
72- if ( spacesOpenXRFeature != null && lastSessionState != spacesOpenXRFeature . SessionState )
73- {
74- // If we've lost focus...
75- // XR_SESSION_STATE_FOCUSED = 5
76- if ( lastSessionState == 5 )
77- {
78- OnFocusChange ( false ) ;
79- }
80- // ...or if we've gained focus
81- // XR_SESSION_STATE_FOCUSED = 5
82- else if ( spacesOpenXRFeature . SessionState == 5 )
83- {
84- OnFocusChange ( true ) ;
85- }
86-
87- lastSessionState = spacesOpenXRFeature . SessionState ;
88- }
89- }
90- #elif ! UNITY_EDITOR
91- /// <summary>
92- /// Sent to all GameObjects when the player gets or loses focus.
93- /// </summary>
94- /// <param name="focus"><see langword="true"/> if the GameObjects have focus, else <see langword="false"/>.</param>
95- /// <remarks>
96- /// Ideally, we'd use XrSessionState here, as it maps better to this behavior than OnApplicationFocus, but
97- /// it isn't easily available in Unity. For now, only the Snapdragon Spaces plugin provides it, and we use
98- /// OnApplicationFocus for the rest.
99- /// </remarks>
100- private void OnApplicationFocus ( bool focus ) => OnFocusChange ( focus ) ;
101- #endif
10250 }
10351}
0 commit comments