Skip to content

Commit

Permalink
feat: add verso protocol (#202)
Browse files Browse the repository at this point in the history
* Register verso protocol

* Make webivew generic
  • Loading branch information
wusyong authored Oct 15, 2024
1 parent 9cf43b3 commit 4e7edd0
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 50 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ fonts = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
layout_thread_2020 = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
media = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
net = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
net_traits = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
profile = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
profile_traits = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
script = { git = "https://github.com/servo/servo.git", rev = "fc0835b" }
Expand All @@ -104,6 +105,7 @@ cargo-packager-resource-resolver = { version = "0.1.1", features = [
"auto-detect-format",
], optional = true }
url = "2.5.2"
headers = "0.3"
versoview_messages = { path = "./versoview_messages" }

[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
Expand Down
16 changes: 8 additions & 8 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use webrender_api::{
};
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
use webrender_traits::{
CompositorHitTestResult, CrossProcessCompositorMessage, ImageUpdate, UntrustedNodeAddress
CompositorHitTestResult, CrossProcessCompositorMessage, ImageUpdate, UntrustedNodeAddress,
};
use winit::window::WindowId;

Expand Down Expand Up @@ -572,7 +572,7 @@ impl IOCompositor {

CompositorMsg::CrossProcess(cross_proces_message) => {
self.handle_cross_process_message(cross_proces_message);
},
}
}

true
Expand Down Expand Up @@ -707,11 +707,11 @@ impl IOCompositor {
match update {
ImageUpdate::AddImage(key, desc, data) => {
txn.add_image(key, desc, data.into(), None)
},
}
ImageUpdate::DeleteImage(key) => txn.delete_image(key),
ImageUpdate::UpdateImage(key, desc, data) => {
txn.update_image(key, desc, data.into(), &DirtyRect::All)
},
}
}
}
self.webrender_api
Expand All @@ -727,7 +727,7 @@ impl IOCompositor {
transaction.add_native_font(font_key, native_handle);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
},
}

CrossProcessCompositorMessage::AddFontInstance(
font_instance_key,
Expand Down Expand Up @@ -777,13 +777,13 @@ impl IOCompositor {
if let Err(e) = req.send(self.viewport.into()) {
warn!("Sending response to get client window failed ({:?}).", e);
}
},
}

CrossProcessCompositorMessage::GetScreenSize(req) => {
if let Err(e) = req.send(self.viewport) {
warn!("Sending response to get screen size failed ({:?}).", e);
}
},
}

