aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-10-04 04:31:42 -0400
committerGitHub <noreply@github.com>2019-10-04 04:31:42 -0400
commitea4e3aee91ede11a00b17c3d806e305f4a7f5a92 (patch)
tree042472ffdb9f8d58f0656a750f5d024981b5443d
parent30e5cfcdb07166bfa12aae5e0d6086432d7ebd9f (diff)
parent931f0b12de9df385dfff0ad438c88105fe4b6cfe (diff)
downloadservo-ea4e3aee91ede11a00b17c3d806e305f4a7f5a92.tar.gz
servo-ea4e3aee91ede11a00b17c3d806e305f4a7f5a92.zip
Auto merge of #24362 - Manishearth:input-selections, r=asajeffrey
Support input tracking loss and selection events in XR Fixes https://github.com/servo/servo/issues/24192 Requires https://github.com/servo/webxr/pull/65 r? @jdm @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/24362) <!-- Reviewable:end -->
-rw-r--r--Cargo.lock4
-rw-r--r--components/atoms/static_atoms.txt2
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/webidls/XRInputSourceEvent.webidl17
-rw-r--r--components/script/dom/webidls/XRSession.webidl6
-rw-r--r--components/script/dom/xrframe.rs12
-rw-r--r--components/script/dom/xrinputsourceevent.rs90
-rw-r--r--components/script/dom/xrsession.rs58
-rw-r--r--components/script/dom/xrspace.rs6
-rw-r--r--tests/wpt/metadata/webxr/idlharness.https.window.js.ini33
10 files changed, 185 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cb0b2e121d3..e8cac13bd42 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5522,7 +5522,7 @@ dependencies = [
[[package]]
name = "webxr"
version = "0.0.1"
-source = "git+https://github.com/servo/webxr#72d85b8254f8ce5d10f91d59ed35cd5969d15ed8"
+source = "git+https://github.com/servo/webxr#a7e8cae09a5fc3cd3434e644b6e9e2b7697b438c"
dependencies = [
"bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5540,7 +5540,7 @@ dependencies = [
[[package]]
name = "webxr-api"
version = "0.0.1"
-source = "git+https://github.com/servo/webxr#72d85b8254f8ce5d10f91d59ed35cd5969d15ed8"
+source = "git+https://github.com/servo/webxr#a7e8cae09a5fc3cd3434e644b6e9e2b7697b438c"
dependencies = [
"euclid 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt
index c8773667e74..c6873dfc171 100644
--- a/components/atoms/static_atoms.txt
+++ b/components/atoms/static_atoms.txt
@@ -102,6 +102,8 @@ search
seeked
seeking
select
+selectend
+selectstart
serif
signalingstatechange
srclang
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index d6a6c30b823..598832403e0 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -549,6 +549,7 @@ pub mod xmlserializer;
pub mod xr;
pub mod xrframe;
pub mod xrinputsource;
+pub mod xrinputsourceevent;
pub mod xrpose;
pub mod xrreferencespace;
pub mod xrrenderstate;
diff --git a/components/script/dom/webidls/XRInputSourceEvent.webidl b/components/script/dom/webidls/XRInputSourceEvent.webidl
new file mode 100644
index 00000000000..f1ffbf2a799
--- /dev/null
+++ b/components/script/dom/webidls/XRInputSourceEvent.webidl
@@ -0,0 +1,17 @@
+/* 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/#xrinputsourceevent-interface
+
+[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
+interface XRInputSourceEvent : Event {
+ [Throws] constructor(DOMString type, XRInputSourceEventInit eventInitDict);
+ [SameObject] readonly attribute XRFrame frame;
+ [SameObject] readonly attribute XRInputSource inputSource;
+};
+
+dictionary XRInputSourceEventInit : EventInit {
+ required XRFrame frame;
+ required XRInputSource inputSource;
+};
diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl
index 6d946ccef55..820ef11dc70 100644
--- a/components/script/dom/webidls/XRSession.webidl
+++ b/components/script/dom/webidls/XRSession.webidl
@@ -39,8 +39,8 @@ interface XRSession : EventTarget {
// attribute EventHandler onblur;
// attribute EventHandler onfocus;
attribute EventHandler onend;
- // attribute EventHandler onselect;
+ attribute EventHandler onselect;
// attribute EventHandler oninputsourceschange;
- // attribute EventHandler onselectstart;
- // attribute EventHandler onselectend;
+ attribute EventHandler onselectstart;
+ attribute EventHandler onselectend;
};
diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs
index 29572c02300..6c67d896f81 100644
--- a/components/script/dom/xrframe.rs
+++ b/components/script/dom/xrframe.rs
@@ -93,8 +93,16 @@ impl XRFrameMethods for XRFrame {
if !self.active.get() {
return Err(Error::InvalidState);
}
- let space = space.get_pose(&self.data);
- let relative_to = relative_to.get_pose(&self.data);
+ let space = if let Some(space) = space.get_pose(&self.data) {
+ space
+ } else {
+ return Ok(None);
+ };
+ let relative_to = if let Some(r) = relative_to.get_pose(&self.data) {
+ r
+ } else {
+ return Ok(None);
+ };
let pose = relative_to.inverse().pre_transform(&space);
Ok(Some(XRPose::new(&self.global(), pose)))
}
diff --git a/components/script/dom/xrinputsourceevent.rs b/components/script/dom/xrinputsourceevent.rs
new file mode 100644
index 00000000000..aa177f1df9a
--- /dev/null
+++ b/components/script/dom/xrinputsourceevent.rs
@@ -0,0 +1,90 @@
+/* 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::XRInputSourceEventBinding::{
+ self, XRInputSourceEventMethods,
+};
+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::xrframe::XRFrame;
+use crate::dom::xrinputsource::XRInputSource;
+use dom_struct::dom_struct;
+use servo_atoms::Atom;
+
+#[dom_struct]
+pub struct XRInputSourceEvent {
+ event: Event,
+ frame: Dom<XRFrame>,
+ source: Dom<XRInputSource>,
+}
+
+impl XRInputSourceEvent {
+ #[allow(unrooted_must_root)]
+ fn new_inherited(frame: &XRFrame, source: &XRInputSource) -> XRInputSourceEvent {
+ XRInputSourceEvent {
+ event: Event::new_inherited(),
+ frame: Dom::from_ref(frame),
+ source: Dom::from_ref(source),
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ type_: Atom,
+ bubbles: bool,
+ cancelable: bool,
+ frame: &XRFrame,
+ source: &XRInputSource,
+ ) -> DomRoot<XRInputSourceEvent> {
+ let trackevent = reflect_dom_object(
+ Box::new(XRInputSourceEvent::new_inherited(frame, source)),
+ global,
+ XRInputSourceEventBinding::Wrap,
+ );
+ {
+ let event = trackevent.upcast::<Event>();
+ event.init_event(type_, bubbles, cancelable);
+ }
+ trackevent
+ }
+
+ pub fn Constructor(
+ window: &Window,
+ type_: DOMString,
+ init: &XRInputSourceEventBinding::XRInputSourceEventInit,
+ ) -> Fallible<DomRoot<XRInputSourceEvent>> {
+ Ok(XRInputSourceEvent::new(
+ &window.global(),
+ Atom::from(type_),
+ init.parent.bubbles,
+ init.parent.cancelable,
+ &init.frame,
+ &init.inputSource,
+ ))
+ }
+}
+
+impl XRInputSourceEventMethods for XRInputSourceEvent {
+ // https://immersive-web.github.io/webxr/#dom-xrinputsourceeventinit-frame
+ fn Frame(&self) -> DomRoot<XRFrame> {
+ DomRoot::from_ref(&*self.frame)
+ }
+
+ // https://immersive-web.github.io/webxr/#dom-xrinputsourceeventinit-inputsource
+ fn InputSource(&self) -> DomRoot<XRInputSource> {
+ DomRoot::from_ref(&*self.source)
+ }
+
+ // https://dom.spec.whatwg.org/#dom-event-istrusted
+ fn IsTrusted(&self) -> bool {
+ self.event.IsTrusted()
+ }
+}
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index dacfc373540..e7a3fab4677 100644
--- a/components/script/dom/xrsession.rs
+++ b/components/script/dom/xrsession.rs
@@ -33,6 +33,7 @@ use crate::dom::promise::Promise;
use crate::dom::webglframebuffer::WebGLFramebufferAttachmentRoot;
use crate::dom::xrframe::XRFrame;
use crate::dom::xrinputsource::XRInputSource;
+use crate::dom::xrinputsourceevent::XRInputSourceEvent;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrrenderstate::XRRenderState;
use crate::dom::xrsessionevent::XRSessionEvent;
@@ -48,7 +49,7 @@ use profile_traits::ipc;
use std::cell::Cell;
use std::mem;
use std::rc::Rc;
-use webxr_api::{self, Event as XREvent, Frame, Session};
+use webxr_api::{self, Event as XREvent, Frame, SelectEvent, Session};
#[dom_struct]
pub struct XRSession {
@@ -170,6 +171,52 @@ impl XRSession {
let event = XRSessionEvent::new(&self.global(), atom!("end"), false, false, self);
event.upcast::<Event>().fire(self.upcast());
},
+ XREvent::Select(input, kind, frame) => {
+ // https://immersive-web.github.io/webxr/#primary-action
+ let source = self
+ .input_sources
+ .borrow_mut()
+ .iter()
+ .find(|s| s.id() == input)
+ .map(|x| DomRoot::from_ref(&**x));
+ if let Some(source) = source {
+ let frame = XRFrame::new(&self.global(), self, frame);
+ frame.set_active(true);
+ if kind == SelectEvent::Start {
+ let event = XRInputSourceEvent::new(
+ &self.global(),
+ atom!("selectstart"),
+ false,
+ false,
+ &frame,
+ &source,
+ );
+ event.upcast::<Event>().fire(self.upcast());
+ } else {
+ if kind == SelectEvent::Select {
+ let event = XRInputSourceEvent::new(
+ &self.global(),
+ atom!("select"),
+ false,
+ false,
+ &frame,
+ &source,
+ );
+ event.upcast::<Event>().fire(self.upcast());
+ }
+ let event = XRInputSourceEvent::new(
+ &self.global(),
+ atom!("selectend"),
+ false,
+ false,
+ &frame,
+ &source,
+ );
+ event.upcast::<Event>().fire(self.upcast());
+ }
+ frame.set_active(false);
+ }
+ },
_ => (), // XXXManishearth TBD
}
}
@@ -244,6 +291,15 @@ impl XRSessionMethods for XRSession {
/// https://immersive-web.github.io/webxr/#eventdef-xrsession-end
event_handler!(end, GetOnend, SetOnend);
+ /// https://immersive-web.github.io/webxr/#eventdef-xrsession-select
+ event_handler!(select, GetOnselect, SetOnselect);
+
+ /// https://immersive-web.github.io/webxr/#eventdef-xrsession-selectstart
+ event_handler!(selectstart, GetOnselectstart, SetOnselectstart);
+
+ /// https://immersive-web.github.io/webxr/#eventdef-xrsession-selectend
+ event_handler!(selectend, GetOnselectend, SetOnselectend);
+
/// https://immersive-web.github.io/webxr/#dom-xrsession-mode
fn Mode(&self) -> XRSessionMode {
XRSessionMode::Immersive_vr
diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs
index 6fa00d1cffe..ce68e786927 100644
--- a/components/script/dom/xrspace.rs
+++ b/components/script/dom/xrspace.rs
@@ -57,9 +57,9 @@ impl XRSpace {
/// The reference origin used is common between all
/// get_pose calls for spaces from the same device, so this can be used to compare
/// with other spaces
- pub fn get_pose(&self, base_pose: &Frame) -> ApiPose {
+ pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> {
if let Some(reference) = self.downcast::<XRReferenceSpace>() {
- reference.get_pose(base_pose)
+ Some(reference.get_pose(base_pose))
} else if let Some(source) = self.input_source.get() {
// XXXManishearth we should be able to request frame information
// for inputs when necessary instead of always loading it
@@ -72,7 +72,7 @@ impl XRSpace {
.iter()
.find(|i| i.id == id)
.expect("no input found");
- cast_transform(frame.target_ray_origin)
+ frame.target_ray_origin.map(cast_transform)
} else {
unreachable!()
}
diff --git a/tests/wpt/metadata/webxr/idlharness.https.window.js.ini b/tests/wpt/metadata/webxr/idlharness.https.window.js.ini
index 6d13e106119..1f341a6fe65 100644
--- a/tests/wpt/metadata/webxr/idlharness.https.window.js.ini
+++ b/tests/wpt/metadata/webxr/idlharness.https.window.js.ini
@@ -53,18 +53,9 @@
[XRWebGLLayer interface: operation getNativeFramebufferScaleFactor(XRSession)]
expected: FAIL
- [XRSession interface: attribute onselectend]
- expected: FAIL
-
- [XRInputSourceEvent interface: attribute frame]
- expected: FAIL
-
[XRRay interface: attribute matrix]
expected: FAIL
- [XRSession interface: attribute onselect]
- expected: FAIL
-
[XRReferenceSpaceEvent interface object length]
expected: FAIL
@@ -74,24 +65,12 @@
[XRInputSourcesChangeEvent interface: attribute added]
expected: FAIL
- [XRInputSourceEvent interface: attribute inputSource]
- expected: FAIL
-
[XRBoundedReferenceSpace interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
- [XRInputSourceEvent interface object name]
- expected: FAIL
-
[XRInputSourcesChangeEvent interface: attribute removed]
expected: FAIL
- [XRSession interface: attribute onselectstart]
- expected: FAIL
-
- [XRInputSourceEvent interface: existence and properties of interface prototype object]
- expected: FAIL
-
[XRReferenceSpaceEvent interface: existence and properties of interface object]
expected: FAIL
@@ -110,9 +89,6 @@
[XRInputSourceArray interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
- [XRInputSourceEvent interface: existence and properties of interface prototype object's @@unscopables property]
- expected: FAIL
-
[XRRay interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
@@ -164,12 +140,6 @@
[XRRay interface: existence and properties of interface prototype object]
expected: FAIL
- [XRInputSourceEvent interface: existence and properties of interface prototype object's "constructor" property]
- expected: FAIL
-
- [XRInputSourceEvent interface: existence and properties of interface object]
- expected: FAIL
-
[XRInputSourceArray interface object length]
expected: FAIL
@@ -206,9 +176,6 @@
[XRInputSourceArray interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
- [XRInputSourceEvent interface object length]
- expected: FAIL
-
[XRSession interface: attribute oninputsourceschange]
expected: FAIL