From 751e4afe3f5b508b95ff9eb1169c5cff890c6abd Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 27 Sep 2025 12:25:00 +1000 Subject: [PATCH] [V3] Fix Window Affinity weirdness (#4600) * Fix window affinity weirdness * Update changelog --- v3/UNRELEASED_CHANGELOG.md | 2 + v3/pkg/application/webview_window_windows.go | 48 ++++++++++++++++---- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 8e4648038..b319ef8d8 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -23,6 +23,8 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Windows: Flicker of window at start and hidden windows being shown incorrectly in [PR](https://github.com/wailsapp/wails/pull/4600) by @leaanthony. +- Fixed Wayland window size maximising issues (https://github.com/wailsapp/wails/issues/4429) by [@samstanier](https://github.com/samstanier) ## Deprecated diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 5e9c5907d..4052fa0f4 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -61,6 +61,8 @@ type windowsWebviewWindow struct { showRequested bool // Track if show() was called before navigation completed visibilityTimeout *time.Timer // Timeout to show window if navigation is delayed windowShown bool // Track if window container has been shown + // Track whether content protection has been applied to the native window yet + contentProtectionApplied bool // resizeBorder* is the width/height of the resize border in pixels. resizeBorderWidth int32 @@ -386,9 +388,6 @@ func (w *windowsWebviewWindow) run() { globalApplication.fatal("unable to create window") } - // Process ContentProtection - w.setContentProtection(w.parent.options.ContentProtectionEnabled) - // Ensure correct window size in case the scale factor of current screen is different from the initial one. // This could happen when using the default window position and the window launches on a secondary monitor. currentScreen, _ := w.getScreen() @@ -1093,6 +1092,7 @@ func (w *windowsWebviewWindow) show() { w32.ShowWindow(w.hwnd, w32.SW_SHOW) w.windowShown = true w.showRequested = true + w.updateContentProtection() // Show WebView if navigation has completed if w.webviewNavigationCompleted { @@ -1437,6 +1437,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp case w32.WM_SHOWWINDOW: if wparam == 1 { w.parent.emit(events.Windows.WindowShow) + w.updateContentProtection() } else { w.parent.emit(events.Windows.WindowHide) } @@ -2446,13 +2447,40 @@ func (w *windowsWebviewWindow) snapAssist() { } func (w *windowsWebviewWindow) setContentProtection(enabled bool) { - var affinity uint32 = w32.WDA_EXCLUDEFROMCAPTURE - if !enabled { - affinity = w32.WDA_NONE + // Ensure the option reflects the requested state for future show() calls + w.parent.options.ContentProtectionEnabled = enabled + w.updateContentProtection() +} + +func (w *windowsWebviewWindow) updateContentProtection() { + if w.hwnd == 0 { + return } - if ok := w32.SetWindowDisplayAffinity(w.hwnd, affinity); !ok { - // Note: wrapper already falls back to WDA_MONITOR on older Windows. - globalApplication.warning("SetWindowDisplayAffinity failed: window=%v, affinity=%v", - w.parent.id, affinity) + + if !w.isVisible() { + // Defer updates until the window is visible to avoid affinity glitches. + return + } + + desired := w.parent.options.ContentProtectionEnabled + + if desired { + if w.applyDisplayAffinity(w32.WDA_EXCLUDEFROMCAPTURE) { + w.contentProtectionApplied = true + } + return + } + + if w.applyDisplayAffinity(w32.WDA_NONE) { + w.contentProtectionApplied = false } } + +func (w *windowsWebviewWindow) applyDisplayAffinity(affinity uint32) bool { + if ok := w32.SetWindowDisplayAffinity(w.hwnd, affinity); !ok { + // Note: wrapper already falls back to WDA_MONITOR on older Windows. + globalApplication.warning("SetWindowDisplayAffinity failed: window=%v, affinity=%v", w.parent.id, affinity) + return false + } + return true +}