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]]
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",

View file

@ -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,
) {
}
}

View file

@ -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(),

View file

@ -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());

View file

@ -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<dyn webxr::openxr::SurfaceProviderRegistration> {
fn clone(&self) -> Box<dyn openxr::SurfaceProviderRegistration> {
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);
impl webxr::openxr::GlThread for GlThread {
fn execute(&self, runnable: Box<dyn FnOnce() + Send>) {
@ -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() {