From cba65d65264f941312b46642584d83e17bd94486 Mon Sep 17 00:00:00 2001 From: zetaloop Date: Mon, 25 May 2026 15:56:35 +0800 Subject: [PATCH] feat(core): add no_redirection_bitmap API on Windows --- .changes/no-redirection-bitmap-api.md | 5 +++++ .changes/no-redirection-bitmap-config.md | 6 ++++++ .changes/no-redirection-bitmap.md | 7 +++++++ crates/tauri-cli/config.schema.json | 7 ++++++- crates/tauri-runtime-wry/src/lib.rs | 9 +++++++++ crates/tauri-runtime/src/window.rs | 10 ++++++++++ .../schemas/config.schema.json | 7 ++++++- crates/tauri-utils/src/config.rs | 11 +++++++++++ crates/tauri/src/test/mock_runtime.rs | 4 ++++ crates/tauri/src/webview/webview_window.rs | 13 +++++++++++++ crates/tauri/src/window/mod.rs | 13 +++++++++++++ packages/api/src/window.ts | 9 +++++++++ 12 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 .changes/no-redirection-bitmap-api.md create mode 100644 .changes/no-redirection-bitmap-config.md create mode 100644 .changes/no-redirection-bitmap.md diff --git a/.changes/no-redirection-bitmap-api.md b/.changes/no-redirection-bitmap-api.md new file mode 100644 index 000000000000..23aa252d9077 --- /dev/null +++ b/.changes/no-redirection-bitmap-api.md @@ -0,0 +1,5 @@ +--- +'@tauri-apps/api': 'minor:feat' +--- + +Added `noRedirectionBitmap` option to the `Window` and `WebviewWindow` constructors on Windows. diff --git a/.changes/no-redirection-bitmap-config.md b/.changes/no-redirection-bitmap-config.md new file mode 100644 index 000000000000..5264ba4c31a0 --- /dev/null +++ b/.changes/no-redirection-bitmap-config.md @@ -0,0 +1,6 @@ +--- +'tauri': 'minor:feat' +'tauri-utils': 'minor:feat' +--- + +Added `app > windows > noRedirectionBitmap` config option to disable the window redirection bitmap on Windows. diff --git a/.changes/no-redirection-bitmap.md b/.changes/no-redirection-bitmap.md new file mode 100644 index 000000000000..230cb4b4878c --- /dev/null +++ b/.changes/no-redirection-bitmap.md @@ -0,0 +1,7 @@ +--- +'tauri': 'minor:feat' +'tauri-runtime': 'minor:feat' +'tauri-runtime-wry': 'minor:feat' +--- + +Added `WindowBuilder/WebviewWindowBuilder::no_redirection_bitmap` method to disable the window redirection bitmap on Windows. diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 898317a465a0..8746baa8e557 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -374,7 +374,7 @@ "type": "boolean" }, "transparent": { - "description": "Whether the window is transparent or not.\n\n Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.\n WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.", + "description": "Whether the window is transparent or not.\n\n Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.\n WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.\n\n On Windows, using `noRedirectionBitmap` can help avoid a white flash when creating a transparent window.", "default": false, "type": "boolean" }, @@ -425,6 +425,11 @@ "null" ] }, + "noRedirectionBitmap": { + "description": "This sets `WS_EX_NOREDIRECTIONBITMAP`.\n\n This can avoid the white flash that may appear before the webview content is rendered\n when using a transparent window. **Windows only**.", + "default": false, + "type": "boolean" + }, "theme": { "description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.", "anyOf": [ diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 7cfbe1855033..6d3d6dcc5905 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -942,6 +942,7 @@ impl WindowBuilder for WindowBuilderWrapper { .content_protected(config.content_protected) .skip_taskbar(config.skip_taskbar) .theme(config.theme) + .no_redirection_bitmap(config.no_redirection_bitmap) .closable(config.closable) .maximizable(config.maximizable) .minimizable(config.minimizable) @@ -1301,6 +1302,14 @@ impl WindowBuilder for WindowBuilderWrapper { self } + fn no_redirection_bitmap(#[allow(unused_mut)] mut self, _enable: bool) -> Self { + #[cfg(windows)] + { + self.inner = self.inner.with_no_redirection_bitmap(_enable); + } + self + } + #[cfg(target_os = "android")] fn activity_name>(mut self, class_name: S) -> Self { self.inner = self.inner.with_activity_name(class_name.into()); diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index e20613ea260d..936280ca18c3 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -363,6 +363,9 @@ pub trait WindowBuilder: WindowBuilderBase { /// Whether the window should be transparent. If this is true, writing colors /// with alpha values different than `1.0` will produce a transparent window. + /// + /// On Windows, using `no_redirection_bitmap` can help avoid a white flash when + /// creating a transparent window. #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] #[cfg_attr( docsrs, @@ -498,6 +501,13 @@ pub trait WindowBuilder: WindowBuilderBase { #[must_use] fn window_classname>(self, window_classname: S) -> Self; + /// This sets `WS_EX_NOREDIRECTIONBITMAP`. + /// + /// This can avoid the white flash that may appear before the webview content is rendered + /// when using a transparent window. **Windows only**. + #[must_use] + fn no_redirection_bitmap(self, enable: bool) -> Self; + /// The name of the activity to create for this webview window. #[cfg(target_os = "android")] fn activity_name>(self, class_name: S) -> Self; diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 898317a465a0..8746baa8e557 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -374,7 +374,7 @@ "type": "boolean" }, "transparent": { - "description": "Whether the window is transparent or not.\n\n Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.\n WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.", + "description": "Whether the window is transparent or not.\n\n Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.\n WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.\n\n On Windows, using `noRedirectionBitmap` can help avoid a white flash when creating a transparent window.", "default": false, "type": "boolean" }, @@ -425,6 +425,11 @@ "null" ] }, + "noRedirectionBitmap": { + "description": "This sets `WS_EX_NOREDIRECTIONBITMAP`.\n\n This can avoid the white flash that may appear before the webview content is rendered\n when using a transparent window. **Windows only**.", + "default": false, + "type": "boolean" + }, "theme": { "description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.", "anyOf": [ diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index a54c619e3f6f..334355aa7987 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -2021,6 +2021,8 @@ pub struct WindowConfig { /// /// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`. /// WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`. + /// + /// On Windows, using `noRedirectionBitmap` can help avoid a white flash when creating a transparent window. #[serde(default)] pub transparent: bool, /// Whether the window is maximized or not. @@ -2053,6 +2055,12 @@ pub struct WindowConfig { pub skip_taskbar: bool, /// The name of the window class created on Windows to create the window. **Windows only**. pub window_classname: Option, + /// This sets `WS_EX_NOREDIRECTIONBITMAP`. + /// + /// This can avoid the white flash that may appear before the webview content is rendered + /// when using a transparent window. **Windows only**. + #[serde(default, alias = "no-redirection-bitmap")] + pub no_redirection_bitmap: bool, /// The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+. pub theme: Option, /// The style of the macOS title bar. @@ -2327,6 +2335,7 @@ impl Default for WindowConfig { content_protected: false, skip_taskbar: false, window_classname: None, + no_redirection_bitmap: false, theme: None, title_bar_style: Default::default(), traffic_light_position: None, @@ -3873,6 +3882,7 @@ mod build { let content_protected = self.content_protected; let skip_taskbar = self.skip_taskbar; let window_classname = opt_str_lit(self.window_classname.as_ref()); + let no_redirection_bitmap = self.no_redirection_bitmap; let theme = opt_lit(self.theme.as_ref()); let title_bar_style = &self.title_bar_style; let traffic_light_position = opt_lit(self.traffic_light_position.as_ref()); @@ -3938,6 +3948,7 @@ mod build { content_protected, skip_taskbar, window_classname, + no_redirection_bitmap, theme, title_bar_style, traffic_light_position, diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index f51c488ec143..0fffeaeec95e 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -464,6 +464,10 @@ impl WindowBuilder for MockWindowBuilder { self } + fn no_redirection_bitmap(self, enable: bool) -> Self { + self + } + fn shadow(self, enable: bool) -> Self { self } diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 8db5db27dbd3..eb0098df9fdb 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -599,6 +599,16 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self } + /// This sets `WS_EX_NOREDIRECTIONBITMAP`. + /// + /// This can avoid the white flash that may appear before the webview content is rendered + /// when using a transparent window. **Windows only**. + #[must_use] + pub fn no_redirection_bitmap(mut self, enable: bool) -> Self { + self.window_builder = self.window_builder.no_redirection_bitmap(enable); + self + } + /// Sets whether or not the window has shadow. /// /// ## Platform-specific @@ -1072,6 +1082,9 @@ impl> WebviewWindowBuilder<'_, R, M> { /// Whether the window should be transparent. If this is true, writing colors /// with alpha values different than `1.0` will produce a transparent window. + /// + /// On Windows, using `no_redirection_bitmap` can help avoid a white flash when + /// creating a transparent window. #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] #[cfg_attr( docsrs, diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 6be20288bd0c..8ec3281a38c6 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -611,6 +611,16 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { self } + /// This sets `WS_EX_NOREDIRECTIONBITMAP`. + /// + /// This can avoid the white flash that may appear before the webview content is rendered + /// when using a transparent window. **Windows only**. + #[must_use] + pub fn no_redirection_bitmap(mut self, enable: bool) -> Self { + self.window_builder = self.window_builder.no_redirection_bitmap(enable); + self + } + /// Sets whether or not the window has shadow. /// /// ## Platform-specific @@ -906,6 +916,9 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { /// Whether the window should be transparent. If this is true, writing colors /// with alpha values different than `1.0` will produce a transparent window. + /// + /// On Windows, using `no_redirection_bitmap` can help avoid a white flash when + /// creating a transparent window. #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] #[cfg_attr( docsrs, diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index a6b157ad84d3..bbf8be44c1a4 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -2362,6 +2362,8 @@ interface WindowOptions { * Whether the window is transparent or not. * Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > app > macOSPrivateApi`. * WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`. + * + * On Windows, using `noRedirectionBitmap` can help avoid a white flash when creating a transparent window. */ transparent?: boolean /** Whether the window should be maximized upon creation or not. */ @@ -2378,6 +2380,13 @@ interface WindowOptions { contentProtected?: boolean /** Whether or not the window icon should be added to the taskbar. */ skipTaskbar?: boolean + /** + * This sets `WS_EX_NOREDIRECTIONBITMAP`. + * + * This can avoid the white flash that may appear before the webview content is rendered + * when using a transparent window. **Windows only**. + */ + noRedirectionBitmap?: boolean /** * Whether or not the window has shadow. *