mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #23814 - Manishearth:events, r=asajeffrey
Partial support for events in WebXR Needs https://github.com/servo/webxr/pull/20 r? @asajeffrey <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23814) <!-- Reviewable:end -->
This commit is contained in:
commit
7afe2153e8
19 changed files with 299 additions and 108 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -5462,7 +5462,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr"
|
name = "webxr"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#5c0eb61f8f38429fde45673d0884f947d14e9c79"
|
source = "git+https://github.com/servo/webxr#b5a4b93fcfb2b03ee264a8f95bbaa1500ff0a087"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -5474,7 +5474,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr-api"
|
name = "webxr-api"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#5c0eb61f8f38429fde45673d0884f947d14e9c79"
|
source = "git+https://github.com/servo/webxr#b5a4b93fcfb2b03ee264a8f95bbaa1500ff0a087"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -25,6 +25,7 @@ dir
|
||||||
durationchange
|
durationchange
|
||||||
email
|
email
|
||||||
emptied
|
emptied
|
||||||
|
end
|
||||||
ended
|
ended
|
||||||
error
|
error
|
||||||
fantasy
|
fantasy
|
||||||
|
|
|
@ -38,6 +38,10 @@ impl FakeXRDevice {
|
||||||
FakeXRDeviceBinding::Wrap,
|
FakeXRDeviceBinding::Wrap,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn disconnect(&self, sender: IpcSender<()>) {
|
||||||
|
let _ = self.sender.send(MockDeviceMsg::Disconnect(sender));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_views(views: &[FakeXRViewInit]) -> Fallible<Views> {
|
pub fn get_views(views: &[FakeXRViewInit]) -> Fallible<Views> {
|
||||||
|
|
|
@ -547,12 +547,12 @@ pub mod xmlserializer;
|
||||||
pub mod xr;
|
pub mod xr;
|
||||||
pub mod xrframe;
|
pub mod xrframe;
|
||||||
pub mod xrinputsource;
|
pub mod xrinputsource;
|
||||||
pub mod xrlayer;
|
|
||||||
pub mod xrpose;
|
pub mod xrpose;
|
||||||
pub mod xrreferencespace;
|
pub mod xrreferencespace;
|
||||||
pub mod xrrenderstate;
|
pub mod xrrenderstate;
|
||||||
pub mod xrrigidtransform;
|
pub mod xrrigidtransform;
|
||||||
pub mod xrsession;
|
pub mod xrsession;
|
||||||
|
pub mod xrsessionevent;
|
||||||
pub mod xrspace;
|
pub mod xrspace;
|
||||||
pub mod xrtest;
|
pub mod xrtest;
|
||||||
pub mod xrview;
|
pub mod xrview;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// https://immersive-web.github.io/webxr/#xrlayer-interface
|
|
||||||
|
|
||||||
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
|
|
||||||
interface XRLayer {};
|
|
|
@ -7,11 +7,11 @@
|
||||||
dictionary XRRenderStateInit {
|
dictionary XRRenderStateInit {
|
||||||
double depthNear;
|
double depthNear;
|
||||||
double depthFar;
|
double depthFar;
|
||||||
XRLayer baseLayer;
|
XRWebGLLayer baseLayer;
|
||||||
};
|
};
|
||||||
|
|
||||||
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRRenderState {
|
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRRenderState {
|
||||||
readonly attribute double depthNear;
|
readonly attribute double depthNear;
|
||||||
readonly attribute double depthFar;
|
readonly attribute double depthFar;
|
||||||
readonly attribute XRLayer? baseLayer;
|
readonly attribute XRWebGLLayer? baseLayer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ interface XRSession : EventTarget {
|
||||||
// FrozenArray<XRInputSource> getInputSources();
|
// FrozenArray<XRInputSource> getInputSources();
|
||||||
sequence<XRInputSource> getInputSources();
|
sequence<XRInputSource> getInputSources();
|
||||||
|
|
||||||
void updateRenderState(optional XRRenderStateInit state = {});
|
[Throws] void updateRenderState(optional XRRenderStateInit state = {});
|
||||||
long requestAnimationFrame(XRFrameRequestCallback callback);
|
long requestAnimationFrame(XRFrameRequestCallback callback);
|
||||||
void cancelAnimationFrame(long handle);
|
void cancelAnimationFrame(long handle);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ interface XRSession : EventTarget {
|
||||||
// // Events
|
// // Events
|
||||||
// attribute EventHandler onblur;
|
// attribute EventHandler onblur;
|
||||||
// attribute EventHandler onfocus;
|
// attribute EventHandler onfocus;
|
||||||
// attribute EventHandler onend;
|
attribute EventHandler onend;
|
||||||
// attribute EventHandler onselect;
|
// attribute EventHandler onselect;
|
||||||
// attribute EventHandler oninputsourceschange;
|
// attribute EventHandler oninputsourceschange;
|
||||||
// attribute EventHandler onselectstart;
|
// attribute EventHandler onselectstart;
|
||||||
|
|
15
components/script/dom/webidls/XRSessionEvent.webidl
Normal file
15
components/script/dom/webidls/XRSessionEvent.webidl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
// https://immersive-web.github.io/webxr/#xrsessionevent-interface
|
||||||
|
|
||||||
|
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled", Constructor
|
||||||
|
(DOMString type, XRSessionEventInit eventInitDict)]
|
||||||
|
interface XRSessionEvent : Event {
|
||||||
|
[SameObject] readonly attribute XRSession session;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary XRSessionEventInit : EventInit {
|
||||||
|
required XRSession session;
|
||||||
|
};
|
|
@ -21,7 +21,7 @@ dictionary XRWebGLLayerInit {
|
||||||
XRWebGLRenderingContext context,
|
XRWebGLRenderingContext context,
|
||||||
optional XRWebGLLayerInit layerInit = {}),
|
optional XRWebGLLayerInit layerInit = {}),
|
||||||
Pref="dom.webxr.enabled"]
|
Pref="dom.webxr.enabled"]
|
||||||
interface XRWebGLLayer : XRLayer {
|
interface XRWebGLLayer {
|
||||||
// // Attributes
|
// // Attributes
|
||||||
readonly attribute XRWebGLRenderingContext context;
|
readonly attribute XRWebGLRenderingContext context;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,17 @@ impl XR {
|
||||||
self.pending_immersive_session.set(false);
|
self.pending_immersive_session.set(false);
|
||||||
self.active_immersive_session.set(Some(session))
|
self.active_immersive_session.set(Some(session))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr/#ref-for-eventdef-xrsession-end
|
||||||
|
pub fn end_session(&self, session: &XRSession) {
|
||||||
|
// Step 3
|
||||||
|
if let Some(active) = self.active_immersive_session.get() {
|
||||||
|
if Dom::from_ref(&*active) == Dom::from_ref(session) {
|
||||||
|
self.active_immersive_session.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// XXXManishearth when we support inline sessions we should remove them too
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for XR {
|
impl Drop for XR {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
use crate::dom::bindings::reflector::Reflector;
|
|
||||||
use dom_struct::dom_struct;
|
|
||||||
|
|
||||||
#[dom_struct]
|
|
||||||
pub struct XRLayer {
|
|
||||||
reflector_: Reflector,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl XRLayer {
|
|
||||||
pub fn new_inherited() -> XRLayer {
|
|
||||||
XRLayer {
|
|
||||||
reflector_: Reflector::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::xrlayer::XRLayer;
|
use crate::dom::xrwebgllayer::XRWebGLLayer;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -17,14 +17,14 @@ pub struct XRRenderState {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
depth_near: Cell<f64>,
|
depth_near: Cell<f64>,
|
||||||
depth_far: Cell<f64>,
|
depth_far: Cell<f64>,
|
||||||
layer: MutNullableDom<XRLayer>,
|
layer: MutNullableDom<XRWebGLLayer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRRenderState {
|
impl XRRenderState {
|
||||||
pub fn new_inherited(
|
pub fn new_inherited(
|
||||||
depth_near: f64,
|
depth_near: f64,
|
||||||
depth_far: f64,
|
depth_far: f64,
|
||||||
layer: Option<&XRLayer>,
|
layer: Option<&XRWebGLLayer>,
|
||||||
) -> XRRenderState {
|
) -> XRRenderState {
|
||||||
XRRenderState {
|
XRRenderState {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
|
@ -38,7 +38,7 @@ impl XRRenderState {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
depth_near: f64,
|
depth_near: f64,
|
||||||
depth_far: f64,
|
depth_far: f64,
|
||||||
layer: Option<&XRLayer>,
|
layer: Option<&XRWebGLLayer>,
|
||||||
) -> DomRoot<XRRenderState> {
|
) -> DomRoot<XRRenderState> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(XRRenderState::new_inherited(depth_near, depth_far, layer)),
|
Box::new(XRRenderState::new_inherited(depth_near, depth_far, layer)),
|
||||||
|
@ -62,7 +62,7 @@ impl XRRenderState {
|
||||||
pub fn set_depth_far(&self, depth: f64) {
|
pub fn set_depth_far(&self, depth: f64) {
|
||||||
self.depth_far.set(depth)
|
self.depth_far.set(depth)
|
||||||
}
|
}
|
||||||
pub fn set_layer(&self, layer: Option<&XRLayer>) {
|
pub fn set_layer(&self, layer: Option<&XRWebGLLayer>) {
|
||||||
self.layer.set(layer)
|
self.layer.set(layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ impl XRRenderStateMethods for XRRenderState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrrenderstate-baselayer
|
/// https://immersive-web.github.io/webxr/#dom-xrrenderstate-baselayer
|
||||||
fn GetBaseLayer(&self) -> Option<DomRoot<XRLayer>> {
|
fn GetBaseLayer(&self) -> Option<DomRoot<XRWebGLLayer>> {
|
||||||
self.layer.get()
|
self.layer.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
use crate::compartments::InCompartment;
|
use crate::compartments::InCompartment;
|
||||||
use crate::dom::bindings::callback::ExceptionHandling;
|
use crate::dom::bindings::callback::ExceptionHandling;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorBinding::NavigatorMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode;
|
use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding::XRReferenceSpaceType;
|
use crate::dom::bindings::codegen::Bindings::XRReferenceSpaceBinding::XRReferenceSpaceType;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateInit;
|
use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateInit;
|
||||||
|
@ -15,12 +17,13 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XREnvironmentBlen
|
||||||
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback;
|
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods;
|
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
|
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::{Error, ErrorResult};
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::num::Finite;
|
use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::refcounted::Trusted;
|
use crate::dom::bindings::refcounted::Trusted;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
|
||||||
|
use crate::dom::event::Event;
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::node::Node;
|
use crate::dom::node::Node;
|
||||||
|
@ -28,9 +31,9 @@ use crate::dom::node::NodeDamage;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::xrframe::XRFrame;
|
use crate::dom::xrframe::XRFrame;
|
||||||
use crate::dom::xrinputsource::XRInputSource;
|
use crate::dom::xrinputsource::XRInputSource;
|
||||||
use crate::dom::xrlayer::XRLayer;
|
|
||||||
use crate::dom::xrreferencespace::XRReferenceSpace;
|
use crate::dom::xrreferencespace::XRReferenceSpace;
|
||||||
use crate::dom::xrrenderstate::XRRenderState;
|
use crate::dom::xrrenderstate::XRRenderState;
|
||||||
|
use crate::dom::xrsessionevent::XRSessionEvent;
|
||||||
use crate::dom::xrspace::XRSpace;
|
use crate::dom::xrspace::XRSpace;
|
||||||
use crate::dom::xrwebgllayer::XRWebGLLayer;
|
use crate::dom::xrwebgllayer::XRWebGLLayer;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
|
@ -42,12 +45,12 @@ use profile_traits::ipc;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webxr_api::{self, Frame, Session};
|
use webxr_api::{self, Event as XREvent, Frame, Session};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRSession {
|
pub struct XRSession {
|
||||||
eventtarget: EventTarget,
|
eventtarget: EventTarget,
|
||||||
base_layer: MutNullableDom<XRLayer>,
|
base_layer: MutNullableDom<XRWebGLLayer>,
|
||||||
blend_mode: XREnvironmentBlendMode,
|
blend_mode: XREnvironmentBlendMode,
|
||||||
viewer_space: MutNullableDom<XRSpace>,
|
viewer_space: MutNullableDom<XRSpace>,
|
||||||
#[ignore_malloc_size_of = "defined in webxr"]
|
#[ignore_malloc_size_of = "defined in webxr"]
|
||||||
|
@ -62,6 +65,11 @@ pub struct XRSession {
|
||||||
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
||||||
raf_sender: DomRefCell<Option<IpcSender<(f64, Frame)>>>,
|
raf_sender: DomRefCell<Option<IpcSender<(f64, Frame)>>>,
|
||||||
input_sources: DomRefCell<Vec<Dom<XRInputSource>>>,
|
input_sources: DomRefCell<Vec<Dom<XRInputSource>>>,
|
||||||
|
// Any promises from calling end()
|
||||||
|
#[ignore_malloc_size_of = "promises are hard"]
|
||||||
|
end_promises: DomRefCell<Vec<Rc<Promise>>>,
|
||||||
|
/// https://immersive-web.github.io/webxr/#ended
|
||||||
|
ended: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRSession {
|
impl XRSession {
|
||||||
|
@ -81,6 +89,8 @@ impl XRSession {
|
||||||
raf_callback_list: DomRefCell::new(vec![]),
|
raf_callback_list: DomRefCell::new(vec![]),
|
||||||
raf_sender: DomRefCell::new(None),
|
raf_sender: DomRefCell::new(None),
|
||||||
input_sources: DomRefCell::new(vec![]),
|
input_sources: DomRefCell::new(vec![]),
|
||||||
|
end_promises: DomRefCell::new(vec![]),
|
||||||
|
ended: Cell::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +110,7 @@ impl XRSession {
|
||||||
input_sources.push(Dom::from_ref(&input));
|
input_sources.push(Dom::from_ref(&input));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret.attach_event_handler();
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +119,71 @@ impl XRSession {
|
||||||
with(&session)
|
with(&session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_ended(&self) -> bool {
|
||||||
|
self.ended.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attach_event_handler(&self) {
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct EventCallback {
|
||||||
|
sender: IpcSender<XREvent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
|
impl webxr_api::EventCallback for EventCallback {
|
||||||
|
fn callback(&mut self, event: XREvent) {
|
||||||
|
let _ = self.sender.send(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let this = Trusted::new(self);
|
||||||
|
let global = self.global();
|
||||||
|
let window = global.as_window();
|
||||||
|
let (task_source, canceller) = window
|
||||||
|
.task_manager()
|
||||||
|
.dom_manipulation_task_source_with_canceller();
|
||||||
|
let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap();
|
||||||
|
ROUTER.add_route(
|
||||||
|
receiver.to_opaque(),
|
||||||
|
Box::new(move |message| {
|
||||||
|
let this = this.clone();
|
||||||
|
let _ = task_source.queue_with_canceller(
|
||||||
|
task!(xr_event_callback: move || {
|
||||||
|
this.root().event_callback(message.to().unwrap());
|
||||||
|
}),
|
||||||
|
&canceller,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// request animation frame
|
||||||
|
self.session
|
||||||
|
.borrow_mut()
|
||||||
|
.set_event_callback(EventCallback { sender });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event_callback(&self, event: XREvent) {
|
||||||
|
match event {
|
||||||
|
XREvent::SessionEnd => {
|
||||||
|
// https://immersive-web.github.io/webxr/#shut-down-the-session
|
||||||
|
// Step 2
|
||||||
|
self.ended.set(true);
|
||||||
|
// Step 3-4
|
||||||
|
self.global().as_window().Navigator().Xr().end_session(self);
|
||||||
|
// Step 5: We currently do not have any such promises
|
||||||
|
// Step 6 is happening n the XR session
|
||||||
|
// https://immersive-web.github.io/webxr/#dom-xrsession-end step 3
|
||||||
|
for promise in self.end_promises.borrow_mut().drain(..) {
|
||||||
|
promise.resolve_native(&());
|
||||||
|
}
|
||||||
|
// Step 7
|
||||||
|
let event = XRSessionEvent::new(&self.global(), atom!("end"), false, false, self);
|
||||||
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
},
|
||||||
|
_ => (), // XXXManishearth TBD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#xr-animation-frame
|
/// https://immersive-web.github.io/webxr/#xr-animation-frame
|
||||||
fn raf_callback(&self, (time, frame): (f64, Frame)) {
|
fn raf_callback(&self, (time, frame): (f64, Frame)) {
|
||||||
// Step 1
|
// Step 1
|
||||||
|
@ -122,13 +198,9 @@ impl XRSession {
|
||||||
let layer = pending.GetBaseLayer();
|
let layer = pending.GetBaseLayer();
|
||||||
if let Some(layer) = layer {
|
if let Some(layer) = layer {
|
||||||
let mut session = self.session.borrow_mut();
|
let mut session = self.session.borrow_mut();
|
||||||
if let Some(layer) = layer.downcast::<XRWebGLLayer>() {
|
|
||||||
session.update_webgl_external_image_api(
|
session.update_webgl_external_image_api(
|
||||||
layer.Context().webgl_sender().webxr_external_image_api(),
|
layer.Context().webgl_sender().webxr_external_image_api(),
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
error!("updateRenderState() called with unknown layer type")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,17 +232,18 @@ impl XRSession {
|
||||||
|
|
||||||
// If the canvas element is attached to the DOM, it is now dirty,
|
// If the canvas element is attached to the DOM, it is now dirty,
|
||||||
// and we need to trigger a reflow.
|
// and we need to trigger a reflow.
|
||||||
if let Some(webgl_layer) = base_layer.downcast::<XRWebGLLayer>() {
|
base_layer
|
||||||
webgl_layer
|
|
||||||
.Context()
|
.Context()
|
||||||
.Canvas()
|
.Canvas()
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.dirty(NodeDamage::OtherNodeDamage);
|
.dirty(NodeDamage::OtherNodeDamage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl XRSessionMethods for XRSession {
|
impl XRSessionMethods for XRSession {
|
||||||
|
/// https://immersive-web.github.io/webxr/#eventdef-xrsession-end
|
||||||
|
event_handler!(end, GetOnend, SetOnend);
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-mode
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-mode
|
||||||
fn Mode(&self) -> XRSessionMode {
|
fn Mode(&self) -> XRSessionMode {
|
||||||
XRSessionMode::Immersive_vr
|
XRSessionMode::Immersive_vr
|
||||||
|
@ -182,11 +255,19 @@ impl XRSessionMethods for XRSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-updaterenderstate
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-updaterenderstate
|
||||||
fn UpdateRenderState(&self, init: &XRRenderStateInit, _: InCompartment) {
|
fn UpdateRenderState(&self, init: &XRRenderStateInit, _: InCompartment) -> ErrorResult {
|
||||||
// XXXManishearth various checks:
|
// Step 2
|
||||||
// If session’s ended value is true, throw an InvalidStateError and abort these steps
|
if self.ended.get() {
|
||||||
// If newState’s baseLayer's was created with an XRSession other than session,
|
return Err(Error::InvalidState);
|
||||||
// throw an InvalidStateError and abort these steps
|
}
|
||||||
|
// Step 3:
|
||||||
|
if let Some(ref layer) = init.baseLayer {
|
||||||
|
if Dom::from_ref(layer.session()) != Dom::from_ref(self) {
|
||||||
|
return Err(Error::InvalidState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXManishearth step 4:
|
||||||
// If newState’s inlineVerticalFieldOfView is set and session is an
|
// If newState’s inlineVerticalFieldOfView is set and session is an
|
||||||
// immersive session, throw an InvalidStateError and abort these steps.
|
// immersive session, throw an InvalidStateError and abort these steps.
|
||||||
|
|
||||||
|
@ -203,6 +284,7 @@ impl XRSessionMethods for XRSession {
|
||||||
pending.set_layer(Some(&layer))
|
pending.set_layer(Some(&layer))
|
||||||
}
|
}
|
||||||
// XXXManishearth handle inlineVerticalFieldOfView
|
// XXXManishearth handle inlineVerticalFieldOfView
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
|
||||||
|
@ -305,9 +387,15 @@ impl XRSessionMethods for XRSession {
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-end
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-end
|
||||||
fn End(&self) -> Rc<Promise> {
|
fn End(&self) -> Rc<Promise> {
|
||||||
// XXXManishearth implement device disconnection and session ending
|
let global = self.global();
|
||||||
let p = Promise::new(&self.global());
|
let p = Promise::new(&global);
|
||||||
p.resolve_native(&());
|
self.end_promises.borrow_mut().push(p.clone());
|
||||||
|
// This is duplicated in event_callback since this should
|
||||||
|
// happen ASAP for end() but can happen later if the device
|
||||||
|
// shuts itself down
|
||||||
|
self.ended.set(true);
|
||||||
|
global.as_window().Navigator().Xr().end_session(self);
|
||||||
|
self.session.borrow_mut().end_session();
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
78
components/script/dom/xrsessionevent.rs
Normal file
78
components/script/dom/xrsessionevent.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRSessionEventBinding::{self, XRSessionEventMethods};
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
|
use crate::dom::bindings::str::DOMString;
|
||||||
|
use crate::dom::event::Event;
|
||||||
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::window::Window;
|
||||||
|
use crate::dom::xrsession::XRSession;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
use servo_atoms::Atom;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct XRSessionEvent {
|
||||||
|
event: Event,
|
||||||
|
session: Dom<XRSession>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XRSessionEvent {
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn new_inherited(session: &XRSession) -> XRSessionEvent {
|
||||||
|
XRSessionEvent {
|
||||||
|
event: Event::new_inherited(),
|
||||||
|
session: Dom::from_ref(session),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
global: &GlobalScope,
|
||||||
|
type_: Atom,
|
||||||
|
bubbles: bool,
|
||||||
|
cancelable: bool,
|
||||||
|
session: &XRSession,
|
||||||
|
) -> DomRoot<XRSessionEvent> {
|
||||||
|
let trackevent = reflect_dom_object(
|
||||||
|
Box::new(XRSessionEvent::new_inherited(&session)),
|
||||||
|
global,
|
||||||
|
XRSessionEventBinding::Wrap,
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let event = trackevent.upcast::<Event>();
|
||||||
|
event.init_event(type_, bubbles, cancelable);
|
||||||
|
}
|
||||||
|
trackevent
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Constructor(
|
||||||
|
window: &Window,
|
||||||
|
type_: DOMString,
|
||||||
|
init: &XRSessionEventBinding::XRSessionEventInit,
|
||||||
|
) -> Fallible<DomRoot<XRSessionEvent>> {
|
||||||
|
Ok(XRSessionEvent::new(
|
||||||
|
&window.global(),
|
||||||
|
Atom::from(type_),
|
||||||
|
init.parent.bubbles,
|
||||||
|
init.parent.cancelable,
|
||||||
|
&init.session,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XRSessionEventMethods for XRSessionEvent {
|
||||||
|
// https://immersive-web.github.io/webxr/#dom-xrsessioneventinit-session
|
||||||
|
fn Session(&self) -> DomRoot<XRSession> {
|
||||||
|
DomRoot::from_ref(&*self.session)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#dom-event-istrusted
|
||||||
|
fn IsTrusted(&self) -> bool {
|
||||||
|
self.event.IsTrusted()
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,13 +7,14 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::callback::ExceptionHandling;
|
use crate::dom::bindings::callback::ExceptionHandling;
|
||||||
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRTestBinding::{
|
use crate::dom::bindings::codegen::Bindings::XRTestBinding::{
|
||||||
self, FakeXRDeviceInit, XRTestMethods,
|
self, FakeXRDeviceInit, XRTestMethods,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::fakexrdevice::{get_origin, get_views, FakeXRDevice};
|
use crate::dom::fakexrdevice::{get_origin, get_views, FakeXRDevice};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
|
@ -31,6 +32,7 @@ use webxr_api::{self, Error as XRError, MockDeviceInit, MockDeviceMsg};
|
||||||
pub struct XRTest {
|
pub struct XRTest {
|
||||||
reflector: Reflector,
|
reflector: Reflector,
|
||||||
session_started: Cell<bool>,
|
session_started: Cell<bool>,
|
||||||
|
devices_connected: DomRefCell<Vec<Dom<FakeXRDevice>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRTest {
|
impl XRTest {
|
||||||
|
@ -38,6 +40,7 @@ impl XRTest {
|
||||||
XRTest {
|
XRTest {
|
||||||
reflector: Reflector::new(),
|
reflector: Reflector::new(),
|
||||||
session_started: Cell::new(false),
|
session_started: Cell::new(false),
|
||||||
|
devices_connected: DomRefCell::new(vec![]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +60,9 @@ impl XRTest {
|
||||||
let promise = trusted.root();
|
let promise = trusted.root();
|
||||||
if let Ok(sender) = response {
|
if let Ok(sender) = response {
|
||||||
let device = FakeXRDevice::new(&self.global(), sender);
|
let device = FakeXRDevice::new(&self.global(), sender);
|
||||||
|
self.devices_connected
|
||||||
|
.borrow_mut()
|
||||||
|
.push(Dom::from_ref(&device));
|
||||||
promise.resolve_native(&device);
|
promise.resolve_native(&device);
|
||||||
} else {
|
} else {
|
||||||
promise.reject_native(&());
|
promise.reject_native(&());
|
||||||
|
@ -174,8 +180,45 @@ impl XRTestMethods for XRTest {
|
||||||
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
||||||
fn DisconnectAllDevices(&self) -> Rc<Promise> {
|
fn DisconnectAllDevices(&self) -> Rc<Promise> {
|
||||||
// XXXManishearth implement device disconnection and session ending
|
// XXXManishearth implement device disconnection and session ending
|
||||||
let p = Promise::new(&self.global());
|
let global = self.global();
|
||||||
|
let p = Promise::new(&global);
|
||||||
|
let mut devices = self.devices_connected.borrow_mut();
|
||||||
|
if devices.is_empty() {
|
||||||
p.resolve_native(&());
|
p.resolve_native(&());
|
||||||
|
} else {
|
||||||
|
let mut len = devices.len();
|
||||||
|
|
||||||
|
let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap();
|
||||||
|
let mut rooted_devices: Vec<_> =
|
||||||
|
devices.iter().map(|x| DomRoot::from_ref(&**x)).collect();
|
||||||
|
devices.clear();
|
||||||
|
for device in rooted_devices.drain(..) {
|
||||||
|
device.disconnect(sender.clone());
|
||||||
|
}
|
||||||
|
let mut trusted = Some(TrustedPromise::new(p.clone()));
|
||||||
|
let (task_source, canceller) = global
|
||||||
|
.as_window()
|
||||||
|
.task_manager()
|
||||||
|
.dom_manipulation_task_source_with_canceller();
|
||||||
|
|
||||||
|
ROUTER.add_route(
|
||||||
|
receiver.to_opaque(),
|
||||||
|
Box::new(move |_| {
|
||||||
|
len -= 1;
|
||||||
|
if len == 0 {
|
||||||
|
let trusted = trusted
|
||||||
|
.take()
|
||||||
|
.expect("DisconnectAllDevices disconnected more devices than expected");
|
||||||
|
let _ =
|
||||||
|
task_source.queue_with_canceller(trusted.resolve_task(()), &canceller);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// XXXManishearth this is a hack, it will need to be replaced when
|
||||||
|
// we improve how mock messaging works
|
||||||
|
p.resolve_native(&())
|
||||||
|
};
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,13 @@ use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGL
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::Error;
|
||||||
use crate::dom::bindings::error::Fallible;
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector, DomObject};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::webgl_validations::types::TexImageTarget;
|
use crate::dom::webgl_validations::types::TexImageTarget;
|
||||||
use crate::dom::webglframebuffer::WebGLFramebuffer;
|
use crate::dom::webglframebuffer::WebGLFramebuffer;
|
||||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
use crate::dom::xrlayer::XRLayer;
|
|
||||||
use crate::dom::xrsession::XRSession;
|
use crate::dom::xrsession::XRSession;
|
||||||
use crate::dom::xrview::XRView;
|
use crate::dom::xrview::XRView;
|
||||||
use crate::dom::xrviewport::XRViewport;
|
use crate::dom::xrviewport::XRViewport;
|
||||||
|
@ -28,7 +27,7 @@ use webxr_api::Views;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRWebGLLayer {
|
pub struct XRWebGLLayer {
|
||||||
xrlayer: XRLayer,
|
reflector_: Reflector,
|
||||||
antialias: bool,
|
antialias: bool,
|
||||||
depth: bool,
|
depth: bool,
|
||||||
stencil: bool,
|
stencil: bool,
|
||||||
|
@ -46,7 +45,7 @@ impl XRWebGLLayer {
|
||||||
framebuffer: &WebGLFramebuffer,
|
framebuffer: &WebGLFramebuffer,
|
||||||
) -> XRWebGLLayer {
|
) -> XRWebGLLayer {
|
||||||
XRWebGLLayer {
|
XRWebGLLayer {
|
||||||
xrlayer: XRLayer::new_inherited(),
|
reflector_: Reflector::new(),
|
||||||
antialias: init.antialias,
|
antialias: init.antialias,
|
||||||
depth: init.depth,
|
depth: init.depth,
|
||||||
stencil: init.stencil,
|
stencil: init.stencil,
|
||||||
|
@ -83,6 +82,13 @@ impl XRWebGLLayer {
|
||||||
context: &WebGLRenderingContext,
|
context: &WebGLRenderingContext,
|
||||||
init: &XRWebGLLayerInit,
|
init: &XRWebGLLayerInit,
|
||||||
) -> Fallible<DomRoot<Self>> {
|
) -> Fallible<DomRoot<Self>> {
|
||||||
|
// Step 2
|
||||||
|
if session.is_ended() {
|
||||||
|
return Err(Error::InvalidState);
|
||||||
|
}
|
||||||
|
// XXXManishearth step 3: throw error if context is lost
|
||||||
|
// XXXManishearth step 4: check XR compat flag for immersive sessions
|
||||||
|
|
||||||
let cx = global.get_cx();
|
let cx = global.get_cx();
|
||||||
let old_fbo = context.bound_framebuffer();
|
let old_fbo = context.bound_framebuffer();
|
||||||
let old_texture = context
|
let old_texture = context
|
||||||
|
@ -139,6 +145,10 @@ impl XRWebGLLayer {
|
||||||
&framebuffer,
|
&framebuffer,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn session(&self) -> &XRSession {
|
||||||
|
&self.session
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRWebGLLayerMethods for XRWebGLLayer {
|
impl XRWebGLLayerMethods for XRWebGLLayer {
|
||||||
|
|
|
@ -44,18 +44,12 @@
|
||||||
[XRInputSourceArray interface: attribute length]
|
[XRInputSourceArray interface: attribute length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface: existence and properties of interface object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRInputSource interface: attribute targetRayMode]
|
[XRInputSource interface: attribute targetRayMode]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface object length]
|
[XRBoundedReferenceSpace interface object length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface object length]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession)]
|
[XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -74,18 +68,12 @@
|
||||||
[XRReferenceSpaceEvent interface object length]
|
[XRReferenceSpaceEvent interface object length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface: existence and properties of interface prototype object's @@unscopables property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGLRenderingContext interface: operation makeXRCompatible()]
|
[WebGLRenderingContext interface: operation makeXRCompatible()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: attribute added]
|
[XRInputSourcesChangeEvent interface: attribute added]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface object name]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRInputSourceEvent interface: attribute inputSource]
|
[XRInputSourceEvent interface: attribute inputSource]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -98,18 +86,12 @@
|
||||||
[XRInputSourcesChangeEvent interface: attribute removed]
|
[XRInputSourcesChangeEvent interface: attribute removed]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface: existence and properties of interface prototype object's "constructor" property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRSession interface: attribute onselectstart]
|
[XRSession interface: attribute onselectstart]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourceEvent interface: existence and properties of interface prototype object]
|
[XRInputSourceEvent interface: existence and properties of interface prototype object]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface: attribute session]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRReferenceSpaceEvent interface: existence and properties of interface object]
|
[XRReferenceSpaceEvent interface: existence and properties of interface object]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -149,12 +131,6 @@
|
||||||
[XRBoundedReferenceSpace interface: attribute boundsGeometry]
|
[XRBoundedReferenceSpace interface: attribute boundsGeometry]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRWebGLLayer interface: existence and properties of interface object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRWebGLLayer interface: existence and properties of interface prototype object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRReferenceSpaceEvent interface object name]
|
[XRReferenceSpaceEvent interface object name]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -236,18 +212,12 @@
|
||||||
[XRSession interface: attribute oninputsourceschange]
|
[XRSession interface: attribute oninputsourceschange]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSessionEvent interface: existence and properties of interface prototype object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object]
|
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XR interface: calling requestSession(XRSessionMode, XRSessionInit) on navigator.xr with too few arguments must throw TypeError]
|
[XR interface: calling requestSession(XRSessionMode, XRSessionInit) on navigator.xr with too few arguments must throw TypeError]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSession interface: attribute onend]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRSession interface: operation end()]
|
[XRSession interface: operation end()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[xrSession_end.https.html]
|
[xrSession_end.https.html]
|
||||||
expected: TIMEOUT
|
expected: ERROR
|
||||||
[end event fires when non-immersive session ends]
|
[end event fires when non-immersive session ends]
|
||||||
expected: NOTRUN
|
expected: NOTRUN
|
||||||
|
|
||||||
[end event fires when immersive session ends]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrSession_input_events_end.https.html]
|
[xrSession_input_events_end.https.html]
|
||||||
|
expected: ERROR
|
||||||
[Calling end during an input callback stops processing at the right time]
|
[Calling end during an input callback stops processing at the right time]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue