diff --git a/v3/go.mod b/v3/go.mod index a664f784..4109f965 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -3,6 +3,7 @@ module github.com/wailsapp/wails/v3 go 1.19 require ( + github.com/bep/debounce v1.2.1 github.com/go-ole/go-ole v1.2.6 github.com/go-task/task/v3 v3.20.0 github.com/google/go-cmp v0.5.9 diff --git a/v3/go.sum b/v3/go.sum index 3057c2cf..8d2aa703 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -12,6 +12,8 @@ github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/ github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= github.com/MarvinJWendt/testza v0.5.1 h1:a9Fqx6vQrHQ4CyiaLhktfTTelwGotmFWy8MNhyaohw8= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= diff --git a/v3/pkg/application/options_win.go b/v3/pkg/application/options_win.go index c4842f63..cefd3219 100644 --- a/v3/pkg/application/options_win.go +++ b/v3/pkg/application/options_win.go @@ -48,6 +48,10 @@ type WindowsWindow struct { // WebviewGpuIsDisabled is used to enable / disable GPU acceleration for the webview WebviewGpuIsDisabled bool + + // ResizeDebounceMS is the amount of time to debounce redraws of webview2 + // when resizing the window + ResizeDebounceMS uint16 } type Theme int diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index b07c4993..34507973 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -5,6 +5,7 @@ package application import ( "errors" "fmt" + "github.com/bep/debounce" "github.com/wailsapp/wails/v2/pkg/assetserver" "io" "net/http" @@ -12,6 +13,7 @@ import ( "net/url" "strconv" "strings" + "time" "unicode/utf16" "unsafe" @@ -36,8 +38,9 @@ type windowsWebviewWindow struct { previousWindowPlacement w32.WINDOWPLACEMENT // Webview - chromium *edge.Chromium - hasStarted bool + chromium *edge.Chromium + hasStarted bool + resizeDebouncer func(func()) } func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { @@ -202,6 +205,10 @@ func (w *windowsWebviewWindow) run() { w.setWindowMask(options.Windows.WindowMask) } + if options.Windows.ResizeDebounceMS > 0 { + w.resizeDebouncer = debounce.New(time.Duration(options.Windows.ResizeDebounceMS) * time.Millisecond) + } + if options.Centered { w.center() } @@ -641,6 +648,26 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp w32.SetFocus(w.hwnd) case w32.WM_MOVE, w32.WM_MOVING: _ = w.chromium.NotifyParentWindowPositionChanged() + case w32.WM_SIZING: + // If the window is frameless, and we are minimizing, then we need to suppress the Resize on the + // WebView2. If we don't do this, restoring does not work as expected and first restores with some wrong + // size during the restore animation and only fully renders when the animation is done. This highly + // depends on the content in the WebView, see https://github.com/wailsapp/wails/issues/1319 + if w.parent.options.Frameless && wparam == w32.SIZE_MINIMIZED { + return 0 + } + + // If we have a resize debouncer, use it + if w.resizeDebouncer != nil { + w.resizeDebouncer(func() { + invokeSync(func() { + w.chromium.Resize() + }) + }) + } else { + w.chromium.Resize() + } + case w32.WM_GETMINMAXINFO: mmi := (*w32.MINMAXINFO)(unsafe.Pointer(lparam)) hasConstraints := false