Pass context menu callbacks down to the openxr device

This commit is contained in:
Manish Goregaokar 2020-03-27 12:58:48 -07:00
parent 3aa15e3fa3
commit 1ba606b919
5 changed files with 57 additions and 9 deletions

4
Cargo.lock generated
View file

@ -6680,7 +6680,7 @@ dependencies = [
[[package]] [[package]]
name = "webxr" name = "webxr"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/servo/webxr#72b30f2b70ff7b40dc0ffdeefce1116b24041f3d" source = "git+https://github.com/servo/webxr#412f385483ad502320f94d98fe5beabf53d14de7"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"crossbeam-channel", "crossbeam-channel",
@ -6702,7 +6702,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#72b30f2b70ff7b40dc0ffdeefce1116b24041f3d" source = "git+https://github.com/servo/webxr#412f385483ad502320f94d98fe5beabf53d14de7"
dependencies = [ dependencies = [
"euclid", "euclid",
"ipc-channel", "ipc-channel",

View file

@ -5,7 +5,7 @@
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`. //! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
use canvas::{SurfaceProviders, WebGlExecutor}; use canvas::{SurfaceProviders, WebGlExecutor};
use embedder_traits::EventLoopWaker; use embedder_traits::{EmbedderProxy, EventLoopWaker};
use euclid::Scale; use euclid::Scale;
#[cfg(feature = "gl")] #[cfg(feature = "gl")]
use gleam::gl; use gleam::gl;
@ -190,6 +190,7 @@ pub trait EmbedderMethods {
_: &mut webxr::MainThreadRegistry, _: &mut webxr::MainThreadRegistry,
_: WebGlExecutor, _: WebGlExecutor,
_: SurfaceProviders, _: SurfaceProviders,
_: EmbedderProxy,
) { ) {
} }
} }

View file

@ -481,6 +481,7 @@ where
&mut webxr_main_thread, &mut webxr_main_thread,
webgl_executor, webgl_executor,
webxr_surface_providers, webxr_surface_providers,
embedder_proxy.clone(),
); );
} }
} }
@ -521,7 +522,7 @@ where
let (constellation_chan, sw_senders) = create_constellation( let (constellation_chan, sw_senders) = create_constellation(
opts.user_agent.clone(), opts.user_agent.clone(),
opts.config_dir.clone(), opts.config_dir.clone(),
embedder_proxy.clone(), embedder_proxy,
compositor_proxy.clone(), compositor_proxy.clone(),
time_profiler_chan.clone(), time_profiler_chan.clone(),
mem_profiler_chan.clone(), mem_profiler_chan.clone(),

View file

@ -14,7 +14,7 @@ use glutin::EventsLoopClosed;
use rust_webvr::GlWindowVRService; use rust_webvr::GlWindowVRService;
use servo::canvas::{SurfaceProviders, WebGlExecutor}; use servo::canvas::{SurfaceProviders, WebGlExecutor};
use servo::compositing::windowing::EmbedderMethods; use servo::compositing::windowing::EmbedderMethods;
use servo::embedder_traits::EventLoopWaker; use servo::embedder_traits::{EmbedderProxy, EventLoopWaker};
use servo::servo_config::{opts, pref}; use servo::servo_config::{opts, pref};
use servo::webvr::VRServiceManager; use servo::webvr::VRServiceManager;
use servo::webvr_traits::WebVRMainThreadHeartbeat; use servo::webvr_traits::WebVRMainThreadHeartbeat;
@ -94,7 +94,8 @@ impl EmbedderMethods for EmbedderCallbacks {
&mut self, &mut self,
xr: &mut webxr::MainThreadRegistry, xr: &mut webxr::MainThreadRegistry,
_executor: WebGlExecutor, _executor: WebGlExecutor,
_surface_provider_registration: SurfaceProviders _surface_provider_registration: SurfaceProviders,
_embedder_proxy: EmbedderProxy,
) { ) {
if pref!(dom.webxr.test) { if pref!(dom.webxr.test) {
xr.register_mock(webxr::headless::HeadlessMockDiscovery::new()); xr.register_mock(webxr::headless::HeadlessMockDiscovery::new());

View file

@ -20,7 +20,9 @@ use servo::compositing::windowing::{
WindowMethods, WindowMethods,
}; };
use servo::embedder_traits::resources::{self, Resource, ResourceReaderMethods}; use servo::embedder_traits::resources::{self, Resource, ResourceReaderMethods};
use servo::embedder_traits::{EmbedderMsg, MediaSessionEvent, PromptDefinition, PromptOrigin}; use servo::embedder_traits::{
EmbedderMsg, EmbedderProxy, MediaSessionEvent, PromptDefinition, PromptOrigin,
};
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use servo::keyboard_types::{Key, KeyState, KeyboardEvent}; use servo::keyboard_types::{Key, KeyState, KeyboardEvent};
use servo::msg::constellation_msg::TraversalDirection; use servo::msg::constellation_msg::TraversalDirection;
@ -764,7 +766,10 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
registry: &mut webxr::MainThreadRegistry, registry: &mut webxr::MainThreadRegistry,
executor: WebGlExecutor, executor: WebGlExecutor,
surface_providers: SurfaceProviders, surface_providers: SurfaceProviders,
embedder_proxy: EmbedderProxy,
) { ) {
use ipc_channel::ipc::{self, IpcReceiver};
use webxr::openxr;
debug!("EmbedderMethods::register_xr"); debug!("EmbedderMethods::register_xr");
assert!( assert!(
self.xr_discovery.is_none(), self.xr_discovery.is_none(),
@ -772,15 +777,53 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
); );
struct ProviderRegistration(SurfaceProviders); struct ProviderRegistration(SurfaceProviders);
impl webxr::openxr::SurfaceProviderRegistration for ProviderRegistration { impl openxr::SurfaceProviderRegistration for ProviderRegistration {
fn register(&self, id: webxr_api::SessionId, provider: servo::canvas::SurfaceProvider) { fn register(&self, id: webxr_api::SessionId, provider: servo::canvas::SurfaceProvider) {
self.0.lock().unwrap().insert(id, provider); self.0.lock().unwrap().insert(id, provider);
} }
fn clone(&self) -> Box<dyn webxr::openxr::SurfaceProviderRegistration> { fn clone(&self) -> Box<dyn openxr::SurfaceProviderRegistration> {
Box::new(ProviderRegistration(self.0.clone())) Box::new(ProviderRegistration(self.0.clone()))
} }
} }
#[derive(Clone)]
struct ContextMenuCallback(EmbedderProxy);
struct ContextMenuFuture(IpcReceiver<ContextMenuResult>);
impl openxr::ContextMenuProvider for ContextMenuCallback {
fn open_context_menu(&self) -> Box<dyn openxr::ContextMenuFuture> {
let (sender, receiver) = ipc::channel().unwrap();
self.0.send((
None,
EmbedderMsg::ShowContextMenu(
sender,
Some("Would you like to exit the XR session?".into()),
vec!["Exit".into()],
),
));
Box::new(ContextMenuFuture(receiver))
}
fn clone_object(&self) -> Box<dyn openxr::ContextMenuProvider> {
Box::new(self.clone())
}
}
impl openxr::ContextMenuFuture for ContextMenuFuture {
fn poll(&self) -> openxr::ContextMenuResult {
if let Ok(result) = self.0.try_recv() {
if let ContextMenuResult::Selected(0) = result {
openxr::ContextMenuResult::ExitSession
} else {
openxr::ContextMenuResult::Dismissed
}
} else {
openxr::ContextMenuResult::Pending
}
}
}
struct GlThread(WebGlExecutor); struct GlThread(WebGlExecutor);
impl webxr::openxr::GlThread for GlThread { impl webxr::openxr::GlThread for GlThread {
fn execute(&self, runnable: Box<dyn FnOnce() + Send>) { fn execute(&self, runnable: Box<dyn FnOnce() + Send>) {
@ -794,6 +837,7 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
let discovery = webxr::openxr::OpenXrDiscovery::new( let discovery = webxr::openxr::OpenXrDiscovery::new(
Box::new(GlThread(executor)), Box::new(GlThread(executor)),
Box::new(ProviderRegistration(surface_providers)), Box::new(ProviderRegistration(surface_providers)),
Box::new(ContextMenuCallback(embedder_proxy)),
); );
registry.register(discovery); registry.register(discovery);
} }
@ -804,6 +848,7 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
registry: &mut webxr::MainThreadRegistry, registry: &mut webxr::MainThreadRegistry,
_executor: WebGlExecutor, _executor: WebGlExecutor,
_surface_provider_registration: SurfaceProviders, _surface_provider_registration: SurfaceProviders,
_embedder_proxy: EmbedderProxy,
) { ) {
debug!("EmbedderMethods::register_xr"); debug!("EmbedderMethods::register_xr");
if let Some(discovery) = self.xr_discovery.take() { if let Some(discovery) = self.xr_discovery.take() {