From 7b1c26adff5fdf13a3364b6fc26c8444c120d5c1 Mon Sep 17 00:00:00 2001 From: Jamie Ridding Date: Wed, 21 Aug 2024 04:01:27 +0100 Subject: [PATCH] feat(windows): add `WebViewBuilderExtWindows::with_scroll_bar_style` (#1344) * Windows: Use `CoreWebView2EnvironmentOptions` API. Use the CoreWebView2EnvironmentOptions API wrapper when creating a WebView2 environment on Windows, as opposed to using the ICoreWebView2EnvironmentOptions* COM interfaces. The wrapper exposes the interface methods with a more Rust-like API. It may be possible to do this with ICoreWebView2Controller as well, but I don't feel like experimenting with that right now. This is just an improvement I realised I could make while implementing #1339. Signed-off-by: Jamie Ridding * Add with_scroll_bar_style to WebViewBuilderExtWindows Signed-off-by: Jamie Ridding * Add change file. Signed-off-by: Jamie Ridding * Adjust change type in change file. I used the wrong change type for wry in 1344-with_scroll_bar_style. This commit upgrades the change type from a patch to a minor change. Signed-off-by: Jamie Ridding * I forgot to run cargo fmt -_- Signed-off-by: Jamie Ridding --------- Signed-off-by: Jamie Ridding --- .changes/1344-with_scroll_bar_style.md | 5 +++++ src/lib.rs | 18 ++++++++++++++++ src/webview2/mod.rs | 29 +++++++++++++++++++------- 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 .changes/1344-with_scroll_bar_style.md diff --git a/.changes/1344-with_scroll_bar_style.md b/.changes/1344-with_scroll_bar_style.md new file mode 100644 index 000000000..36845ec6b --- /dev/null +++ b/.changes/1344-with_scroll_bar_style.md @@ -0,0 +1,5 @@ +--- +"wry": minor +--- + +Windows: Implement `WebViewBuilderExtWindows::with_scroll_bar_style` to allow opting into Fluent Overlay style scrollbars. diff --git a/src/lib.rs b/src/lib.rs index 88eb0a389..114c1f060 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -238,6 +238,8 @@ pub use wkwebview::{PrintMargin, PrintOptions}; #[cfg(target_os = "windows")] pub(crate) mod webview2; #[cfg(target_os = "windows")] +pub use self::webview2::ScrollBarStyle; +#[cfg(target_os = "windows")] use self::webview2::*; #[cfg(target_os = "windows")] use webview2_com::Microsoft::Web::WebView2::Win32::ICoreWebView2Controller; @@ -1088,6 +1090,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes { browser_accelerator_keys: bool, theme: Option, use_https: bool, + scroll_bar_style: ScrollBarStyle, } #[cfg(windows)] @@ -1098,6 +1101,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. + scroll_bar_style: ScrollBarStyle::default(), } } } @@ -1140,6 +1144,15 @@ pub trait WebViewBuilderExtWindows { /// /// The default value is `false`. fn with_https_scheme(self, enabled: bool) -> Self; + + /// Specifies the native scrollbar style to use with webview2. + /// CSS styles that modify the scrollbar are applied on top of the native appearance configured here. + /// + /// Defaults to [`ScrollbarStyle::Default`] which is the browser default used by Microsoft Edge. + /// + /// Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions, + /// see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541 + fn with_scroll_bar_style(self, style: ScrollBarStyle) -> Self; } #[cfg(windows)] @@ -1163,6 +1176,11 @@ impl WebViewBuilderExtWindows for WebViewBuilder<'_> { self.platform_specific.use_https = enabled; self } + + fn with_scroll_bar_style(mut self, style: ScrollBarStyle) -> Self { + self.platform_specific.scroll_bar_style = style; + self + } } #[cfg(target_os = "android")] diff --git a/src/webview2/mod.rs b/src/webview2/mod.rs index 23bc14fea..ff2fdb463 100644 --- a/src/webview2/mod.rs +++ b/src/webview2/mod.rs @@ -287,26 +287,30 @@ impl InnerWebView { arguments }); - let additional_browser_args = HSTRING::from(additional_browser_args); - let (tx, rx) = mpsc::channel(); CreateCoreWebView2EnvironmentCompletedHandler::wait_for_async_operation( Box::new(move |environmentcreatedhandler| unsafe { - let options: ICoreWebView2EnvironmentOptions = - CoreWebView2EnvironmentOptions::default().into(); + let options = CoreWebView2EnvironmentOptions::default(); - let _ = options.SetAdditionalBrowserArguments(&additional_browser_args); + options.set_additional_browser_arguments(additional_browser_args); // Get user's system language let lcid = GetUserDefaultUILanguage(); let mut lang = [0; MAX_LOCALE_NAME as usize]; LCIDToLocaleName(lcid as u32, Some(&mut lang), LOCALE_ALLOW_NEUTRAL_NAMES); - options.SetLanguage(PCWSTR::from_raw(lang.as_ptr()))?; + options.set_language(String::from_utf16_lossy(&lang)); + + let scroll_bar_style = match pl_attrs.scroll_bar_style { + ScrollBarStyle::Default => COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT, + ScrollBarStyle::FluentOverlay => COREWEBVIEW2_SCROLLBAR_STYLE_FLUENT_OVERLAY, + }; + + options.set_scroll_bar_style(scroll_bar_style); CreateCoreWebView2EnvironmentWithOptions( PCWSTR::null(), &data_directory.unwrap_or_default(), - &options, + &ICoreWebView2EnvironmentOptions::from(options), &environmentcreatedhandler, ) .map_err(Into::into) @@ -1371,6 +1375,17 @@ impl InnerWebView { } } +/// The scrollbar style to use in the webview. +#[derive(Clone, Copy, Default)] +pub enum ScrollBarStyle { + #[default] + /// The browser default scrollbar style. + Default, + + /// Fluent UI style overlay scrollbars. + FluentOverlay, +} + #[inline] fn load_url_with_headers( webview: &ICoreWebView2,