diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index a21efef4ff4..81d8e510e60 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -115,6 +115,7 @@ selectend selectionchange selectstart serif +sessionavailable signalingstatechange squeeze squeezeend diff --git a/components/config/prefs.rs b/components/config/prefs.rs index cab08d066da..da985238dd2 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -281,7 +281,8 @@ mod gen { }, layers: { enabled: bool, - } + }, + sessionavailable: bool, }, worklet: { blockingsleep: { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 4253f14f69c..437b147678d 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -17,6 +17,7 @@ use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMe use crate::dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods; +use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorBinding::NavigatorMethods; use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods; @@ -2267,6 +2268,17 @@ impl Document { // Step 11. // TODO: ready for post-load tasks. + // The dom.webxr.sessionavailable pref allows webxr + // content to immediately begin a session without waiting for a user gesture. + // TODO: should this only happen on the first document loaded? + // https://immersive-web.github.io/webxr/#user-intention + // https://github.com/immersive-web/navigation/issues/10 + if pref!(dom.webxr.sessionavailable) { + if self.window.is_top_level() { + self.window.Navigator().Xr().dispatch_sessionavailable(); + } + } + // Step 12: completely loaded. // https://html.spec.whatwg.org/multipage/#completely-loaded // TODO: fully implement "completely loaded". diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index a2ba7946e62..798ba502aeb 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -7,6 +7,7 @@ use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionInit; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::{XRSessionMode, XRSystemMethods}; use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible}; use crate::dom::bindings::error::Error; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; @@ -289,4 +290,26 @@ impl XRSystem { // This must be called _after_ the promise is resolved session.setup_initial_inputs(); } + + // https://github.com/immersive-web/navigation/issues/10 + pub fn dispatch_sessionavailable(&self) { + let xr = Trusted::new(self); + let global = self.global(); + let window = global.as_window(); + window + .task_manager() + .dom_manipulation_task_source() + .queue( + task!(fire_sessionavailable_event: move || { + // The sessionavailable event indicates user intent to enter an XR session + let xr = xr.root(); + let interacting = ScriptThread::is_user_interacting(); + ScriptThread::set_user_interacting(true); + xr.upcast::().fire_bubbling_event(atom!("sessionavailable")); + ScriptThread::set_user_interacting(interacting); + }), + window.upcast(), + ) + .unwrap(); + } } diff --git a/resources/prefs.json b/resources/prefs.json index 364e25c5682..9d946e20dad 100644 --- a/resources/prefs.json +++ b/resources/prefs.json @@ -41,6 +41,7 @@ "dom.webxr.glwindow.spherical": false, "dom.webxr.hands.enabled": false, "dom.webxr.layers.enabled": false, + "dom.webxr.sessionavailable": false, "dom.webxr.test": false, "dom.worklet.timeout_ms": 10, "gfx.subpixel-text-antialiasing.enabled": true,