mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Always trigger an input sources change event on session creation
This commit is contained in:
parent
5f55cd5d71
commit
09a23b0cb1
3 changed files with 47 additions and 24 deletions
|
@ -284,7 +284,6 @@ impl XR {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let session = XRSession::new(&self.global(), session, mode, frame_receiver);
|
let session = XRSession::new(&self.global(), session, mode, frame_receiver);
|
||||||
if mode == XRSessionMode::Inline {
|
if mode == XRSessionMode::Inline {
|
||||||
self.active_inline_sessions
|
self.active_inline_sessions
|
||||||
|
@ -294,6 +293,9 @@ impl XR {
|
||||||
self.set_active_immersive_session(&session);
|
self.set_active_immersive_session(&session);
|
||||||
}
|
}
|
||||||
promise.resolve_native(&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>>, ()> {
|
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 mut input_sources = self.input_sources.borrow_mut();
|
||||||
let global = self.global();
|
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 added = vec![];
|
||||||
let mut input_sources = self.input_sources.borrow_mut();
|
for info in inputs {
|
||||||
let global = self.global();
|
// 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!(
|
debug_assert!(
|
||||||
input_sources.iter().find(|i| i.id() == info.id).is_none(),
|
input_sources.iter().find(|i| i.id() == info.id).is_none(),
|
||||||
"Should never add a duplicate input id!"
|
"Should never add a duplicate input id!"
|
||||||
);
|
);
|
||||||
let input = XRInputSource::new(&global, &session, info);
|
let input = XRInputSource::new(&global, &session, info.clone());
|
||||||
input_sources.push(Dom::from_ref(&input));
|
input_sources.push(Dom::from_ref(&input));
|
||||||
|
added.push(input);
|
||||||
let added = [input];
|
}
|
||||||
|
|
||||||
let event = XRInputSourcesChangeEvent::new(
|
let event = XRInputSourcesChangeEvent::new(
|
||||||
&global,
|
&global,
|
||||||
|
|
|
@ -136,7 +136,6 @@ impl XRSession {
|
||||||
global,
|
global,
|
||||||
XRSessionBinding::Wrap,
|
XRSessionBinding::Wrap,
|
||||||
);
|
);
|
||||||
input_sources.set_initial_inputs(&ret);
|
|
||||||
ret.attach_event_handler();
|
ret.attach_event_handler();
|
||||||
ret.setup_raf_loop(frame_receiver);
|
ret.setup_raf_loop(frame_receiver);
|
||||||
ret
|
ret
|
||||||
|
@ -208,6 +207,36 @@ impl XRSession {
|
||||||
self.session.borrow_mut().set_event_dest(sender);
|
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) {
|
fn event_callback(&self, event: XREvent) {
|
||||||
match event {
|
match event {
|
||||||
XREvent::SessionEnd => {
|
XREvent::SessionEnd => {
|
||||||
|
@ -290,7 +319,7 @@ impl XRSession {
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
},
|
},
|
||||||
XREvent::AddInput(info) => {
|
XREvent::AddInput(info) => {
|
||||||
self.input_sources.add_input_source(self, info);
|
self.input_sources.add_input_sources(self, &[info]);
|
||||||
},
|
},
|
||||||
XREvent::RemoveInput(id) => {
|
XREvent::RemoveInput(id) => {
|
||||||
self.input_sources.remove_input_source(self, id);
|
self.input_sources.remove_input_source(self, id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue