feat(macos): implement background_color for WKWebView#1662
feat(macos): implement background_color for WKWebView#1662pewsheen merged 4 commits intotauri-apps:devfrom
Conversation
Previously, `background_color` / `with_background_color` was documented as "Not implemented" on macOS. The WKWebView rendered a white background by default, causing a visible white flash on startup for apps using a dark theme with a hidden-then-shown window pattern. This implements macOS support using two complementary approaches: 1. Disable the default white background via the `drawsBackground` KVC key on WKWebViewConfiguration (the same private key already used by the `transparent` feature). 2. Set `underPageBackgroundColor` (public API, macOS 12+) on the WKWebView instance for overscroll/loading areas. Both init-time (`with_background_color`) and runtime (`set_background_color`) paths are now implemented. Fixes tauri-apps#197
src/wkwebview/mod.rs
Outdated
| // so the WKWebView never renders a white frame. | ||
| // Uses the same `drawsBackground` KVC key as the `transparent` feature above. | ||
| #[cfg(target_os = "macos")] | ||
| if attributes.background_color.is_some() { |
There was a problem hiding this comment.
you can merge this into the transparent if above. since it is a private api it should be behind a feature flag. having one use of it behind a flag and the other not does not make much sense. Of course we could remove the flag since nobody ever reported issues with it, but we all know that the reports will come in as soon as we do 😂
There was a problem hiding this comment.
I had a feeling you were gonna say similar, fine! 😛
Consolidate the drawsBackground KVC call into the existing transparent feature-gated block instead of a separate macOS-only block. Also gate the runtime set_background_color behind the transparent feature.
pewsheen
left a comment
There was a problem hiding this comment.
Thanks for the PR. My only concern here is that Tauri has minimal support for macOS 10.15+.
I'm not sure if it will crash when calling setUnderPageBackgroundColor under macOS 12.
Maybe we should set a version check like how datastore did and mention in document that only macOS12+ will work:
Line 224 in 9fa99b1
|
That sounds reasonable to me. I can adjust accordingly? |
Sure! |
setUnderPageBackgroundColor is only available on macOS 12+. Add os_major_version >= 12 guards at both call sites (init-time and runtime set_background_color) to prevent crashes on older macOS.
|
Gated, re-tested |
|
I can't run macOS 11 either lol. @JSKitty we'll need you to add a changelog in |
|
I think I still have a VM with it somewhere, will check after breakfast |
|
i meant breakfast tomorrow 🙃 |
|
Okay so my macOS 11 VM has gone missing and my macOS 10.15 VM is broken beyond repair, so i used https://developer.apple.com/documentation/webkit/wkwebview/isinspectable?language=objc to simulate a similar situation on my macOS 12 VM. At least in that test, the kind of version guard we have is enough, which is enough for me to approve this. |
Package Changes Through 86c00faThere are 1 changes which include wry with patch Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
Summary
Implements
background_color/with_background_color/set_background_coloron macOS — the only remaining platform where this was documented as "Not implemented".drawsBackgroundKVC key onWKWebViewConfiguration(pre-init), the same key already used by thetransparentfeatureunderPageBackgroundColor(public API, macOS 12+) on theWKWebViewinstance for overscroll/loading areasContext
The
backgroundColorconfig in Tauri'stauri.conf.jsoncorrectly sets the NSWindow background on macOS, and the webview background on Windows (WebView2), Linux (WebKitGTK), iOS, and Android. However, wry's macOS codepath was a no-op — the WKWebView layer on top of the window retained its default white background, causing a visible white flash before HTML/CSS paints.This has been a long-standing issue affecting dark-themed apps that use a hidden-then-shown window pattern to prevent flash on startup. The fix was deferred in the original PR #682 because no maintainer had macOS hardware to test on. The Vector Privacy team would like to change that — we're committed to assisting fully with the review and merging of this PR, for the benefit of Vector as well as all other Tauri v2 apps on macOS that deserve a standardised way of preventing "the unholy flashbang".
Real-World Tests (on a real Tauri v2 app)
Before (With Flashbang!):
Screen.Recording.2026-02-05.at.22.48.41.mp4
After (No Flashbang!):
Screen.Recording.2026-02-05.at.22.43.39.mp4
Approach:
drawsBackgroundKVC keyThere is no public Apple API to disable WKWebView's default white background on macOS (
NSViewdoesn't have a writableopaqueproperty like iOS'sUIView). ThedrawsBackgroundKVC key onWKWebViewConfigurationis the standard approach — and is already used by wry's owntransparentfeature.We investigated alternatives:
setUnderPageBackgroundColoralone — does not prevent the initial white flash (only affects overscroll areas)setOpaque(false)— not available on macOSNSView(iOS-only setter)setTimeoutdelays before.show()— device-dependent, unreliable across hardwareFeature-gating
If the maintainers prefer extra caution, this could be gated behind the existing
transparentormacos-private-apifeature flag — though we'd argue it should be ungated sincebackground_coloris a standard webview configuration, and the same KVC key is already used by thetransparentfeature on macOS.Research: safety of the
drawsBackgroundKVC keyWe conducted extensive research into the App Store safety of this key. Findings:
Zero documented App Store rejections. After searching Apple Developer Forums (thread/121139, thread/65553, thread/87474), GitHub issues across wry, Tauri, WebKit, react-native-webview, Sparkle, and the WebKit bug tracker (bug 200528) — not a single report documents an actual Mac App Store rejection caused by
drawsBackground.KVC string keys vs private selectors. Apple's App Store scanner works by extracting Objective-C selectors from the binary's
__objc_selrefssection and matching them against a private API database. WhendrawsBackgroundis accessed viasetValue:forKey:(a public KVC API), the binary only contains the public selectorsetValue:forKey:and a string literal — not the private selector_setDrawsBackground:. Documented App Store rejections (Electron #20027, react-native-webview #2527, cordova-plugin-ionic-webview #286) all flagged direct private selectors or class names in__objc_selrefs/__objc_classrefs, never KVC string keys.~9 years of stability. The
drawsBackgroundproperty has been present in WebKit since at least macOS 10.12 Sierra (2016) through macOS 15 Sequoia (2025), declared inWKWebViewPrivate.handWKWebViewConfigurationPrivate.h. It has never been removed or broken across releases.Apple is aware of the gap. Feedback FB7539179 (filed January 2020) explicitly requested Apple make transparent WKWebView backgrounds a public API on macOS, noting developers are forced to use a "semi-private property." Apple has not made it public, but has also not broken or flagged it.
No public alternative exists. Apple added
underPageBackgroundColor(macOS 12+) as a public API, but it only controls the color visible when scrolling past page bounds — it does not replacedrawsBackgroundfor preventing the white background from rendering.wry's existing warnings are precautionary. The documentation at
src/lib.rslines 309-312 warns to "avoid this in release build if your app needs to publish to App Store" for thetransparentfeature. This warning cites no actual rejection event and is precautionary in nature (tauri-docs #463 likewise contains no evidence of rejections).Test plan
backgroundColor: "#030303"+visible: false+ show-on-content-ready patternunderPageBackgroundColorwith_background_color) and runtime (set_background_color) paths