Skip to content

feat(macos): implement background_color for WKWebView#1662

Merged
pewsheen merged 4 commits intotauri-apps:devfrom
VectorPrivacy:fix/macos-background-color-upstream
Feb 8, 2026
Merged

feat(macos): implement background_color for WKWebView#1662
pewsheen merged 4 commits intotauri-apps:devfrom
VectorPrivacy:fix/macos-background-color-upstream

Conversation

@JSKitty
Copy link
Contributor

@JSKitty JSKitty commented Feb 5, 2026

Summary

Implements background_color / with_background_color / set_background_color on macOS — the only remaining platform where this was documented as "Not implemented".

  • Disables the default white WKWebView background via the drawsBackground KVC key on WKWebViewConfiguration (pre-init), the same key already used by the transparent feature
  • Sets underPageBackgroundColor (public API, macOS 12+) on the WKWebView instance for overscroll/loading areas
  • Updates all three doc comments to reflect macOS support

Context

The backgroundColor config in Tauri's tauri.conf.json correctly 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: drawsBackground KVC key

There is no public Apple API to disable WKWebView's default white background on macOS (NSView doesn't have a writable opaque property like iOS's UIView). The drawsBackground KVC key on WKWebViewConfiguration is the standard approach — and is already used by wry's own transparent feature.

We investigated alternatives:

  • setUnderPageBackgroundColor alone — does not prevent the initial white flash (only affects overscroll areas)
  • setOpaque(false) — not available on macOS NSView (iOS-only setter)
  • JS-side setTimeout delays before .show() — device-dependent, unreliable across hardware

Feature-gating

If the maintainers prefer extra caution, this could be gated behind the existing transparent or macos-private-api feature flag — though we'd argue it should be ungated since background_color is a standard webview configuration, and the same KVC key is already used by the transparent feature on macOS.

Research: safety of the drawsBackground KVC key

We 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_selrefs section and matching them against a private API database. When drawsBackground is accessed via setValue:forKey: (a public KVC API), the binary only contains the public selector setValue: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 drawsBackground property has been present in WebKit since at least macOS 10.12 Sierra (2016) through macOS 15 Sequoia (2025), declared in WKWebViewPrivate.h and WKWebViewConfigurationPrivate.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 replace drawsBackground for preventing the white background from rendering.

wry's existing warnings are precautionary. The documentation at src/lib.rs lines 309-312 warns to "avoid this in release build if your app needs to publish to App Store" for the transparent feature. This warning cites no actual rejection event and is precautionary in nature (tauri-docs #463 likewise contains no evidence of rejections).

Test plan

  • Tested on macOS (Apple Silicon) with a Tauri v2 app using backgroundColor: "#030303" + visible: false + show-on-content-ready pattern
  • Verified zero white flash on startup in release builds — no JS-side delays needed
  • Verified overscroll areas show the correct dark color via underPageBackgroundColor
  • Confirmed the fix works with both init-time (with_background_color) and runtime (set_background_color) paths
  • Windows/Linux builds should be unaffected (no changes to those codepaths)

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
@JSKitty JSKitty requested a review from a team as a code owner February 5, 2026 22:38
// 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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Contributor

@pewsheen pewsheen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

let custom_data_store_available = os_major_version >= 14;

@JSKitty
Copy link
Contributor Author

JSKitty commented Feb 6, 2026

That sounds reasonable to me. I can adjust accordingly?

@pewsheen
Copy link
Contributor

pewsheen commented Feb 6, 2026

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.
@JSKitty
Copy link
Contributor Author

JSKitty commented Feb 6, 2026

Gated, re-tested Wry in my Production App on macOS 26.2 (Tahoe) with the expected functionality, I do not have an older MacBook (Intel) to test the false branch however.

@pewsheen
Copy link
Contributor

pewsheen commented Feb 7, 2026

I'll see if I can run macOS 11 VM on my machine.

I can't run macOS 11 either lol.
@FabianLars, do you have the machine to test this one? Otherwise I think the code is good to merge.

@JSKitty we'll need you to add a changelog in .changes/ (https://github.com/tauri-apps/wry/blob/dev/.changes/readme.md)

@FabianLars
Copy link
Member

I think I still have a VM with it somewhere, will check after breakfast

@FabianLars
Copy link
Member

i meant breakfast tomorrow 🙃

@FabianLars
Copy link
Member

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.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

Package Changes Through 86c00fa

There are 1 changes which include wry with patch

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
wry 0.54.1 0.54.2

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@pewsheen pewsheen merged commit 1d1b870 into tauri-apps:dev Feb 8, 2026
20 checks passed
@JSKitty JSKitty deleted the fix/macos-background-color-upstream branch February 8, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants