From f721113f8d2b6bae00b9be280d80c6a7d16861b6 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 8 Jan 2020 17:54:26 +0530 Subject: [PATCH] Handle AddInput/RemoveInput events --- components/atoms/static_atoms.txt | 1 + .../script/dom/webidls/XRSession.webidl | 2 +- components/script/dom/xrinputsourcearray.rs | 55 ++++++++++++++++++- .../script/dom/xrinputsourceschangeevent.rs | 4 +- components/script/dom/xrsession.rs | 14 ++++- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index bf50e2e9acd..65ca743ed90 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -44,6 +44,7 @@ iceconnectionstatechange icegatheringstatechange image input +inputsourceschange invalid keydown keypress diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index e726a500cb7..a00e0c4cd3d 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -40,7 +40,7 @@ interface XRSession : EventTarget { attribute EventHandler onend; attribute EventHandler onselect; attribute EventHandler onsqueeze; - // attribute EventHandler oninputsourceschange; + attribute EventHandler oninputsourceschange; attribute EventHandler onselectstart; attribute EventHandler onselectend; attribute EventHandler onsqueezestart; diff --git a/components/script/dom/xrinputsourcearray.rs b/components/script/dom/xrinputsourcearray.rs index 48f84991db0..45e0f2851e4 100644 --- a/components/script/dom/xrinputsourcearray.rs +++ b/components/script/dom/xrinputsourcearray.rs @@ -5,13 +5,16 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::XRInputSourceArrayBinding; 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::root::{Dom, DomRoot}; +use crate::dom::event::Event; use crate::dom::globalscope::GlobalScope; use crate::dom::xrinputsource::XRInputSource; +use crate::dom::xrinputsourceschangeevent::XRInputSourcesChangeEvent; use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; -use webxr_api::InputId; +use webxr_api::{InputId, InputSource}; #[dom_struct] 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::().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::().fire(session.upcast()); + } + pub fn find(&self, id: InputId) -> Option> { self.input_sources .borrow() diff --git a/components/script/dom/xrinputsourceschangeevent.rs b/components/script/dom/xrinputsourceschangeevent.rs index f89bdeba9d1..02e81e4bf53 100644 --- a/components/script/dom/xrinputsourceschangeevent.rs +++ b/components/script/dom/xrinputsourceschangeevent.rs @@ -66,10 +66,10 @@ impl XRInputSourcesChangeEvent { let cx = global.get_cx(); unsafe { rooted!(in(*cx) let mut added_val = UndefinedValue()); - rooted!(in(*cx) let mut removed_val = UndefinedValue()); added.to_jsval(*cx, added_val.handle_mut()); - removed.to_jsval(*cx, removed_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()); } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index a4ced8689a5..4979835fc42 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -289,7 +289,12 @@ impl XRSession { ); event.upcast::().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 ); + /// https://immersive-web.github.io/webxr/#eventdef-xrsession-inputsourceschange + event_handler!( + inputsourceschange, + GetOninputsourceschange, + SetOninputsourceschange + ); + // https://immersive-web.github.io/webxr/#dom-xrsession-renderstate fn RenderState(&self) -> DomRoot { self.active_render_state.get()