From 1ba606b919360266054f7af3c2ac7e1b5750a3e5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 27 Mar 2020 12:58:48 -0700 Subject: [PATCH] Pass context menu callbacks down to the openxr device --- Cargo.lock | 4 +-- components/compositing/windowing.rs | 3 +- components/servo/lib.rs | 3 +- ports/glutin/embedder.rs | 5 +-- ports/libsimpleservo/api/src/lib.rs | 51 +++++++++++++++++++++++++++-- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e1d21bb7b2a..a9938cdf075e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6680,7 +6680,7 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#72b30f2b70ff7b40dc0ffdeefce1116b24041f3d" +source = "git+https://github.com/servo/webxr#412f385483ad502320f94d98fe5beabf53d14de7" dependencies = [ "bindgen", "crossbeam-channel", @@ -6702,7 +6702,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#72b30f2b70ff7b40dc0ffdeefce1116b24041f3d" +source = "git+https://github.com/servo/webxr#412f385483ad502320f94d98fe5beabf53d14de7" dependencies = [ "euclid", "ipc-channel", diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index a27473ca0f1f..1e7a7b30b8d8 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -5,7 +5,7 @@ //! Abstract windowing methods. The concrete implementations of these can be found in `platform/`. use canvas::{SurfaceProviders, WebGlExecutor}; -use embedder_traits::EventLoopWaker; +use embedder_traits::{EmbedderProxy, EventLoopWaker}; use euclid::Scale; #[cfg(feature = "gl")] use gleam::gl; @@ -190,6 +190,7 @@ pub trait EmbedderMethods { _: &mut webxr::MainThreadRegistry, _: WebGlExecutor, _: SurfaceProviders, + _: EmbedderProxy, ) { } } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index a71a1e708bac..69bba795d876 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -481,6 +481,7 @@ where &mut webxr_main_thread, webgl_executor, webxr_surface_providers, + embedder_proxy.clone(), ); } } @@ -521,7 +522,7 @@ where let (constellation_chan, sw_senders) = create_constellation( opts.user_agent.clone(), opts.config_dir.clone(), - embedder_proxy.clone(), + embedder_proxy, compositor_proxy.clone(), time_profiler_chan.clone(), mem_profiler_chan.clone(), diff --git a/ports/glutin/embedder.rs b/ports/glutin/embedder.rs index af65d4c34a1c..b5240a36e787 100644 --- a/ports/glutin/embedder.rs +++ b/ports/glutin/embedder.rs @@ -14,7 +14,7 @@ use glutin::EventsLoopClosed; use rust_webvr::GlWindowVRService; use servo::canvas::{SurfaceProviders, WebGlExecutor}; use servo::compositing::windowing::EmbedderMethods; -use servo::embedder_traits::EventLoopWaker; +use servo::embedder_traits::{EmbedderProxy, EventLoopWaker}; use servo::servo_config::{opts, pref}; use servo::webvr::VRServiceManager; use servo::webvr_traits::WebVRMainThreadHeartbeat; @@ -94,7 +94,8 @@ impl EmbedderMethods for EmbedderCallbacks { &mut self, xr: &mut webxr::MainThreadRegistry, _executor: WebGlExecutor, - _surface_provider_registration: SurfaceProviders + _surface_provider_registration: SurfaceProviders, + _embedder_proxy: EmbedderProxy, ) { if pref!(dom.webxr.test) { xr.register_mock(webxr::headless::HeadlessMockDiscovery::new()); diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 0c14dbf3851a..65531644734e 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -20,7 +20,9 @@ use servo::compositing::windowing::{ WindowMethods, }; 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::keyboard_types::{Key, KeyState, KeyboardEvent}; use servo::msg::constellation_msg::TraversalDirection; @@ -764,7 +766,10 @@ impl EmbedderMethods for ServoEmbedderCallbacks { registry: &mut webxr::MainThreadRegistry, executor: WebGlExecutor, surface_providers: SurfaceProviders, + embedder_proxy: EmbedderProxy, ) { + use ipc_channel::ipc::{self, IpcReceiver}; + use webxr::openxr; debug!("EmbedderMethods::register_xr"); assert!( self.xr_discovery.is_none(), @@ -772,15 +777,53 @@ impl EmbedderMethods for ServoEmbedderCallbacks { ); 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) { self.0.lock().unwrap().insert(id, provider); } - fn clone(&self) -> Box { + fn clone(&self) -> Box { Box::new(ProviderRegistration(self.0.clone())) } } + #[derive(Clone)] + struct ContextMenuCallback(EmbedderProxy); + + struct ContextMenuFuture(IpcReceiver); + + impl openxr::ContextMenuProvider for ContextMenuCallback { + fn open_context_menu(&self) -> Box { + 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 { + 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); impl webxr::openxr::GlThread for GlThread { fn execute(&self, runnable: Box) { @@ -794,6 +837,7 @@ impl EmbedderMethods for ServoEmbedderCallbacks { let discovery = webxr::openxr::OpenXrDiscovery::new( Box::new(GlThread(executor)), Box::new(ProviderRegistration(surface_providers)), + Box::new(ContextMenuCallback(embedder_proxy)), ); registry.register(discovery); } @@ -804,6 +848,7 @@ impl EmbedderMethods for ServoEmbedderCallbacks { registry: &mut webxr::MainThreadRegistry, _executor: WebGlExecutor, _surface_provider_registration: SurfaceProviders, + _embedder_proxy: EmbedderProxy, ) { debug!("EmbedderMethods::register_xr"); if let Some(discovery) = self.xr_discovery.take() {