CrossProcessCompositorMessage::GetAvailableScreenSize(req) => {
if let Err(e) = req.send(self.viewport) {
Expand Down Expand Up @@ -833,7 +833,7 @@ impl IOCompositor {
.map(|_| self.webrender_api.generate_font_instance_key())
.collect();
let _ = result_sender.send((font_keys, font_instance_keys));
},
}
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect(
req,
)) => {
Expand Down
45 changes: 45 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use std::{fs, path::PathBuf};

use embedder_traits::resources::{self, Resource, ResourceReaderMethods};
use headers::{ContentType, HeaderMapExt};
use net::protocols::{ProtocolHandler, ProtocolRegistry};
use net_traits::{
request::Request,
response::{Response, ResponseBody},
ResourceFetchTiming,
};
use servo_config::opts::{default_opts, set_options, Opts};

/// Configuration of Verso instance.
Expand All @@ -20,6 +27,14 @@ impl Config {
Self { opts, resource_dir }
}

/// Register URL scheme protocols
pub fn create_protocols(&self) -> ProtocolRegistry {
let handler = ResourceReader(self.resource_dir.clone());
let mut protocols = ProtocolRegistry::with_internal_protocols();
protocols.register("verso", handler);
protocols
}

/// Init options and preferences.
pub fn init(self) {
// Set the resource files and preferences of Servo.
Expand All @@ -46,3 +61,33 @@ impl ResourceReaderMethods for ResourceReader {
vec![]
}
}

impl ProtocolHandler for ResourceReader {
fn load(
&self,
request: &mut Request,
_done_chan: &mut net::fetch::methods::DoneChannel,
_context: &net::fetch::methods::FetchContext,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Response> + Send>> {
let path = self.0.join(request.current_url().domain().unwrap());

let response = if let Ok(file) = fs::read(path) {
let mut response = Response::new(
request.current_url(),
ResourceFetchTiming::new(request.timing_type()),
);

// Set Content-Type header.
// TODO: We assume it's HTML for now. This should be updated once we have IPC interface.
response.headers.typed_insert(ContentType::html());

*response.body.lock().unwrap() = ResponseBody::Done(file);

response
} else {
Response::network_internal_error("Opening file failed")
};

Box::pin(std::future::ready(response))
}
}
28 changes: 10 additions & 18 deletions src/verso.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use std::{
borrow::Cow,
collections::HashMap,
path::PathBuf,
sync::{atomic::Ordering, Arc},
};

use arboard::Clipboard;
use base::id::WebViewId;
use base::id::{PipelineNamespace, PipelineNamespaceId, WebViewId};
use bluetooth::BluetoothThreadFactory;
use bluetooth_traits::BluetoothRequest;
use canvas::canvas_paint_thread::CanvasPaintThread;
use compositing_traits::{
CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg,
};
use compositing_traits::{CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg};
use constellation::{Constellation, FromCompositorLogger, InitialConstellationState};
use crossbeam_channel::{unbounded, Sender};
use devtools;
Expand All @@ -24,7 +21,7 @@ use ipc_channel::router::ROUTER;
use layout_thread_2020;
use log::{Log, Metadata, Record};
use media::{GlApi, GlContext, NativeDisplay, WindowGLContext};
use net::{protocols::ProtocolRegistry, resource_thread};
use net::resource_thread;
use profile;
use script::{self, JSEngineSetup};
use script_traits::WindowSizeData;
Expand Down Expand Up @@ -62,7 +59,6 @@ pub struct Verso {
_js_engine_setup: Option<JSEngineSetup>,
/// FIXME: It's None on wayland in Flatpak. Find a way to support this.
clipboard: Option<Clipboard>,
resource_dir: PathBuf,
}

impl Verso {
Expand All @@ -84,8 +80,10 @@ impl Verso {
/// - Image Cache: Enabled
pub fn new(evl: &ActiveEventLoop, proxy: EventLoopProxy<()>, config: Config) -> Self {
// Initialize configurations and Verso window
let resource_dir = config.resource_dir.clone();
let protocols = config.create_protocols();
config.init();
// Reserving a namespace to create TopLevelBrowsingContextId.
PipelineNamespace::install(PipelineNamespaceId(0));
let (window, rendering_context) = Window::new(evl);
let event_loop_waker = Box::new(Waker(proxy));
let opts = opts::get();
Expand Down Expand Up @@ -262,9 +260,6 @@ impl Verso {
let bluetooth_thread: IpcSender<BluetoothRequest> =
BluetoothThreadFactory::new(embedder_sender.clone());

// Register URL scheme protocols
let protocols = ProtocolRegistry::with_internal_protocols();

// Create resource thread pool
let user_agent: Cow<'static, str> = default_user_agent_string().into();
let (public_resource_threads, private_resource_threads) =
Expand All @@ -282,7 +277,8 @@ impl Verso {

// Create font cache thread
let system_font_service = Arc::new(
SystemFontService::spawn(compositor_sender.cross_process_compositor_api.clone()).to_proxy(),
SystemFontService::spawn(compositor_sender.cross_process_compositor_api.clone())
.to_proxy(),
);

// Create canvas thread
Expand Down Expand Up @@ -369,8 +365,7 @@ impl Verso {
// Send the constellation message to start Panel UI
// TODO: Should become a window method
let panel_id = window.panel.as_ref().unwrap().webview_id;
let path = resource_dir.join("panel.html");
let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap();
let url = ServoUrl::parse("verso://panel.html").unwrap();
send_to_constellation(
&constellation_sender,
ConstellationMsg::NewWebView(url, panel_id),
Expand All @@ -387,7 +382,6 @@ impl Verso {
embedder_receiver,
_js_engine_setup: js_engine_setup,
clipboard: Clipboard::new().ok(),
resource_dir,
};

verso.setup_logging();
Expand Down Expand Up @@ -445,10 +439,8 @@ impl Verso {
let mut window =
Window::new_with_compositor(evl, compositor);
let panel_id = WebViewId::new();
let path = self.resource_dir.join("panel.html");
let url =
ServoUrl::from_file_path(path.to_str().unwrap())
.unwrap();
ServoUrl::parse("verso://panel.html").unwrap();
send_to_constellation(
&self.constellation_sender,
ConstellationMsg::NewWebView(url, panel_id),
Expand Down
23 changes: 1 addition & 22 deletions src/webview.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use arboard::Clipboard;
use base::id::{BrowsingContextId, PipelineNamespace, PipelineNamespaceId, WebViewId};
use base::id::{BrowsingContextId, WebViewId};
use compositing_traits::ConstellationMsg;
use crossbeam_channel::Sender;
use embedder_traits::{CompositorEventVariant, EmbedderMsg, PromptDefinition};
Expand Down Expand Up @@ -29,27 +29,6 @@ impl WebView {
Self { webview_id, rect }
}

/// Create a panel view from Winit window. A panel is a special web view that focus on controlling states around window.
/// It could be treated as the control panel or navigation bar of the window depending on usages.
///
/// At the moment, following Web API is supported:
/// - Close window: `window.close()`
/// - Navigate to previous page: `window.prompt('PREV')`
/// - Navigate to next page: `window.prompt('FORWARD')`
/// - Refresh the page: `window.prompt('REFRESH')`
/// - Minimize the window: `window.prompt('MINIMIZE')`
/// - Maximize the window: `window.prompt('MAXIMIZE')`
/// - Navigate to a specific URL: `window.prompt('NAVIGATE_TO:${url}')`
pub fn new_panel(rect: DeviceIntRect) -> Self {
// Reserving a namespace to create TopLevelBrowsingContextId.
PipelineNamespace::install(PipelineNamespaceId(0));
let id = WebViewId::new();
Self {
webview_id: id,
rect,
}
}

/// Set the webview size corresponding to the window size.
pub fn set_size(&mut self, mut rect: DeviceIntRect) {
rect.min.y = rect.max.y.min(100);
Expand Down
17 changes: 15 additions & 2 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ pub struct Window {
pub(crate) window: WinitWindow,
/// GL surface of the window
pub(crate) surface: Surface<WindowSurface>,
/// The main control panel of this window.
/// The main panel of this window. A panel is a special web view that focus on controlling states around window.
/// It could be treated as the control panel or navigation bar of the window depending on usages.
///
/// At the moment, following Web API is supported:
/// - Close window: `window.close()`
/// - Navigate to previous page: `window.prompt('PREV')`
/// - Navigate to next page: `window.prompt('FORWARD')`
/// - Refresh the page: `window.prompt('REFRESH')`
/// - Minimize the window: `window.prompt('MINIMIZE')`
/// - Maximize the window: `window.prompt('MAXIMIZE')`
/// - Navigate to a specific URL: `window.prompt('NAVIGATE_TO:${url}')`
pub(crate) panel: Option<WebView>,
/// The WebView of this window.
pub(crate) webview: Option<WebView>,
Expand Down Expand Up @@ -89,7 +99,10 @@ impl Window {
Self {
window,
surface,
panel: Some(WebView::new_panel(DeviceIntRect::from_size(size))),
panel: Some(WebView::new(
WebViewId::new(),
DeviceIntRect::from_size(size),
)),
webview: None,
mouse_position: Cell::new(PhysicalPosition::default()),
modifiers_state: Cell::new(ModifiersState::default()),
Expand Down
1 change: 1 addition & 0 deletions versoview/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions versoview_messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 4e7edd0

Please sign in to comment.