Skip to content

Commit

Permalink
feat: webview2 composition support
Browse files Browse the repository at this point in the history
  • Loading branch information
yydcnjjw committed Jun 16, 2024
1 parent f56ae29 commit 87bb057
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
13 changes: 11 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes {
browser_accelerator_keys: bool,
theme: Option<Theme>,
use_https: bool,
composition: bool,
}

#[cfg(windows)]
Expand All @@ -1083,6 +1084,7 @@ impl Default for PlatformSpecificWebViewAttributes {
browser_accelerator_keys: true, // This is WebView2's default behavior
theme: None,
use_https: false, // To match macOS & Linux behavior in the context of mixed content.
composition: false,
}
}
}
Expand Down Expand Up @@ -1119,6 +1121,8 @@ pub trait WebViewBuilderExtWindows {
///
/// The default value is `false`.
fn with_https_scheme(self, enabled: bool) -> Self;

fn with_composition(self, enabled: bool) -> Self;
}

#[cfg(windows)]
Expand All @@ -1142,6 +1146,11 @@ impl WebViewBuilderExtWindows for WebViewBuilder<'_> {
self.platform_specific.use_https = enabled;
self
}

fn with_composition(mut self, enabled: bool) -> Self {
self.platform_specific.composition = enabled;
self
}
}

#[cfg(target_os = "android")]
Expand All @@ -1151,7 +1160,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes {
Option<Box<dyn Fn(prelude::Context) -> std::result::Result<(), jni::errors::Error> + Send>>,
with_asset_loader: bool,
asset_loader_domain: Option<String>,
https_scheme: bool,
use_https: bool,
}

#[cfg(target_os = "android")]
Expand Down Expand Up @@ -1210,7 +1219,7 @@ impl WebViewBuilderExtAndroid for WebViewBuilder<'_> {
}

fn with_https_scheme(mut self, enabled: bool) -> Self {
self.platform_specific.https_scheme = enabled;
self.platform_specific.use_https = enabled;
self
}
}
Expand Down
56 changes: 42 additions & 14 deletions src/webview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ 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,
path::PathBuf,
rc::Rc,
sync::mpsc,
};

use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
Expand Down Expand Up @@ -118,7 +124,8 @@ impl InnerWebView {
let bounds = attributes.bounds;

let env = Self::create_environment(&web_context, pl_attrs.clone(), &attributes)?;
let controller = Self::create_controller(hwnd, &env, attributes.incognito)?;
let controller =
Self::create_controller(hwnd, &env, attributes.incognito, pl_attrs.composition)?;
let webview = Self::init_webview(
parent,
hwnd,
Expand Down Expand Up @@ -326,25 +333,46 @@ impl InnerWebView {
hwnd: HWND,
env: &ICoreWebView2Environment,
incognito: bool,
composition: bool,
) -> Result<ICoreWebView2Controller> {
let (tx, rx) = mpsc::channel();
let env = env.clone().cast::<ICoreWebView2Environment10>()?;
let controller_opts = unsafe { env.CreateCoreWebView2ControllerOptions()? };

unsafe { controller_opts.SetIsInPrivateModeEnabled(incognito)? }

CreateCoreWebView2ControllerCompletedHandler::wait_for_async_operation(
Box::new(move |handler| unsafe {
env
.CreateCoreWebView2ControllerWithOptions(hwnd, &controller_opts, &handler)
.map_err(Into::into)
}),
Box::new(move |error_code, controller| {
error_code?;
tx.send(controller.ok_or_else(|| windows::core::Error::from(E_POINTER)))
.map_err(|_| windows::core::Error::from(E_UNEXPECTED))
}),
)?;
if composition {
CreateCoreWebView2CompositionControllerCompletedHandler::wait_for_async_operation(
Box::new(move |handler| unsafe {
env
.CreateCoreWebView2CompositionControllerWithOptions(hwnd, &controller_opts, &handler)
.map_err(webview2_com::Error::WindowsError)
}),
Box::new(move |error_code, controller| {
error_code?;
tx.send(
controller
.ok_or_else(|| windows::core::Error::from(E_POINTER))
.and_then(|c| c.cast::<ICoreWebView2Controller>()),
)
.expect("send over mpsc channel");
Ok(())
}),
)?;
} else {
CreateCoreWebView2ControllerCompletedHandler::wait_for_async_operation(
Box::new(move |handler| unsafe {
env
.CreateCoreWebView2ControllerWithOptions(hwnd, &controller_opts, &handler)
.map_err(Into::into)
}),
Box::new(move |error_code, controller| {
error_code?;
tx.send(controller.ok_or_else(|| windows::core::Error::from(E_POINTER)))
.map_err(|_| windows::core::Error::from(E_UNEXPECTED))
}),
)?;
}

rx.recv()?.map_err(Into::into)
}
Expand Down

0 comments on commit 87bb057

Please sign in to comment.