Skip to content

Commit

Permalink
feat: Allow setting extension path for Windows and Linux (#1403)
Browse files Browse the repository at this point in the history
  • Loading branch information
SpikeHD authored Oct 28, 2024
1 parent c1b26b9 commit 1d63fa3
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changes/extension-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": "patch"
---

Add `WebViewBuilder::with_extension_path` API to Windows and Linux.
46 changes: 36 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes {
use_https: bool,
scroll_bar_style: ScrollBarStyle,
browser_extensions_enabled: bool,
extension_path: Option<PathBuf>,
}

#[cfg(windows)]
Expand All @@ -1198,6 +1199,7 @@ impl Default for PlatformSpecificWebViewAttributes {
use_https: false, // To match macOS & Linux behavior in the context of mixed content.
scroll_bar_style: ScrollBarStyle::default(),
browser_extensions_enabled: false,
extension_path: None,
}
}
}
Expand Down Expand Up @@ -1257,6 +1259,11 @@ pub trait WebViewBuilderExtWindows {
/// Requires WebView2 Runtime version 1.0.2210.55 or higher, does nothing on older versions,
/// see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/archive?tabs=dotnetcsharp#10221055
fn with_browser_extensions_enabled(self, enabled: bool) -> Self;

/// Set the path from which to load extensions from. Extensions stored in this path should be unpacked.
///
/// Does nothing if browser extensions are disabled. See [`with_browser_extensions_enabled`](Self::with_browser_extensions_enabled)
fn with_extension_path(self, path: impl Into<PathBuf>) -> Self;
}

#[cfg(windows)]
Expand Down Expand Up @@ -1302,6 +1309,13 @@ impl WebViewBuilderExtWindows for WebViewBuilder<'_> {
Ok(b)
})
}

fn with_extension_path(self, path: impl Into<PathBuf>) -> Self {
self.and_then(|mut b| {
b.platform_specific.extension_path = Some(path.into());
Ok(b)
})
}
}

#[cfg(target_os = "android")]
Expand Down Expand Up @@ -1381,6 +1395,18 @@ impl WebViewBuilderExtAndroid for WebViewBuilder<'_> {
}
}

#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
#[derive(Default)]
pub(crate) struct PlatformSpecificWebViewAttributes {
extension_path: Option<PathBuf>,
}

#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
Expand All @@ -1402,6 +1428,9 @@ pub trait WebViewBuilderExtUnix<'a> {
fn build_gtk<W>(self, widget: &'a W) -> Result<WebView>
where
W: gtk::prelude::IsA<gtk::Container>;

/// Set the path from which to load extensions from.
fn with_extension_path(self, path: impl Into<PathBuf>) -> Self;
}

#[cfg(any(
Expand All @@ -1421,6 +1450,13 @@ impl<'a> WebViewBuilderExtUnix<'a> for WebViewBuilder<'a> {
InnerWebView::new_gtk(widget, parts.attrs, parts.platform_specific)
.map(|webview| WebView { webview })
}

fn with_extension_path(self, path: impl Into<PathBuf>) -> Self {
self.and_then(|mut b| {
b.platform_specific.extension_path = Some(path.into());
Ok(b)
})
}
}

/// The fundamental type to present a [`WebView`].
Expand Down Expand Up @@ -1879,16 +1915,6 @@ pub enum PageLoadEvent {
Finished,
}

#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
#[derive(Default)]
pub(crate) struct PlatformSpecificWebViewAttributes;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
7 changes: 6 additions & 1 deletion src/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl InnerWebView {
pub fn new_gtk<W>(
container: &W,
mut attributes: WebViewAttributes,
_pl_attrs: super::PlatformSpecificWebViewAttributes,
pl_attrs: super::PlatformSpecificWebViewAttributes,
) -> Result<Self>
where
W: IsA<gtk::Container>,
Expand Down Expand Up @@ -242,6 +242,11 @@ impl InnerWebView {
}
}

// Extension loading
if let Some(extension_path) = pl_attrs.extension_path {
web_context.os.set_web_extensions_directory(&extension_path);
}

let webview = Self::create_webview(web_context, &attributes);

// Transparent
Expand Down
6 changes: 6 additions & 0 deletions src/webkitgtk/web_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ impl WebContextImpl {
self.automation = flag;
self.context.set_automation_allowed(flag);
}

pub fn set_web_extensions_directory(&mut self, path: &Path) {
self
.context
.set_web_extensions_directory(&path.to_string_lossy());
}
}

/// [`WebContext`](super::WebContext) items that only matter on unix.
Expand Down
30 changes: 29 additions & 1 deletion src/webview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ mod drag_drop;
mod util;

use std::{
borrow::Cow, cell::RefCell, collections::HashSet, fmt::Write, path::PathBuf, rc::Rc, sync::mpsc,
borrow::Cow, cell::RefCell, collections::HashSet, fmt::Write, fs, path::PathBuf, rc::Rc,
sync::mpsc,
};

use dpi::{PhysicalPosition, PhysicalSize};
Expand Down Expand Up @@ -499,6 +500,15 @@ impl InnerWebView {
}
}

// Extension loading
if pl_attrs.browser_extensions_enabled {
if let Some(extension_path) = pl_attrs.extension_path {
unsafe {
Self::load_extensions(&webview, &extension_path)?;
}
}
}

Ok(webview)
}

Expand Down Expand Up @@ -1174,6 +1184,24 @@ impl InnerWebView {
unsafe { webview.Source(&mut pwstr)? };
Ok(take_pwstr(pwstr))
}

#[inline]
unsafe fn load_extensions(webview: &ICoreWebView2, extension_path: &PathBuf) -> Result<()> {
let profile = webview
.cast::<ICoreWebView2_13>()?
.Profile()?
.cast::<ICoreWebView2Profile7>()?;

// Iterate over all folders in the extension path
for entry in fs::read_dir(extension_path)? {
let path = entry?.path();
let path_hs = HSTRING::from(path.as_path());

profile.AddBrowserExtension(&path_hs, None)?;
}

Ok(())
}
}

/// Public APIs
Expand Down

0 comments on commit 1d63fa3

Please sign in to comment.