mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #25463 - Manishearth:input-mocking, r=asajeffrey
Add input mocking, input sources change event Depends on https://github.com/servo/webxr/pull/118 Also fixes some bugs I found. Wanted to finish and merge this before I started on hit testing since the transient hit test stuff might have overlap. There are a bunch of missing mock pieces that I'll probably do in a separate PR. Still need to run tests. Some things I skipped: - Doing handedness/target ray setting: See https://github.com/immersive-web/webxr-test-api/issues/46 , this would require making our impl support these changing - Handling button initial state: Would require some mock changes, but I ran out of time - Handling profiles/etc: We don't yet have impl support for these r? @jdm
This commit is contained in:
commit
dbee7f7d27
30 changed files with 485 additions and 79 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -6461,7 +6461,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr"
|
name = "webxr"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#c6abf4c60d165ffc978ad2ebd6bcddc3c21698e1"
|
source = "git+https://github.com/servo/webxr#ed1ec1afadce730247401e60994b7f6ff226639d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"euclid",
|
"euclid",
|
||||||
|
@ -6482,7 +6482,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#c6abf4c60d165ffc978ad2ebd6bcddc3c21698e1"
|
source = "git+https://github.com/servo/webxr#ed1ec1afadce730247401e60994b7f6ff226639d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid",
|
"euclid",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
|
|
@ -44,6 +44,7 @@ iceconnectionstatechange
|
||||||
icegatheringstatechange
|
icegatheringstatechange
|
||||||
image
|
image
|
||||||
input
|
input
|
||||||
|
inputsourceschange
|
||||||
invalid
|
invalid
|
||||||
keydown
|
keydown
|
||||||
keypress
|
keypress
|
||||||
|
|
|
@ -534,7 +534,8 @@ unsafe_no_jsmanaged_fields!(
|
||||||
webxr_api::Registry,
|
webxr_api::Registry,
|
||||||
webxr_api::Session,
|
webxr_api::Session,
|
||||||
webxr_api::Frame,
|
webxr_api::Frame,
|
||||||
webxr_api::InputSource
|
webxr_api::InputSource,
|
||||||
|
webxr_api::InputId
|
||||||
);
|
);
|
||||||
unsafe_no_jsmanaged_fields!(ScriptToConstellationChan);
|
unsafe_no_jsmanaged_fields!(ScriptToConstellationChan);
|
||||||
unsafe_no_jsmanaged_fields!(InteractiveMetrics);
|
unsafe_no_jsmanaged_fields!(InteractiveMetrics);
|
||||||
|
|
|
@ -5,11 +5,17 @@
|
||||||
use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::{
|
use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::{
|
||||||
self, FakeXRDeviceMethods, FakeXRRigidTransformInit, FakeXRViewInit,
|
self, FakeXRDeviceMethods, FakeXRRigidTransformInit, FakeXRViewInit,
|
||||||
};
|
};
|
||||||
|
use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::FakeXRInputSourceInit;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
||||||
|
XRHandedness, XRTargetRayMode,
|
||||||
|
};
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
|
use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
|
||||||
use crate::dom::bindings::error::{Error, Fallible};
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::refcounted::TrustedPromise;
|
use crate::dom::bindings::refcounted::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::DomRoot;
|
||||||
|
use crate::dom::fakexrinputcontroller::FakeXRInputController;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
|
@ -19,14 +25,20 @@ use euclid::{RigidTransform3D, Rotation3D, Transform3D, Vector3D};
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use profile_traits::ipc;
|
use profile_traits::ipc;
|
||||||
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webxr_api::{MockDeviceMsg, MockViewInit, MockViewsInit};
|
use webxr_api::{
|
||||||
|
Handedness, InputId, InputSource, MockDeviceMsg, MockInputInit, MockViewInit, MockViewsInit,
|
||||||
|
TargetRayMode, Visibility,
|
||||||
|
};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct FakeXRDevice {
|
pub struct FakeXRDevice {
|
||||||
reflector: Reflector,
|
reflector: Reflector,
|
||||||
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
||||||
sender: IpcSender<MockDeviceMsg>,
|
sender: IpcSender<MockDeviceMsg>,
|
||||||
|
#[ignore_malloc_size_of = "defined in webxr-api"]
|
||||||
|
next_input_id: Cell<InputId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FakeXRDevice {
|
impl FakeXRDevice {
|
||||||
|
@ -34,6 +46,7 @@ impl FakeXRDevice {
|
||||||
FakeXRDevice {
|
FakeXRDevice {
|
||||||
reflector: Reflector::new(),
|
reflector: Reflector::new(),
|
||||||
sender,
|
sender,
|
||||||
|
next_input_id: Cell::new(InputId(0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +176,59 @@ impl FakeXRDeviceMethods for FakeXRDevice {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-simulatevisibilitychange
|
||||||
|
fn SimulateVisibilityChange(&self, v: XRVisibilityState) {
|
||||||
|
let v = match v {
|
||||||
|
XRVisibilityState::Visible => Visibility::Visible,
|
||||||
|
XRVisibilityState::Visible_blurred => Visibility::VisibleBlurred,
|
||||||
|
XRVisibilityState::Hidden => Visibility::Hidden,
|
||||||
|
};
|
||||||
|
let _ = self.sender.send(MockDeviceMsg::VisibilityChange(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-simulateinputsourceconnection
|
||||||
|
fn SimulateInputSourceConnection(
|
||||||
|
&self,
|
||||||
|
init: &FakeXRInputSourceInit,
|
||||||
|
) -> Fallible<DomRoot<FakeXRInputController>> {
|
||||||
|
let id = self.next_input_id.get();
|
||||||
|
self.next_input_id.set(InputId(id.0 + 1));
|
||||||
|
|
||||||
|
let handedness = init.handedness.into();
|
||||||
|
let target_ray_mode = init.targetRayMode.into();
|
||||||
|
|
||||||
|
let pointer_origin = Some(get_origin(&init.pointerOrigin)?);
|
||||||
|
|
||||||
|
let grip_origin = if let Some(ref g) = init.gripOrigin {
|
||||||
|
Some(get_origin(g)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXXManishearth deal with profiles, supportedButtons, selection*
|
||||||
|
|
||||||
|
let source = InputSource {
|
||||||
|
handedness,
|
||||||
|
target_ray_mode,
|
||||||
|
id,
|
||||||
|
supports_grip: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let init = MockInputInit {
|
||||||
|
source,
|
||||||
|
pointer_origin,
|
||||||
|
grip_origin,
|
||||||
|
};
|
||||||
|
|
||||||
|
let global = self.global();
|
||||||
|
let _ = self.sender.send(MockDeviceMsg::AddInputSource(init));
|
||||||
|
|
||||||
|
let controller = FakeXRInputController::new(&global, self.sender.clone(), id);
|
||||||
|
|
||||||
|
Ok(controller)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrdevice-disconnect
|
||||||
fn Disconnect(&self) -> Rc<Promise> {
|
fn Disconnect(&self) -> Rc<Promise> {
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let p = Promise::new(&global);
|
let p = Promise::new(&global);
|
||||||
|
@ -186,3 +251,23 @@ impl FakeXRDeviceMethods for FakeXRDevice {
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<XRHandedness> for Handedness {
|
||||||
|
fn from(h: XRHandedness) -> Self {
|
||||||
|
match h {
|
||||||
|
XRHandedness::None => Handedness::None,
|
||||||
|
XRHandedness::Left => Handedness::Left,
|
||||||
|
XRHandedness::Right => Handedness::Right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XRTargetRayMode> for TargetRayMode {
|
||||||
|
fn from(t: XRTargetRayMode) -> Self {
|
||||||
|
match t {
|
||||||
|
XRTargetRayMode::Gaze => TargetRayMode::Gaze,
|
||||||
|
XRTargetRayMode::Tracked_pointer => TargetRayMode::TrackedPointer,
|
||||||
|
XRTargetRayMode::Screen => TargetRayMode::Screen,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
106
components/script/dom/fakexrinputcontroller.rs
Normal file
106
components/script/dom/fakexrinputcontroller.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* 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::FakeXRDeviceBinding::FakeXRRigidTransformInit;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::{
|
||||||
|
self, FakeXRInputControllerMethods,
|
||||||
|
};
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||||
|
use crate::dom::bindings::root::DomRoot;
|
||||||
|
use crate::dom::fakexrdevice::get_origin;
|
||||||
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use webxr_api::{InputId, MockDeviceMsg, MockInputMsg, SelectEvent, SelectKind};
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct FakeXRInputController {
|
||||||
|
reflector: Reflector,
|
||||||
|
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
||||||
|
sender: IpcSender<MockDeviceMsg>,
|
||||||
|
#[ignore_malloc_size_of = "defined in webxr-api"]
|
||||||
|
id: InputId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FakeXRInputController {
|
||||||
|
pub fn new_inherited(sender: IpcSender<MockDeviceMsg>, id: InputId) -> FakeXRInputController {
|
||||||
|
FakeXRInputController {
|
||||||
|
reflector: Reflector::new(),
|
||||||
|
sender,
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
global: &GlobalScope,
|
||||||
|
sender: IpcSender<MockDeviceMsg>,
|
||||||
|
id: InputId,
|
||||||
|
) -> DomRoot<FakeXRInputController> {
|
||||||
|
reflect_dom_object(
|
||||||
|
Box::new(FakeXRInputController::new_inherited(sender, id)),
|
||||||
|
global,
|
||||||
|
FakeXRInputControllerBinding::Wrap,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_message(&self, msg: MockInputMsg) {
|
||||||
|
let _ = self
|
||||||
|
.sender
|
||||||
|
.send(MockDeviceMsg::MessageInputSource(self.id, msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FakeXRInputControllerMethods for FakeXRInputController {
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-setpointerorigin
|
||||||
|
fn SetPointerOrigin(&self, origin: &FakeXRRigidTransformInit, _emulated: bool) -> Fallible<()> {
|
||||||
|
self.send_message(MockInputMsg::SetPointerOrigin(Some(get_origin(origin)?)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-setgriporigin
|
||||||
|
fn SetGripOrigin(&self, origin: &FakeXRRigidTransformInit, _emulated: bool) -> Fallible<()> {
|
||||||
|
self.send_message(MockInputMsg::SetGripOrigin(Some(get_origin(origin)?)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-cleargriporigin
|
||||||
|
fn ClearGripOrigin(&self) {
|
||||||
|
self.send_message(MockInputMsg::SetGripOrigin(None))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-disconnect
|
||||||
|
fn Disconnect(&self) {
|
||||||
|
self.send_message(MockInputMsg::Disconnect)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-reconnect
|
||||||
|
fn Reconnect(&self) {
|
||||||
|
self.send_message(MockInputMsg::Reconnect)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-startselection
|
||||||
|
fn StartSelection(&self) {
|
||||||
|
self.send_message(MockInputMsg::TriggerSelect(
|
||||||
|
SelectKind::Select,
|
||||||
|
SelectEvent::Start,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-endselection
|
||||||
|
fn EndSelection(&self) {
|
||||||
|
self.send_message(MockInputMsg::TriggerSelect(
|
||||||
|
SelectKind::Select,
|
||||||
|
SelectEvent::End,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-simulateselect
|
||||||
|
fn SimulateSelect(&self) {
|
||||||
|
self.send_message(MockInputMsg::TriggerSelect(
|
||||||
|
SelectKind::Select,
|
||||||
|
SelectEvent::Select,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
|
@ -301,6 +301,7 @@ pub mod eventtarget;
|
||||||
pub mod extendableevent;
|
pub mod extendableevent;
|
||||||
pub mod extendablemessageevent;
|
pub mod extendablemessageevent;
|
||||||
pub mod fakexrdevice;
|
pub mod fakexrdevice;
|
||||||
|
pub mod fakexrinputcontroller;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod filelist;
|
pub mod filelist;
|
||||||
pub mod filereader;
|
pub mod filereader;
|
||||||
|
@ -564,6 +565,7 @@ pub mod xrframe;
|
||||||
pub mod xrinputsource;
|
pub mod xrinputsource;
|
||||||
pub mod xrinputsourcearray;
|
pub mod xrinputsourcearray;
|
||||||
pub mod xrinputsourceevent;
|
pub mod xrinputsourceevent;
|
||||||
|
pub mod xrinputsourceschangeevent;
|
||||||
pub mod xrpose;
|
pub mod xrpose;
|
||||||
pub mod xrreferencespace;
|
pub mod xrreferencespace;
|
||||||
pub mod xrrenderstate;
|
pub mod xrrenderstate;
|
||||||
|
|
|
@ -10,9 +10,6 @@ interface FakeXRDevice {
|
||||||
// requestAnimationFrame() callbacks.
|
// requestAnimationFrame() callbacks.
|
||||||
[Throws] void setViews(sequence<FakeXRViewInit> views);
|
[Throws] void setViews(sequence<FakeXRViewInit> views);
|
||||||
|
|
||||||
// // behaves as if device was disconnected
|
|
||||||
// Promise<void> disconnect();
|
|
||||||
|
|
||||||
[Throws] void setViewerOrigin(FakeXRRigidTransformInit origin, optional boolean emulatedPosition = false);
|
[Throws] void setViewerOrigin(FakeXRRigidTransformInit origin, optional boolean emulatedPosition = false);
|
||||||
void clearViewerOrigin();
|
void clearViewerOrigin();
|
||||||
|
|
||||||
|
@ -20,15 +17,11 @@ interface FakeXRDevice {
|
||||||
void clearFloorOrigin();
|
void clearFloorOrigin();
|
||||||
|
|
||||||
// // Simulates devices focusing and blurring sessions.
|
// // Simulates devices focusing and blurring sessions.
|
||||||
// void simulateVisibilityChange(XRVisibilityState);
|
void simulateVisibilityChange(XRVisibilityState state);
|
||||||
|
|
||||||
// void setBoundsGeometry(sequence<FakeXRBoundsPoint> boundsCoodinates);
|
// void setBoundsGeometry(sequence<FakeXRBoundsPoint> boundsCoodinates);
|
||||||
// // Sets eye level used for calculating floor-level spaces
|
|
||||||
// void setEyeLevel(float eyeLevel);
|
|
||||||
|
|
||||||
|
[Throws] FakeXRInputController simulateInputSourceConnection(FakeXRInputSourceInit init);
|
||||||
// Promise<FakeXRInputController>
|
|
||||||
// simulateInputSourceConnection(FakeXRInputSourceInit);
|
|
||||||
|
|
||||||
// behaves as if device was disconnected
|
// behaves as if device was disconnected
|
||||||
Promise<void> disconnect();
|
Promise<void> disconnect();
|
||||||
|
|
53
components/script/dom/webidls/FakeXRInputController.webidl
Normal file
53
components/script/dom/webidls/FakeXRInputController.webidl
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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-test-api/#fakexrinputcontroller
|
||||||
|
|
||||||
|
[Exposed=Window, Pref="dom.webxr.test"]
|
||||||
|
interface FakeXRInputController {
|
||||||
|
// void setHandedness(XRHandedness handedness);
|
||||||
|
// void setTargetRayMode(XRTargetRayMode targetRayMode);
|
||||||
|
// void setProfiles(sequence<DOMString> profiles);
|
||||||
|
[Throws] void setGripOrigin(FakeXRRigidTransformInit gripOrigin, optional boolean emulatedPosition = false);
|
||||||
|
void clearGripOrigin();
|
||||||
|
[Throws] void setPointerOrigin(FakeXRRigidTransformInit pointerOrigin, optional boolean emulatedPosition = false);
|
||||||
|
|
||||||
|
void disconnect();
|
||||||
|
void reconnect();
|
||||||
|
|
||||||
|
void startSelection();
|
||||||
|
void endSelection();
|
||||||
|
void simulateSelect();
|
||||||
|
|
||||||
|
// void setSupportedButtons(sequence<FakeXRButtonStateInit> supportedButtons);
|
||||||
|
// void updateButtonState(FakeXRButtonStateInit buttonState);
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary FakeXRInputSourceInit {
|
||||||
|
required XRHandedness handedness;
|
||||||
|
required XRTargetRayMode targetRayMode;
|
||||||
|
required FakeXRRigidTransformInit pointerOrigin;
|
||||||
|
required sequence<DOMString> profiles;
|
||||||
|
boolean selectionStarted = false;
|
||||||
|
boolean selectionClicked = false;
|
||||||
|
sequence<FakeXRButtonStateInit> supportedButtons;
|
||||||
|
FakeXRRigidTransformInit gripOrigin;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FakeXRButtonType {
|
||||||
|
"grip",
|
||||||
|
"touchpad",
|
||||||
|
"thumbstick",
|
||||||
|
"optional-button",
|
||||||
|
"optional-thumbstick"
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary FakeXRButtonStateInit {
|
||||||
|
required FakeXRButtonType buttonType;
|
||||||
|
required boolean pressed;
|
||||||
|
required boolean touched;
|
||||||
|
required float pressedValue;
|
||||||
|
float xValue = 0.0;
|
||||||
|
float yValue = 0.0;
|
||||||
|
};
|
|
@ -19,7 +19,7 @@ enum XRTargetRayMode {
|
||||||
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
|
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
|
||||||
interface XRInputSource {
|
interface XRInputSource {
|
||||||
readonly attribute XRHandedness handedness;
|
readonly attribute XRHandedness handedness;
|
||||||
// [SameObject] readonly attribute XRTargetRayMode targetRayMode;
|
readonly attribute XRTargetRayMode targetRayMode;
|
||||||
[SameObject] readonly attribute XRSpace targetRaySpace;
|
[SameObject] readonly attribute XRSpace targetRaySpace;
|
||||||
[SameObject] readonly attribute XRSpace? gripSpace;
|
[SameObject] readonly attribute XRSpace? gripSpace;
|
||||||
// [SameObject] readonly attribute Gamepad? gamepad;
|
// [SameObject] readonly attribute Gamepad? gamepad;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* 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/#xrinputsourceschangedevent-interface
|
||||||
|
|
||||||
|
[SecureContext, Exposed=Window, Pref="dom.webxr.test"]
|
||||||
|
interface XRInputSourcesChangeEvent : Event {
|
||||||
|
constructor(DOMString type, XRInputSourcesChangeEventInit eventInitDict);
|
||||||
|
[SameObject] readonly attribute XRSession session;
|
||||||
|
/* [SameObject] */ readonly attribute /* FrozenArray<XRInputSource> */ any added;
|
||||||
|
/* [SameObject] */ readonly attribute /* FrozenArray<XRInputSource> */ any removed;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary XRInputSourcesChangeEventInit : EventInit {
|
||||||
|
required XRSession session;
|
||||||
|
required sequence<XRInputSource> added;
|
||||||
|
required sequence<XRInputSource> removed;
|
||||||
|
};
|
|
@ -40,7 +40,7 @@ interface XRSession : EventTarget {
|
||||||
attribute EventHandler onend;
|
attribute EventHandler onend;
|
||||||
attribute EventHandler onselect;
|
attribute EventHandler onselect;
|
||||||
attribute EventHandler onsqueeze;
|
attribute EventHandler onsqueeze;
|
||||||
// attribute EventHandler oninputsourceschange;
|
attribute EventHandler oninputsourceschange;
|
||||||
attribute EventHandler onselectstart;
|
attribute EventHandler onselectstart;
|
||||||
attribute EventHandler onselectend;
|
attribute EventHandler onselectend;
|
||||||
attribute EventHandler onsqueezestart;
|
attribute EventHandler onsqueezestart;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding;
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
||||||
XRHandedness, XRInputSourceMethods,
|
XRHandedness, XRInputSourceMethods, XRTargetRayMode,
|
||||||
};
|
};
|
||||||
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::{Dom, DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||||
|
@ -12,7 +12,7 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::xrsession::XRSession;
|
use crate::dom::xrsession::XRSession;
|
||||||
use crate::dom::xrspace::XRSpace;
|
use crate::dom::xrspace::XRSpace;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webxr_api::{Handedness, InputId, InputSource};
|
use webxr_api::{Handedness, InputId, InputSource, TargetRayMode};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRInputSource {
|
pub struct XRInputSource {
|
||||||
|
@ -64,6 +64,15 @@ impl XRInputSourceMethods for XRInputSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-targetraymode
|
||||||
|
fn TargetRayMode(&self) -> XRTargetRayMode {
|
||||||
|
match self.info.target_ray_mode {
|
||||||
|
TargetRayMode::Gaze => XRTargetRayMode::Gaze,
|
||||||
|
TargetRayMode::TrackedPointer => XRTargetRayMode::Tracked_pointer,
|
||||||
|
TargetRayMode::Screen => XRTargetRayMode::Screen,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-targetrayspace
|
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-targetrayspace
|
||||||
fn TargetRaySpace(&self) -> DomRoot<XRSpace> {
|
fn TargetRaySpace(&self) -> DomRoot<XRSpace> {
|
||||||
self.target_ray_space.or_init(|| {
|
self.target_ray_space.or_init(|| {
|
||||||
|
@ -75,7 +84,7 @@ impl XRInputSourceMethods for XRInputSource {
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-gripspace
|
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-gripspace
|
||||||
fn GetGripSpace(&self) -> Option<DomRoot<XRSpace>> {
|
fn GetGripSpace(&self) -> Option<DomRoot<XRSpace>> {
|
||||||
if self.info.supports_grip {
|
if self.info.supports_grip {
|
||||||
Some(self.target_ray_space.or_init(|| {
|
Some(self.grip_space.or_init(|| {
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
XRSpace::new_inputspace(&global, &self.session, &self, true)
|
XRSpace::new_inputspace(&global, &self.session, &self, true)
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding;
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding::XRInputSourceArrayMethods;
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding::XRInputSourceArrayMethods;
|
||||||
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
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::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
|
use crate::dom::event::Event;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::xrinputsource::XRInputSource;
|
use crate::dom::xrinputsource::XRInputSource;
|
||||||
|
use crate::dom::xrinputsourceschangeevent::XRInputSourcesChangeEvent;
|
||||||
use crate::dom::xrsession::XRSession;
|
use crate::dom::xrsession::XRSession;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webxr_api::InputId;
|
use webxr_api::{InputId, InputSource};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRInputSourceArray {
|
pub struct XRInputSourceArray {
|
||||||
|
@ -48,6 +51,56 @@ impl XRInputSourceArray {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_input_source(&self, session: &XRSession, info: InputSource) {
|
||||||
|
let mut input_sources = self.input_sources.borrow_mut();
|
||||||
|
let global = self.global();
|
||||||
|
let input = XRInputSource::new(&global, &session, info);
|
||||||
|
debug_assert!(
|
||||||
|
input_sources.iter().find(|i| i.id() == info.id).is_none(),
|
||||||
|
"Should never add a duplicate input id!"
|
||||||
|
);
|
||||||
|
input_sources.push(Dom::from_ref(&input));
|
||||||
|
|
||||||
|
let added = [input];
|
||||||
|
|
||||||
|
let event = XRInputSourcesChangeEvent::new(
|
||||||
|
&global,
|
||||||
|
atom!("inputsourceschange"),
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
session,
|
||||||
|
&added,
|
||||||
|
&[],
|
||||||
|
);
|
||||||
|
// Release the refcell guard
|
||||||
|
drop(input_sources);
|
||||||
|
event.upcast::<Event>().fire(session.upcast());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_input_source(&self, session: &XRSession, id: InputId) {
|
||||||
|
let mut input_sources = self.input_sources.borrow_mut();
|
||||||
|
let global = self.global();
|
||||||
|
let removed = if let Some(i) = input_sources.iter().find(|i| i.id() == id) {
|
||||||
|
[DomRoot::from_ref(&**i)]
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let event = XRInputSourcesChangeEvent::new(
|
||||||
|
&global,
|
||||||
|
atom!("inputsourceschange"),
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
session,
|
||||||
|
&[],
|
||||||
|
&removed,
|
||||||
|
);
|
||||||
|
input_sources.retain(|i| i.id() != id);
|
||||||
|
// release the refcell guard
|
||||||
|
drop(input_sources);
|
||||||
|
event.upcast::<Event>().fire(session.upcast());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find(&self, id: InputId) -> Option<DomRoot<XRInputSource>> {
|
pub fn find(&self, id: InputId) -> Option<DomRoot<XRInputSource>> {
|
||||||
self.input_sources
|
self.input_sources
|
||||||
.borrow()
|
.borrow()
|
||||||
|
|
117
components/script/dom/xrinputsourceschangeevent.rs
Normal file
117
components/script/dom/xrinputsourceschangeevent.rs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/* 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::compartments::enter_realm;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRInputSourcesChangeEventBinding::{
|
||||||
|
self, XRInputSourcesChangeEventMethods,
|
||||||
|
};
|
||||||
|
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::xrinputsource::XRInputSource;
|
||||||
|
use crate::dom::xrsession::XRSession;
|
||||||
|
use crate::script_runtime::JSContext;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
use js::conversions::ToJSValConvertible;
|
||||||
|
use js::jsapi::Heap;
|
||||||
|
use js::jsval::{JSVal, UndefinedValue};
|
||||||
|
use servo_atoms::Atom;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct XRInputSourcesChangeEvent {
|
||||||
|
event: Event,
|
||||||
|
session: Dom<XRSession>,
|
||||||
|
#[ignore_malloc_size_of = "mozjs"]
|
||||||
|
added: Heap<JSVal>,
|
||||||
|
#[ignore_malloc_size_of = "mozjs"]
|
||||||
|
removed: Heap<JSVal>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XRInputSourcesChangeEvent {
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn new_inherited(session: &XRSession) -> XRInputSourcesChangeEvent {
|
||||||
|
XRInputSourcesChangeEvent {
|
||||||
|
event: Event::new_inherited(),
|
||||||
|
session: Dom::from_ref(session),
|
||||||
|
added: Heap::default(),
|
||||||
|
removed: Heap::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
pub fn new(
|
||||||
|
global: &GlobalScope,
|
||||||
|
type_: Atom,
|
||||||
|
bubbles: bool,
|
||||||
|
cancelable: bool,
|
||||||
|
session: &XRSession,
|
||||||
|
added: &[DomRoot<XRInputSource>],
|
||||||
|
removed: &[DomRoot<XRInputSource>],
|
||||||
|
) -> DomRoot<XRInputSourcesChangeEvent> {
|
||||||
|
let changeevent = reflect_dom_object(
|
||||||
|
Box::new(XRInputSourcesChangeEvent::new_inherited(session)),
|
||||||
|
global,
|
||||||
|
XRInputSourcesChangeEventBinding::Wrap,
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let event = changeevent.upcast::<Event>();
|
||||||
|
event.init_event(type_, bubbles, cancelable);
|
||||||
|
}
|
||||||
|
let _ac = enter_realm(&*global);
|
||||||
|
let cx = global.get_cx();
|
||||||
|
unsafe {
|
||||||
|
rooted!(in(*cx) let mut added_val = UndefinedValue());
|
||||||
|
added.to_jsval(*cx, added_val.handle_mut());
|
||||||
|
changeevent.added.set(added_val.get());
|
||||||
|
rooted!(in(*cx) let mut removed_val = UndefinedValue());
|
||||||
|
removed.to_jsval(*cx, removed_val.handle_mut());
|
||||||
|
changeevent.added.set(removed_val.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
changeevent
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Constructor(
|
||||||
|
window: &Window,
|
||||||
|
type_: DOMString,
|
||||||
|
init: &XRInputSourcesChangeEventBinding::XRInputSourcesChangeEventInit,
|
||||||
|
) -> DomRoot<XRInputSourcesChangeEvent> {
|
||||||
|
XRInputSourcesChangeEvent::new(
|
||||||
|
&window.global(),
|
||||||
|
Atom::from(type_),
|
||||||
|
init.parent.bubbles,
|
||||||
|
init.parent.cancelable,
|
||||||
|
&init.session,
|
||||||
|
&*init.added,
|
||||||
|
&*init.removed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XRInputSourcesChangeEventMethods for XRInputSourcesChangeEvent {
|
||||||
|
// https://immersive-web.github.io/webxr/#dom-xrinputsourceschangeevent-session
|
||||||
|
fn Session(&self) -> DomRoot<XRSession> {
|
||||||
|
DomRoot::from_ref(&*self.session)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://immersive-web.github.io/webxr/#dom-xrinputsourceschangeevent-added
|
||||||
|
fn Added(&self, _cx: JSContext) -> JSVal {
|
||||||
|
self.added.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://immersive-web.github.io/webxr/#dom-xrinputsourceschangeevent-removed
|
||||||
|
fn Removed(&self, _cx: JSContext) -> JSVal {
|
||||||
|
self.removed.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#dom-event-istrusted
|
||||||
|
fn IsTrusted(&self) -> bool {
|
||||||
|
self.event.IsTrusted()
|
||||||
|
}
|
||||||
|
}
|
|
@ -289,7 +289,12 @@ impl XRSession {
|
||||||
);
|
);
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
},
|
},
|
||||||
_ => (), // XXXManishearth TBD
|
XREvent::AddInput(info) => {
|
||||||
|
self.input_sources.add_input_source(self, info);
|
||||||
|
},
|
||||||
|
XREvent::RemoveInput(id) => {
|
||||||
|
self.input_sources.remove_input_source(self, id);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +437,13 @@ impl XRSessionMethods for XRSession {
|
||||||
SetOnvisibilitychange
|
SetOnvisibilitychange
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// https://immersive-web.github.io/webxr/#eventdef-xrsession-inputsourceschange
|
||||||
|
event_handler!(
|
||||||
|
inputsourceschange,
|
||||||
|
GetOninputsourceschange,
|
||||||
|
SetOninputsourceschange
|
||||||
|
);
|
||||||
|
|
||||||
// https://immersive-web.github.io/webxr/#dom-xrsession-renderstate
|
// https://immersive-web.github.io/webxr/#dom-xrsession-renderstate
|
||||||
fn RenderState(&self) -> DomRoot<XRRenderState> {
|
fn RenderState(&self) -> DomRoot<XRRenderState> {
|
||||||
self.active_render_state.get()
|
self.active_render_state.get()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::compartments::enter_realm;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
|
use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding;
|
use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods;
|
use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods;
|
||||||
|
@ -40,6 +41,7 @@ impl XRViewerPose {
|
||||||
session: &XRSession,
|
session: &XRSession,
|
||||||
pose: ApiViewerPose,
|
pose: ApiViewerPose,
|
||||||
) -> DomRoot<XRViewerPose> {
|
) -> DomRoot<XRViewerPose> {
|
||||||
|
let _ac = enter_realm(&*global);
|
||||||
rooted_vec!(let mut views);
|
rooted_vec!(let mut views);
|
||||||
session.with_session(|s| match s.views() {
|
session.with_session(|s| match s.views() {
|
||||||
Views::Inline => views.push(XRView::new(
|
Views::Inline => views.push(XRView::new(
|
||||||
|
|
|
@ -733547,7 +733547,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"webxr/xrInputSource_add_remove.https.html": [
|
"webxr/xrInputSource_add_remove.https.html": [
|
||||||
"4c50670c70ec87754a777cc0bcfe8272e794ca07",
|
"33264ddd68ab09e2ed6a596614116bd1225f2665",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"webxr/xrInputSource_emulatedPosition.https.html": [
|
"webxr/xrInputSource_emulatedPosition.https.html": [
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[events_input_source_recreation.https.html]
|
[events_input_source_recreation.https.html]
|
||||||
|
expected: ERROR
|
||||||
[Input sources are re-created when handedness or target ray mode changes]
|
[Input sources are re-created when handedness or target ray mode changes]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[events_session_select.https.html]
|
|
||||||
[XRInputSources primary input presses properly fires off the right events]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[events_session_select_subframe.https.html]
|
|
||||||
[Ensures that an XRInputSources primary input being pressed and released in the space of a single frame properly fires off the right events]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrInputSource_gamepad_disconnect.https.html]
|
[xrInputSource_gamepad_disconnect.https.html]
|
||||||
|
expected: ERROR
|
||||||
[WebXR InputSource's gamepad gets disconnected when the input source is removed]
|
[WebXR InputSource's gamepad gets disconnected when the input source is removed]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrInputSource_gamepad_input_registered.https.html]
|
[xrInputSource_gamepad_input_registered.https.html]
|
||||||
|
expected: ERROR
|
||||||
[WebXR InputSource's gamepad properly registers input]
|
[WebXR InputSource's gamepad properly registers input]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[getInputPose_handedness.https.html]
|
[getInputPose_handedness.https.html]
|
||||||
|
expected: ERROR
|
||||||
[XRInputSources properly communicate their handedness]
|
[XRInputSources properly communicate their handedness]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -2,21 +2,12 @@
|
||||||
[XR interface: attribute ondevicechange]
|
[XR interface: attribute ondevicechange]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: attribute session]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface object name]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRInputSourceArray interface: iterable<XRInputSource>]
|
[XRInputSourceArray interface: iterable<XRInputSource>]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError]
|
[XR interface: calling supportsSession(XRSessionMode) on navigator.xr with too few arguments must throw TypeError]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface object length]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRReferenceSpaceEvent interface: attribute referenceSpace]
|
[XRReferenceSpaceEvent interface: attribute referenceSpace]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -32,9 +23,6 @@
|
||||||
[XRPose interface: attribute emulatedPosition]
|
[XRPose interface: attribute emulatedPosition]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSource interface: attribute targetRayMode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface object length]
|
[XRBoundedReferenceSpace interface object length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -50,15 +38,9 @@
|
||||||
[WebGLRenderingContext interface: operation makeXRCompatible()]
|
[WebGLRenderingContext interface: operation makeXRCompatible()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: attribute added]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property]
|
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: attribute removed]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRReferenceSpaceEvent interface: existence and properties of interface object]
|
[XRReferenceSpaceEvent interface: existence and properties of interface object]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -83,9 +65,6 @@
|
||||||
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property]
|
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's "constructor" property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface: attribute boundsGeometry]
|
[XRBoundedReferenceSpace interface: attribute boundsGeometry]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -98,12 +77,6 @@
|
||||||
[XRInputSource interface: attribute gamepad]
|
[XRInputSource interface: attribute gamepad]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: existence and properties of interface prototype object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: existence and properties of interface object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRReferenceSpace interface: attribute onreset]
|
[XRReferenceSpace interface: attribute onreset]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -125,9 +98,6 @@
|
||||||
[XRInputSource interface: attribute profiles]
|
[XRInputSource interface: attribute profiles]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRInputSourcesChangeEvent interface: existence and properties of interface prototype object's @@unscopables property]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XR interface: operation requestSession(XRSessionMode, XRSessionInit)]
|
[XR interface: operation requestSession(XRSessionMode, XRSessionInit)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -140,9 +110,6 @@
|
||||||
[XRWebGLLayer interface: attribute ignoreDepthValues]
|
[XRWebGLLayer interface: attribute ignoreDepthValues]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[XRSession interface: attribute oninputsourceschange]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object]
|
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[xrInputSource_add_remove.https.html]
|
|
||||||
[XRInputSources can be properly added and removed from the session]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[xrInputSource_sameObject.https.html]
|
|
||||||
[XRInputSource attributes meet [SameObject\] requirement]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[xrPose_transform_sameObject.https.html]
|
|
||||||
[XRPose.transform meets [SameObject\] requirement]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrReferenceSpace_originOffsetBounded.https.html]
|
[xrReferenceSpace_originOffsetBounded.https.html]
|
||||||
|
expected: ERROR
|
||||||
[Updating XRBoundedReferenceSpace origin offset updates view, input matrices, and bounds geometry.]
|
[Updating XRBoundedReferenceSpace origin offset updates view, input matrices, and bounds geometry.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[xrSession_sameObject.https.html]
|
[xrSession_sameObject.https.html]
|
||||||
|
expected: ERROR
|
||||||
[XRSession attributes meet [SameObject\] requirement]
|
[XRSession attributes meet [SameObject\] requirement]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ let testFunction = (session, fakeDeviceController, t) => new Promise((resolve) =
|
||||||
assert_equals(input_sources[1].handedness, "none");
|
assert_equals(input_sources[1].handedness, "none");
|
||||||
});
|
});
|
||||||
|
|
||||||
fakeDeviceController.removeInputSource(input_source_1);
|
input_source_1.disconnect();
|
||||||
|
|
||||||
session.requestAnimationFrame((time, xrFrame) => {
|
session.requestAnimationFrame((time, xrFrame) => {
|
||||||
let input_sources = session.inputSources;
|
let input_sources = session.inputSources;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue