Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always trigger an input sources change event on session creation #25773

Merged
merged 1 commit into from Feb 16, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -284,7 +284,6 @@ impl XR {
return;
},
};

let session = XRSession::new(&self.global(), session, mode, frame_receiver);
if mode == XRSessionMode::Inline {
self.active_inline_sessions
@@ -294,6 +293,9 @@ impl XR {
self.set_active_immersive_session(&session);
}
promise.resolve_native(&session);
// https://github.com/immersive-web/webxr/issues/961
// This must be called _after_ the promise is resolved
session.setup_initial_inputs();
}

pub fn get_displays(&self) -> Result<Vec<DomRoot<VRDisplay>>, ()> {
@@ -38,30 +38,22 @@ impl XRInputSourceArray {
)
}

pub fn set_initial_inputs(&self, session: &XRSession) {
pub fn add_input_sources(&self, session: &XRSession, inputs: &[InputSource]) {
let mut input_sources = self.input_sources.borrow_mut();
let global = self.global();
session.with_session(|sess| {
for info in sess.initial_inputs() {
// XXXManishearth we should be able to listen for updates
// to the input sources
let input = XRInputSource::new(&global, &session, info.clone());
input_sources.push(Dom::from_ref(&input));
}
});
}

pub fn add_input_source(&self, session: &XRSession, info: InputSource) {
let mut input_sources = self.input_sources.borrow_mut();
let global = self.global();
debug_assert!(
input_sources.iter().find(|i| i.id() == info.id).is_none(),
"Should never add a duplicate input id!"
);
let input = XRInputSource::new(&global, &session, info);
input_sources.push(Dom::from_ref(&input));

let added = [input];
let mut added = vec![];
for info in inputs {
// This is quadratic, but won't be a problem for the only case
// where we add multiple input sources (the initial input sources case)
debug_assert!(
input_sources.iter().find(|i| i.id() == info.id).is_none(),
"Should never add a duplicate input id!"
);
let input = XRInputSource::new(&global, &session, info.clone());
input_sources.push(Dom::from_ref(&input));
added.push(input);
}

let event = XRInputSourcesChangeEvent::new(
&global,
@@ -136,7 +136,6 @@ impl XRSession {
global,
XRSessionBinding::Wrap,
);
input_sources.set_initial_inputs(&ret);
ret.attach_event_handler();
ret.setup_raf_loop(frame_receiver);
ret
@@ -208,6 +207,36 @@ impl XRSession {
self.session.borrow_mut().set_event_dest(sender);
}

// Must be called after the promise for session creation is resolved
// https://github.com/immersive-web/webxr/issues/961
//
// This enables content that assumes all input sources are accompanied
// by an inputsourceschange event to work properly. Without
pub fn setup_initial_inputs(&self) {
let initial_inputs = self.session.borrow().initial_inputs().to_owned();

if initial_inputs.is_empty() {
// do not fire an empty event
return;
}

let global = self.global();
let window = global.as_window();
let (task_source, canceller) = window
.task_manager()
.dom_manipulation_task_source_with_canceller();
let this = Trusted::new(self);
// Queue a task so that it runs after resolve()'s microtasks complete
// so that content has a chance to attach a listener for inputsourceschange
let _ = task_source.queue_with_canceller(
task!(session_initial_inputs: move || {
let this = this.root();
this.input_sources.add_input_sources(&this, &initial_inputs);
}),
&canceller,
);
}

fn event_callback(&self, event: XREvent) {
match event {
XREvent::SessionEnd => {
@@ -290,7 +319,7 @@ impl XRSession {
event.upcast::<Event>().fire(self.upcast());
},
XREvent::AddInput(info) => {
self.input_sources.add_input_source(self, info);
self.input_sources.add_input_sources(self, &[info]);
},
XREvent::RemoveInput(id) => {
self.input_sources.remove_input_source(self, id);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.