mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
libservo: Expose a ServoBuilder
(#36549)
Expose a `ServoBuilder` for easily creating Servo instances using default values. This change enables removing `EmbedderTraits`. Testing: This is covered by `Servo` unit tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
7a8e75266f
commit
d8a7abda69
17 changed files with 252 additions and 271 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -8595,6 +8595,7 @@ name = "webxr"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
"embedder_traits",
|
||||||
"euclid",
|
"euclid",
|
||||||
"glow",
|
"glow",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
|
||||||
|
|
||||||
use embedder_traits::EventLoopWaker;
|
|
||||||
use net::protocols::ProtocolRegistry;
|
|
||||||
|
|
||||||
/// Various debug and profiling flags that WebRender supports.
|
/// Various debug and profiling flags that WebRender supports.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum WebRenderDebugOption {
|
pub enum WebRenderDebugOption {
|
||||||
|
@ -14,23 +9,3 @@ pub enum WebRenderDebugOption {
|
||||||
TextureCacheDebug,
|
TextureCacheDebug,
|
||||||
RenderTargetDebug,
|
RenderTargetDebug,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EmbedderMethods {
|
|
||||||
/// Returns a thread-safe object to wake up the window's event loop.
|
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker>;
|
|
||||||
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
/// Register services with a WebXR Registry.
|
|
||||||
fn register_webxr(
|
|
||||||
&mut self,
|
|
||||||
_: &mut webxr::MainThreadRegistry,
|
|
||||||
_: embedder_traits::EmbedderProxy,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the protocol handlers implemented by that embedder.
|
|
||||||
/// They will be merged with the default internal ones.
|
|
||||||
fn get_protocol_handlers(&self) -> ProtocolRegistry {
|
|
||||||
ProtocolRegistry::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,10 +5,10 @@ use std::cell::RefCell;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use compositing::windowing::EmbedderMethods;
|
|
||||||
use euclid::{Scale, Size2D};
|
use euclid::{Scale, Size2D};
|
||||||
use servo::{
|
use servo::{
|
||||||
RenderingContext, Servo, TouchEventType, WebView, WebViewBuilder, WindowRenderingContext,
|
RenderingContext, Servo, ServoBuilder, TouchEventType, WebView, WebViewBuilder,
|
||||||
|
WindowRenderingContext,
|
||||||
};
|
};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -95,15 +95,9 @@ impl ApplicationHandler<WakerEvent> for App {
|
||||||
|
|
||||||
let _ = rendering_context.make_current();
|
let _ = rendering_context.make_current();
|
||||||
|
|
||||||
let servo = Servo::new(
|
let servo = ServoBuilder::new(rendering_context.clone())
|
||||||
Default::default(),
|
.event_loop_waker(Box::new(waker.clone()))
|
||||||
Default::default(),
|
.build();
|
||||||
rendering_context.clone(),
|
|
||||||
Box::new(EmbedderDelegate {
|
|
||||||
waker: waker.clone(),
|
|
||||||
}),
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
servo.setup_logging();
|
servo.setup_logging();
|
||||||
|
|
||||||
let app_state = Rc::new(AppState {
|
let app_state = Rc::new(AppState {
|
||||||
|
@ -204,19 +198,6 @@ impl ApplicationHandler<WakerEvent> for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmbedderDelegate {
|
|
||||||
waker: Waker,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EmbedderMethods for EmbedderDelegate {
|
|
||||||
// FIXME: rust-analyzer “Implement missing members” autocompletes this as
|
|
||||||
// webxr_api::MainThreadWaker, which is not available when building without
|
|
||||||
// libservo/webxr, and even if it was, it would fail to compile with E0053.
|
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn embedder_traits::EventLoopWaker> {
|
|
||||||
Box::new(self.waker.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Waker(winit::event_loop::EventLoopProxy<WakerEvent>);
|
struct Waker(winit::event_loop::EventLoopProxy<WakerEvent>);
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -42,7 +42,6 @@ use canvas::WebGLComm;
|
||||||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||||
use canvas_traits::webgl::{GlType, WebGLThreads};
|
use canvas_traits::webgl::{GlType, WebGLThreads};
|
||||||
use clipboard_delegate::StringRequest;
|
use clipboard_delegate::StringRequest;
|
||||||
use compositing::windowing::EmbedderMethods;
|
|
||||||
use compositing::{IOCompositor, InitialCompositorState};
|
use compositing::{IOCompositor, InitialCompositorState};
|
||||||
pub use compositing_traits::rendering_context::{
|
pub use compositing_traits::rendering_context::{
|
||||||
OffscreenRenderingContext, RenderingContext, SoftwareRenderingContext, WindowRenderingContext,
|
OffscreenRenderingContext, RenderingContext, SoftwareRenderingContext, WindowRenderingContext,
|
||||||
|
@ -247,26 +246,18 @@ impl webrender_api::RenderNotifier for RenderNotifier {
|
||||||
impl Servo {
|
impl Servo {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(
|
tracing::instrument(skip(builder), fields(servo_profiling = true), level = "trace",)
|
||||||
skip(preferences, rendering_context, embedder),
|
|
||||||
fields(servo_profiling = true),
|
|
||||||
level = "trace",
|
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
pub fn new(
|
fn new(builder: ServoBuilder) -> Self {
|
||||||
opts: Opts,
|
|
||||||
preferences: Preferences,
|
|
||||||
rendering_context: Rc<dyn RenderingContext>,
|
|
||||||
mut embedder: Box<dyn EmbedderMethods>,
|
|
||||||
user_content_manager: UserContentManager,
|
|
||||||
) -> Self {
|
|
||||||
// Global configuration options, parsed from the command line.
|
// Global configuration options, parsed from the command line.
|
||||||
opts::set_options(opts);
|
let opts = builder.opts.map(|opts| *opts);
|
||||||
|
opts::set_options(opts.unwrap_or_default());
|
||||||
let opts = opts::get();
|
let opts = opts::get();
|
||||||
|
|
||||||
// Set the preferences globally.
|
// Set the preferences globally.
|
||||||
// TODO: It would be better to make these private to a particular Servo instance.
|
// TODO: It would be better to make these private to a particular Servo instance.
|
||||||
servo_config::prefs::set(preferences);
|
let preferences = builder.preferences.map(|opts| *opts);
|
||||||
|
servo_config::prefs::set(preferences.unwrap_or_default());
|
||||||
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
@ -282,6 +273,7 @@ impl Servo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get GL bindings
|
// Get GL bindings
|
||||||
|
let rendering_context = builder.rendering_context;
|
||||||
let webrender_gl = rendering_context.gleam_gl_api();
|
let webrender_gl = rendering_context.gleam_gl_api();
|
||||||
|
|
||||||
// Make sure the gl context is made current.
|
// Make sure the gl context is made current.
|
||||||
|
@ -297,7 +289,7 @@ impl Servo {
|
||||||
// the client window and the compositor. This channel is unique because
|
// the client window and the compositor. This channel is unique because
|
||||||
// messages to client may need to pump a platform-specific event loop
|
// messages to client may need to pump a platform-specific event loop
|
||||||
// to deliver the message.
|
// to deliver the message.
|
||||||
let event_loop_waker = embedder.create_event_loop_waker();
|
let event_loop_waker = builder.event_loop_waker;
|
||||||
let (compositor_proxy, compositor_receiver) =
|
let (compositor_proxy, compositor_receiver) =
|
||||||
create_compositor_channel(event_loop_waker.clone());
|
create_compositor_channel(event_loop_waker.clone());
|
||||||
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
|
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
|
||||||
|
@ -424,7 +416,7 @@ impl Servo {
|
||||||
.expect("Failed to create WebXR device registry");
|
.expect("Failed to create WebXR device registry");
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
if pref!(dom_webxr_enabled) {
|
if pref!(dom_webxr_enabled) {
|
||||||
embedder.register_webxr(&mut webxr_main_thread, embedder_proxy.clone());
|
builder.webxr_registry.register(&mut webxr_main_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
|
@ -447,7 +439,7 @@ impl Servo {
|
||||||
// Create the constellation, which maintains the engine pipelines, including script and
|
// Create the constellation, which maintains the engine pipelines, including script and
|
||||||
// layout, as well as the navigation context.
|
// layout, as well as the navigation context.
|
||||||
let mut protocols = ProtocolRegistry::with_internal_protocols();
|
let mut protocols = ProtocolRegistry::with_internal_protocols();
|
||||||
protocols.merge(embedder.get_protocol_handlers());
|
protocols.merge(builder.protocol_registry);
|
||||||
|
|
||||||
let constellation_chan = create_constellation(
|
let constellation_chan = create_constellation(
|
||||||
opts.config_dir.clone(),
|
opts.config_dir.clone(),
|
||||||
|
@ -465,7 +457,7 @@ impl Servo {
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
wgpu_image_map,
|
wgpu_image_map,
|
||||||
protocols,
|
protocols,
|
||||||
user_content_manager,
|
builder.user_content_manager,
|
||||||
);
|
);
|
||||||
|
|
||||||
if cfg!(feature = "webdriver") {
|
if cfg!(feature = "webdriver") {
|
||||||
|
@ -1204,3 +1196,77 @@ fn create_sandbox() {
|
||||||
fn create_sandbox() {
|
fn create_sandbox() {
|
||||||
panic!("Sandboxing is not supported on Windows, iOS, ARM targets and android.");
|
panic!("Sandboxing is not supported on Windows, iOS, ARM targets and android.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DefaultEventLoopWaker;
|
||||||
|
|
||||||
|
impl EventLoopWaker for DefaultEventLoopWaker {
|
||||||
|
fn clone_box(&self) -> Box<dyn EventLoopWaker> {
|
||||||
|
Box::new(DefaultEventLoopWaker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
struct DefaultWebXrRegistry;
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
impl webxr::WebXrRegistry for DefaultWebXrRegistry {}
|
||||||
|
|
||||||
|
pub struct ServoBuilder {
|
||||||
|
rendering_context: Rc<dyn RenderingContext>,
|
||||||
|
opts: Option<Box<Opts>>,
|
||||||
|
preferences: Option<Box<Preferences>>,
|
||||||
|
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
|
user_content_manager: UserContentManager,
|
||||||
|
protocol_registry: ProtocolRegistry,
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
webxr_registry: Box<dyn webxr::WebXrRegistry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServoBuilder {
|
||||||
|
pub fn new(rendering_context: Rc<dyn RenderingContext>) -> Self {
|
||||||
|
Self {
|
||||||
|
rendering_context,
|
||||||
|
opts: None,
|
||||||
|
preferences: None,
|
||||||
|
event_loop_waker: Box::new(DefaultEventLoopWaker),
|
||||||
|
user_content_manager: UserContentManager::default(),
|
||||||
|
protocol_registry: ProtocolRegistry::default(),
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
webxr_registry: Box::new(DefaultWebXrRegistry),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> Servo {
|
||||||
|
Servo::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opts(mut self, opts: Opts) -> Self {
|
||||||
|
self.opts = Some(Box::new(opts));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn preferences(mut self, preferences: Preferences) -> Self {
|
||||||
|
self.preferences = Some(Box::new(preferences));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event_loop_waker(mut self, event_loop_waker: Box<dyn EventLoopWaker>) -> Self {
|
||||||
|
self.event_loop_waker = event_loop_waker;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_content_manager(mut self, user_content_manager: UserContentManager) -> Self {
|
||||||
|
self.user_content_manager = user_content_manager;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn protocol_registry(mut self, protocol_registry: ProtocolRegistry) -> Self {
|
||||||
|
self.protocol_registry = protocol_registry;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
pub fn webxr_registry(mut self, webxr_registry: Box<dyn webxr::WebXrRegistry>) -> Self {
|
||||||
|
self.webxr_registry = webxr_registry;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@ use std::sync::{Arc, OnceLock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use compositing::windowing::EmbedderMethods;
|
|
||||||
use compositing_traits::rendering_context::{RenderingContext, SoftwareRenderingContext};
|
use compositing_traits::rendering_context::{RenderingContext, SoftwareRenderingContext};
|
||||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
use crossbeam_channel::{Receiver, Sender, unbounded};
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use embedder_traits::EventLoopWaker;
|
use embedder_traits::EventLoopWaker;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use servo::Servo;
|
use servo::{Servo, ServoBuilder};
|
||||||
|
|
||||||
pub struct ServoTest {
|
pub struct ServoTest {
|
||||||
servo: Servo,
|
servo: Servo,
|
||||||
|
@ -41,14 +40,6 @@ impl ServoTest {
|
||||||
);
|
);
|
||||||
assert!(rendering_context.make_current().is_ok());
|
assert!(rendering_context.make_current().is_ok());
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct EmbedderMethodsImpl(Arc<AtomicBool>);
|
|
||||||
impl EmbedderMethods for EmbedderMethodsImpl {
|
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn embedder_traits::EventLoopWaker> {
|
|
||||||
Box::new(EventLoopWakerImpl(self.0.clone()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct EventLoopWakerImpl(Arc<AtomicBool>);
|
struct EventLoopWakerImpl(Arc<AtomicBool>);
|
||||||
impl EventLoopWaker for EventLoopWakerImpl {
|
impl EventLoopWaker for EventLoopWakerImpl {
|
||||||
|
@ -62,13 +53,9 @@ impl ServoTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_event_triggered = Arc::new(AtomicBool::new(false));
|
let user_event_triggered = Arc::new(AtomicBool::new(false));
|
||||||
let servo = Servo::new(
|
let servo = ServoBuilder::new(rendering_context.clone())
|
||||||
Default::default(),
|
.event_loop_waker(Box::new(EventLoopWakerImpl(user_event_triggered)))
|
||||||
Default::default(),
|
.build();
|
||||||
rendering_context.clone(),
|
|
||||||
Box::new(EmbedderMethodsImpl(user_event_triggered)),
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
Self { servo }
|
Self { servo }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ pub enum Cursor {
|
||||||
|
|
||||||
pub trait EventLoopWaker: 'static + Send {
|
pub trait EventLoopWaker: 'static + Send {
|
||||||
fn clone_box(&self) -> Box<dyn EventLoopWaker>;
|
fn clone_box(&self) -> Box<dyn EventLoopWaker>;
|
||||||
fn wake(&self);
|
fn wake(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Box<dyn EventLoopWaker> {
|
impl Clone for Box<dyn EventLoopWaker> {
|
||||||
|
|
|
@ -26,6 +26,7 @@ openxr-api = ["angle", "openxr", "winapi", "wio", "surfman/sm-angle-default"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossbeam-channel = { workspace = true }
|
crossbeam-channel = { workspace = true }
|
||||||
|
embedder_traits = { workspace = true }
|
||||||
euclid = { workspace = true }
|
euclid = { workspace = true }
|
||||||
glow = { workspace = true }
|
glow = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|
|
@ -19,3 +19,8 @@ pub type MainThreadRegistry = webxr_api::MainThreadRegistry<surfman_layer_manage
|
||||||
pub type Discovery = Box<dyn webxr_api::DiscoveryAPI<SurfmanGL>>;
|
pub type Discovery = Box<dyn webxr_api::DiscoveryAPI<SurfmanGL>>;
|
||||||
|
|
||||||
pub(crate) mod gl_utils;
|
pub(crate) mod gl_utils;
|
||||||
|
|
||||||
|
pub trait WebXrRegistry {
|
||||||
|
/// Register services with a WebXR Registry.
|
||||||
|
fn register(&self, _: &mut MainThreadRegistry) {}
|
||||||
|
}
|
||||||
|
|
|
@ -11,16 +11,14 @@ use std::rc::Rc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
|
||||||
|
use ::servo::ServoBuilder;
|
||||||
use log::{info, trace, warn};
|
use log::{info, trace, warn};
|
||||||
|
use net::protocols::ProtocolRegistry;
|
||||||
|
use servo::EventLoopWaker;
|
||||||
use servo::config::opts::Opts;
|
use servo::config::opts::Opts;
|
||||||
use servo::config::prefs::Preferences;
|
use servo::config::prefs::Preferences;
|
||||||
use servo::servo_config::pref;
|
|
||||||
use servo::servo_url::ServoUrl;
|
use servo::servo_url::ServoUrl;
|
||||||
use servo::user_content_manager::{UserContentManager, UserScript};
|
use servo::user_content_manager::{UserContentManager, UserScript};
|
||||||
use servo::webxr::glwindow::GlWindowDiscovery;
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use servo::webxr::openxr::{AppInfo, OpenXrDiscovery};
|
|
||||||
use servo::{EventLoopWaker, Servo};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::event::WindowEvent;
|
use winit::event::WindowEvent;
|
||||||
|
@ -32,8 +30,9 @@ use super::events_loop::{EventsLoop, WakerEvent};
|
||||||
use super::minibrowser::{Minibrowser, MinibrowserEvent};
|
use super::minibrowser::{Minibrowser, MinibrowserEvent};
|
||||||
use super::{headed_window, headless_window};
|
use super::{headed_window, headless_window};
|
||||||
use crate::desktop::app_state::RunningAppState;
|
use crate::desktop::app_state::RunningAppState;
|
||||||
use crate::desktop::embedder::{EmbedderCallbacks, XrDiscovery};
|
use crate::desktop::protocols;
|
||||||
use crate::desktop::tracing::trace_winit_event;
|
use crate::desktop::tracing::trace_winit_event;
|
||||||
|
use crate::desktop::webxr::XrDiscoveryWebXrRegistry;
|
||||||
use crate::desktop::window_trait::WindowPortsMethods;
|
use crate::desktop::window_trait::WindowPortsMethods;
|
||||||
use crate::parser::{get_default_url, location_bar_input_to_url};
|
use crate::parser::{get_default_url, location_bar_input_to_url};
|
||||||
use crate::prefs::ServoShellPreferences;
|
use crate::prefs::ServoShellPreferences;
|
||||||
|
@ -115,26 +114,6 @@ impl App {
|
||||||
self.suspended.set(false);
|
self.suspended.set(false);
|
||||||
let (_, window) = self.windows.iter().next().unwrap();
|
let (_, window) = self.windows.iter().next().unwrap();
|
||||||
|
|
||||||
let xr_discovery = if pref!(dom_webxr_openxr_enabled) && !headless {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
let openxr = {
|
|
||||||
let app_info = AppInfo::new("Servoshell", 0, "Servo", 0);
|
|
||||||
Some(XrDiscovery::OpenXr(OpenXrDiscovery::new(None, app_info)))
|
|
||||||
};
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
let openxr = None;
|
|
||||||
|
|
||||||
openxr
|
|
||||||
} else if pref!(dom_webxr_glwindow_enabled) && !headless {
|
|
||||||
let window = window.new_glwindow(event_loop.unwrap());
|
|
||||||
Some(XrDiscovery::GlWindow(GlWindowDiscovery::new(window)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements embedder methods, used by libservo and constellation.
|
|
||||||
let embedder = Box::new(EmbedderCallbacks::new(self.waker.clone(), xr_discovery));
|
|
||||||
|
|
||||||
let mut user_content_manager = UserContentManager::new();
|
let mut user_content_manager = UserContentManager::new();
|
||||||
for script in load_userscripts(self.servoshell_preferences.userscripts_directory.as_deref())
|
for script in load_userscripts(self.servoshell_preferences.userscripts_directory.as_deref())
|
||||||
.expect("Loading userscripts failed")
|
.expect("Loading userscripts failed")
|
||||||
|
@ -142,13 +121,32 @@ impl App {
|
||||||
user_content_manager.add_script(script);
|
user_content_manager.add_script(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
let servo = Servo::new(
|
let mut protocol_registry = ProtocolRegistry::default();
|
||||||
self.opts.clone(),
|
protocol_registry.register(
|
||||||
self.preferences.clone(),
|
"urlinfo",
|
||||||
window.rendering_context(),
|
protocols::urlinfo::UrlInfoProtocolHander::default(),
|
||||||
embedder,
|
|
||||||
user_content_manager,
|
|
||||||
);
|
);
|
||||||
|
protocol_registry.register("servo", protocols::servo::ServoProtocolHandler::default());
|
||||||
|
protocol_registry.register(
|
||||||
|
"resource",
|
||||||
|
protocols::resource::ResourceProtocolHandler::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let servo_builder = ServoBuilder::new(window.rendering_context())
|
||||||
|
.opts(self.opts.clone())
|
||||||
|
.preferences(self.preferences.clone())
|
||||||
|
.user_content_manager(user_content_manager)
|
||||||
|
.protocol_registry(protocol_registry)
|
||||||
|
.event_loop_waker(self.waker.clone());
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
let servo_builder = servo_builder.webxr_registry(XrDiscoveryWebXrRegistry::new_boxed(
|
||||||
|
window.clone(),
|
||||||
|
event_loop,
|
||||||
|
&self.preferences,
|
||||||
|
));
|
||||||
|
|
||||||
|
let servo = servo_builder.build();
|
||||||
servo.setup_logging();
|
servo.setup_logging();
|
||||||
|
|
||||||
let running_state = Rc::new(RunningAppState::new(
|
let running_state = Rc::new(RunningAppState::new(
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Implements the global methods required by Servo (not window/gl/compositor related).
|
|
||||||
|
|
||||||
use net::protocols::ProtocolRegistry;
|
|
||||||
use servo::compositing::windowing::EmbedderMethods;
|
|
||||||
use servo::servo_config::pref;
|
|
||||||
use servo::webxr::glwindow::GlWindowDiscovery;
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use servo::webxr::openxr::OpenXrDiscovery;
|
|
||||||
use servo::{EmbedderProxy, EventLoopWaker};
|
|
||||||
|
|
||||||
use crate::desktop::protocols::{resource, servo as servo_handler, urlinfo};
|
|
||||||
|
|
||||||
pub enum XrDiscovery {
|
|
||||||
GlWindow(GlWindowDiscovery),
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
OpenXr(OpenXrDiscovery),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EmbedderCallbacks {
|
|
||||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
|
||||||
xr_discovery: Option<XrDiscovery>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EmbedderCallbacks {
|
|
||||||
pub fn new(
|
|
||||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
|
||||||
xr_discovery: Option<XrDiscovery>,
|
|
||||||
) -> EmbedderCallbacks {
|
|
||||||
EmbedderCallbacks {
|
|
||||||
event_loop_waker,
|
|
||||||
xr_discovery,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EmbedderMethods for EmbedderCallbacks {
|
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker> {
|
|
||||||
self.event_loop_waker.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
fn register_webxr(
|
|
||||||
&mut self,
|
|
||||||
xr: &mut servo::webxr::MainThreadRegistry,
|
|
||||||
_embedder_proxy: EmbedderProxy,
|
|
||||||
) {
|
|
||||||
use servo::webxr::headless::HeadlessMockDiscovery;
|
|
||||||
|
|
||||||
if pref!(dom_webxr_test) {
|
|
||||||
xr.register_mock(HeadlessMockDiscovery::default());
|
|
||||||
} else if let Some(xr_discovery) = self.xr_discovery.take() {
|
|
||||||
match xr_discovery {
|
|
||||||
XrDiscovery::GlWindow(discovery) => xr.register(discovery),
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
XrDiscovery::OpenXr(discovery) => xr.register(discovery),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_protocol_handlers(&self) -> ProtocolRegistry {
|
|
||||||
let mut registry = ProtocolRegistry::default();
|
|
||||||
registry.register("urlinfo", urlinfo::UrlInfoProtocolHander::default());
|
|
||||||
registry.register("servo", servo_handler::ServoProtocolHandler::default());
|
|
||||||
registry.register("resource", resource::ResourceProtocolHandler::default());
|
|
||||||
registry
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ mod app_state;
|
||||||
pub(crate) mod cli;
|
pub(crate) mod cli;
|
||||||
mod dialog;
|
mod dialog;
|
||||||
mod egui_glue;
|
mod egui_glue;
|
||||||
mod embedder;
|
|
||||||
pub(crate) mod events_loop;
|
pub(crate) mod events_loop;
|
||||||
mod gamepad;
|
mod gamepad;
|
||||||
pub mod geometry;
|
pub mod geometry;
|
||||||
|
@ -20,4 +19,5 @@ mod keyutils;
|
||||||
mod minibrowser;
|
mod minibrowser;
|
||||||
mod protocols;
|
mod protocols;
|
||||||
mod tracing;
|
mod tracing;
|
||||||
|
mod webxr;
|
||||||
mod window_trait;
|
mod window_trait;
|
||||||
|
|
78
ports/servoshell/desktop/webxr.rs
Normal file
78
ports/servoshell/desktop/webxr.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use servo::config::pref;
|
||||||
|
use servo::config::prefs::Preferences;
|
||||||
|
use servo::webxr::WebXrRegistry;
|
||||||
|
use servo::webxr::glwindow::GlWindowDiscovery;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use servo::webxr::openxr::{AppInfo, OpenXrDiscovery};
|
||||||
|
use winit::event_loop::ActiveEventLoop;
|
||||||
|
|
||||||
|
use super::window_trait::WindowPortsMethods;
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
enum XrDiscovery {
|
||||||
|
GlWindow(GlWindowDiscovery),
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
OpenXr(OpenXrDiscovery),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
pub(crate) struct XrDiscoveryWebXrRegistry {
|
||||||
|
xr_discovery: RefCell<Option<XrDiscovery>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XrDiscoveryWebXrRegistry {
|
||||||
|
pub(crate) fn new_boxed(
|
||||||
|
window: Rc<dyn WindowPortsMethods>,
|
||||||
|
event_loop: Option<&ActiveEventLoop>,
|
||||||
|
preferences: &Preferences,
|
||||||
|
) -> Box<Self> {
|
||||||
|
let Some(event_loop) = event_loop else {
|
||||||
|
return Box::new(Self {
|
||||||
|
xr_discovery: RefCell::new(None),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let xr_discovery = if preferences.dom_webxr_openxr_enabled {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
let app_info = AppInfo::new("Servoshell", 0, "Servo", 0);
|
||||||
|
Some(XrDiscovery::OpenXr(OpenXrDiscovery::new(None, app_info)))
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
None
|
||||||
|
} else if preferences.dom_webxr_glwindow_enabled {
|
||||||
|
let window = window.new_glwindow(event_loop);
|
||||||
|
Some(XrDiscovery::GlWindow(GlWindowDiscovery::new(window)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Box::new(Self {
|
||||||
|
xr_discovery: RefCell::new(xr_discovery),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
impl WebXrRegistry for XrDiscoveryWebXrRegistry {
|
||||||
|
fn register(&self, xr: &mut servo::webxr::MainThreadRegistry) {
|
||||||
|
use servo::webxr::headless::HeadlessMockDiscovery;
|
||||||
|
|
||||||
|
if pref!(dom_webxr_test) {
|
||||||
|
xr.register_mock(HeadlessMockDiscovery::default());
|
||||||
|
} else if let Some(xr_discovery) = self.xr_discovery.take() {
|
||||||
|
match xr_discovery {
|
||||||
|
XrDiscovery::GlWindow(discovery) => xr.register(discovery),
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
XrDiscovery::OpenXr(discovery) => xr.register(discovery),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,11 +20,10 @@ use raw_window_handle::{
|
||||||
AndroidDisplayHandle, AndroidNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
|
AndroidDisplayHandle, AndroidNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
};
|
};
|
||||||
use servo::{
|
use servo::{
|
||||||
AlertResponse, LoadStatus, MediaSessionActionType, PermissionRequest, SimpleDialog, WebView,
|
AlertResponse, EventLoopWaker, LoadStatus, MediaSessionActionType, PermissionRequest,
|
||||||
};
|
SimpleDialog, WebView,
|
||||||
use simpleservo::{
|
|
||||||
APP, DeviceIntRect, EventLoopWaker, InitOptions, InputMethodType, MediaSessionPlaybackState,
|
|
||||||
};
|
};
|
||||||
|
use simpleservo::{APP, DeviceIntRect, InitOptions, InputMethodType, MediaSessionPlaybackState};
|
||||||
|
|
||||||
use super::app_state::{Coordinates, RunningAppState};
|
use super::app_state::{Coordinates, RunningAppState};
|
||||||
use super::host_trait::HostTrait;
|
use super::host_trait::HostTrait;
|
||||||
|
|
|
@ -8,18 +8,14 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use raw_window_handle::{DisplayHandle, RawDisplayHandle, RawWindowHandle, WindowHandle};
|
use raw_window_handle::{DisplayHandle, RawDisplayHandle, RawWindowHandle, WindowHandle};
|
||||||
/// The EventLoopWaker::wake function will be called from any thread.
|
|
||||||
/// It will be called to notify embedder that some events are available,
|
|
||||||
/// and that perform_updates need to be called
|
|
||||||
pub use servo::EventLoopWaker;
|
|
||||||
pub use servo::webrender_api::units::DeviceIntRect;
|
pub use servo::webrender_api::units::DeviceIntRect;
|
||||||
use servo::{self, Servo, resources};
|
use servo::{self, EventLoopWaker, ServoBuilder, resources};
|
||||||
pub use servo::{InputMethodType, MediaSessionPlaybackState, WindowRenderingContext};
|
pub use servo::{InputMethodType, MediaSessionPlaybackState, WindowRenderingContext};
|
||||||
|
|
||||||
use crate::egl::android::resources::ResourceReaderInstance;
|
use crate::egl::android::resources::ResourceReaderInstance;
|
||||||
use crate::egl::app_state::{
|
#[cfg(feature = "webxr")]
|
||||||
Coordinates, RunningAppState, ServoEmbedderCallbacks, ServoWindowCallbacks,
|
use crate::egl::app_state::XrDiscoveryWebXrRegistry;
|
||||||
};
|
use crate::egl::app_state::{Coordinates, RunningAppState, ServoWindowCallbacks};
|
||||||
use crate::egl::host_trait::HostTrait;
|
use crate::egl::host_trait::HostTrait;
|
||||||
use crate::prefs::{ArgumentParsingResult, parse_command_line_arguments};
|
use crate::prefs::{ArgumentParsingResult, parse_command_line_arguments};
|
||||||
|
|
||||||
|
@ -85,26 +81,22 @@ pub fn init(
|
||||||
RefCell::new(init_opts.coordinates),
|
RefCell::new(init_opts.coordinates),
|
||||||
));
|
));
|
||||||
|
|
||||||
let embedder_callbacks = Box::new(ServoEmbedderCallbacks::new(
|
let servo_builder = ServoBuilder::new(rendering_context.clone())
|
||||||
waker,
|
.opts(opts)
|
||||||
#[cfg(feature = "webxr")]
|
.preferences(preferences)
|
||||||
init_opts.xr_discovery,
|
.event_loop_waker(waker);
|
||||||
));
|
|
||||||
|
|
||||||
let servo = Servo::new(
|
#[cfg(feature = "webxr")]
|
||||||
opts,
|
let servo_builder = servo_builder.webxr_registry(Box::new(XrDiscoveryWebXrRegistry::new(
|
||||||
preferences,
|
init_opts.xr_discovery,
|
||||||
rendering_context.clone(),
|
)));
|
||||||
embedder_callbacks,
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
APP.with(|app| {
|
APP.with(|app| {
|
||||||
let app_state = RunningAppState::new(
|
let app_state = RunningAppState::new(
|
||||||
init_opts.url,
|
init_opts.url,
|
||||||
init_opts.density,
|
init_opts.density,
|
||||||
rendering_context,
|
rendering_context,
|
||||||
servo,
|
servo_builder.build(),
|
||||||
window_callbacks,
|
window_callbacks,
|
||||||
servoshell_preferences,
|
servoshell_preferences,
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,18 +11,16 @@ use keyboard_types::{CompositionEvent, CompositionState};
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use raw_window_handle::{RawWindowHandle, WindowHandle};
|
use raw_window_handle::{RawWindowHandle, WindowHandle};
|
||||||
use servo::base::id::WebViewId;
|
use servo::base::id::WebViewId;
|
||||||
use servo::compositing::windowing::EmbedderMethods;
|
|
||||||
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
|
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
|
||||||
use servo::servo_geometry::DeviceIndependentPixel;
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::webrender_api::ScrollLocation;
|
use servo::webrender_api::ScrollLocation;
|
||||||
use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePixel};
|
use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePixel};
|
||||||
use servo::{
|
use servo::{
|
||||||
AllowOrDenyRequest, ContextMenuResult, EmbedderProxy, EventLoopWaker, ImeEvent, InputEvent,
|
AllowOrDenyRequest, ContextMenuResult, ImeEvent, InputEvent, InputMethodType, Key, KeyState,
|
||||||
InputMethodType, Key, KeyState, KeyboardEvent, LoadStatus, MediaSessionActionType,
|
KeyboardEvent, LoadStatus, MediaSessionActionType, MediaSessionEvent, MouseButton,
|
||||||
MediaSessionEvent, MouseButton, MouseButtonAction, MouseButtonEvent, MouseMoveEvent,
|
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, NavigationRequest, PermissionRequest,
|
||||||
NavigationRequest, PermissionRequest, RenderingContext, ScreenGeometry, Servo, ServoDelegate,
|
RenderingContext, ScreenGeometry, Servo, ServoDelegate, ServoError, SimpleDialog, TouchEvent,
|
||||||
ServoError, SimpleDialog, TouchEvent, TouchEventType, TouchId, WebView, WebViewBuilder,
|
TouchEventType, TouchId, WebView, WebViewBuilder, WebViewDelegate, WindowRenderingContext,
|
||||||
WebViewDelegate, WindowRenderingContext,
|
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -682,38 +680,24 @@ impl RunningAppState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct ServoEmbedderCallbacks {
|
#[cfg(feature = "webxr")]
|
||||||
waker: Box<dyn EventLoopWaker>,
|
pub(crate) struct XrDiscoveryWebXrRegistry {
|
||||||
#[cfg(feature = "webxr")]
|
xr_discovery: RefCell<Option<servo::webxr::Discovery>>,
|
||||||
xr_discovery: Option<servo::webxr::Discovery>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServoEmbedderCallbacks {
|
#[cfg(feature = "webxr")]
|
||||||
pub(super) fn new(
|
impl XrDiscoveryWebXrRegistry {
|
||||||
waker: Box<dyn EventLoopWaker>,
|
pub(crate) fn new(xr_discovery: Option<servo::webxr::Discovery>) -> Self {
|
||||||
#[cfg(feature = "webxr")] xr_discovery: Option<servo::webxr::Discovery>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
waker,
|
xr_discovery: RefCell::new(xr_discovery),
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
xr_discovery,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmbedderMethods for ServoEmbedderCallbacks {
|
#[cfg(feature = "webxr")]
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker> {
|
impl servo::webxr::WebXrRegistry for XrDiscoveryWebXrRegistry {
|
||||||
debug!("EmbedderMethods::create_event_loop_waker");
|
fn register(&self, registry: &mut servo::webxr::MainThreadRegistry) {
|
||||||
self.waker.clone()
|
debug!("XrDiscoveryWebXrRegistry::register");
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
fn register_webxr(
|
|
||||||
&mut self,
|
|
||||||
registry: &mut servo::webxr::MainThreadRegistry,
|
|
||||||
_embedder_proxy: EmbedderProxy,
|
|
||||||
) {
|
|
||||||
debug!("EmbedderMethods::register_xr");
|
|
||||||
if let Some(discovery) = self.xr_discovery.take() {
|
if let Some(discovery) = self.xr_discovery.take() {
|
||||||
registry.register(discovery);
|
registry.register(discovery);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,9 @@ use ohos_ime::{AttachOptions, Ime, ImeProxy, RawTextEditorProxy};
|
||||||
use ohos_ime_sys::types::InputMethod_EnterKeyType;
|
use ohos_ime_sys::types::InputMethod_EnterKeyType;
|
||||||
use servo::style::Zero;
|
use servo::style::Zero;
|
||||||
use servo::{
|
use servo::{
|
||||||
AlertResponse, InputMethodType, LoadStatus, MediaSessionPlaybackState, PermissionRequest,
|
AlertResponse, EventLoopWaker, InputMethodType, LoadStatus, MediaSessionPlaybackState,
|
||||||
SimpleDialog, WebView,
|
PermissionRequest, SimpleDialog, WebView,
|
||||||
};
|
};
|
||||||
use simpleservo::EventLoopWaker;
|
|
||||||
use xcomponent_sys::{
|
use xcomponent_sys::{
|
||||||
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
|
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
|
||||||
OH_NativeXComponent_GetKeyEventAction, OH_NativeXComponent_GetKeyEventCode,
|
OH_NativeXComponent_GetKeyEventAction, OH_NativeXComponent_GetKeyEventCode,
|
||||||
|
|
|
@ -14,16 +14,10 @@ use raw_window_handle::{
|
||||||
DisplayHandle, OhosDisplayHandle, OhosNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
|
DisplayHandle, OhosDisplayHandle, OhosNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
WindowHandle,
|
WindowHandle,
|
||||||
};
|
};
|
||||||
/// The EventLoopWaker::wake function will be called from any thread.
|
use servo::{self, EventLoopWaker, ServoBuilder, WindowRenderingContext, resources};
|
||||||
/// It will be called to notify embedder that some events are available,
|
|
||||||
/// and that perform_updates need to be called
|
|
||||||
pub use servo::EventLoopWaker;
|
|
||||||
use servo::{self, Servo, WindowRenderingContext, resources};
|
|
||||||
use xcomponent_sys::OH_NativeXComponent;
|
use xcomponent_sys::OH_NativeXComponent;
|
||||||
|
|
||||||
use crate::egl::app_state::{
|
use crate::egl::app_state::{Coordinates, RunningAppState, ServoWindowCallbacks};
|
||||||
Coordinates, RunningAppState, ServoEmbedderCallbacks, ServoWindowCallbacks,
|
|
||||||
};
|
|
||||||
use crate::egl::host_trait::HostTrait;
|
use crate::egl::host_trait::HostTrait;
|
||||||
use crate::egl::ohos::InitOpts;
|
use crate::egl::ohos::InitOpts;
|
||||||
use crate::egl::ohos::resources::ResourceReaderInstance;
|
use crate::egl::ohos::resources::ResourceReaderInstance;
|
||||||
|
@ -128,19 +122,11 @@ pub fn init(
|
||||||
RefCell::new(coordinates),
|
RefCell::new(coordinates),
|
||||||
));
|
));
|
||||||
|
|
||||||
let embedder_callbacks = Box::new(ServoEmbedderCallbacks::new(
|
let servo = ServoBuilder::new(rendering_context.clone())
|
||||||
waker,
|
.opts(opts)
|
||||||
#[cfg(feature = "webxr")]
|
.preferences(preferences)
|
||||||
None,
|
.event_loop_waker(waker)
|
||||||
));
|
.build();
|
||||||
|
|
||||||
let servo = Servo::new(
|
|
||||||
opts,
|
|
||||||
preferences,
|
|
||||||
rendering_context.clone(),
|
|
||||||
embedder_callbacks,
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let app_state = RunningAppState::new(
|
let app_state = RunningAppState::new(
|
||||||
Some(options.url),
|
Some(options.url),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue