Skip to content

Commit

Permalink
Set Window Background colour if provided + debounce redraw option (#1466
Browse files Browse the repository at this point in the history
)

* Set Window Background colour if provided. Added debounce option for Webview2 redraw on resize

* [windows] Workaround resize flickering in frameless mode

Co-authored-by: stffabi <stffabi@users.noreply.github.com>
  • Loading branch information
leaanthony and stffabi committed Jun 20, 2022
1 parent 4dd1be5 commit cb16961
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 15 deletions.
1 change: 1 addition & 0 deletions v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require github.com/bitfield/script v0.19.0
require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/bep/debounce v1.2.1 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
Expand Down
2 changes: 2 additions & 0 deletions v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/bitfield/script v0.19.0 h1:W24f+FQuPab9gXcW8bhcbo5qO8AtrXyu3XOnR4zhHN0=
github.com/bitfield/script v0.19.0/go.mod h1:ana6F8YOSZ3ImT8SauIzuYSqXgFVkSUJ6kgja+WMmIY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
43 changes: 30 additions & 13 deletions v2/internal/frontend/desktop/windows/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,28 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32"
"io"
"log"
"net/http"
"net/http/httptest"
"net/url"
"runtime"
"strconv"
"strings"
"text/template"

"github.com/bep/debounce"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/system/operatingsystem"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/windows"
"io"
"log"
"net/http"
"net/http/httptest"
"net/url"
"runtime"
"strconv"
"strings"
"text/template"
"time"
)

const startURL = "http://wails.localhost/"
Expand All @@ -54,7 +55,8 @@ type Frontend struct {
hasStarted bool

// Windows build number
versionInfo *operatingsystem.WindowsVersionInfo
versionInfo *operatingsystem.WindowsVersionInfo
resizeDebouncer func(f func())
}

func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
Expand All @@ -71,6 +73,12 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
versionInfo: versionInfo,
}

if appoptions.Windows != nil {
if appoptions.Windows.ResizeDebounceMS > 0 {
result.resizeDebouncer = debounce.New(time.Duration(appoptions.Windows.ResizeDebounceMS) * time.Millisecond)
}
}

// We currently can't use wails://wails/ as other platforms do, therefore we map the assets sever onto the following url.
result.startURL, _ = url.Parse(startURL)

Expand Down Expand Up @@ -151,7 +159,15 @@ func (f *Frontend) Run(ctx context.Context) error {
}
}

f.chromium.Resize()
if f.resizeDebouncer != nil {
f.resizeDebouncer(func() {
f.mainWindow.Invoke(func() {
f.chromium.Resize()
})
})
} else {
f.chromium.Resize()
}
})

mainWindow.OnClose().Bind(func(arg *winc.Event) {
Expand Down Expand Up @@ -329,6 +345,7 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
log.Fatal(err)
}
})

}

func (f *Frontend) Quit() {
Expand Down
6 changes: 6 additions & 0 deletions v2/internal/frontend/desktop/windows/win32/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ var (
moduser32 = syscall.NewLazyDLL("user32.dll")
procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW")
procGetWindowLong = moduser32.NewProc("GetWindowLongW")
procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW")
procShowWindow = moduser32.NewProc("ShowWindow")
)
var (
moddwmapi = syscall.NewLazyDLL("dwmapi.dll")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea")
)
var (
modwingdi = syscall.NewLazyDLL("gdi32.dll")
procCreateSolidBrush = modwingdi.NewProc("CreateSolidBrush")
)

var windowsVersion, _ = operatingsystem.GetWindowsVersionInfo()

func IsWindowsVersionAtLeast(major, minor, buildNumber int) bool {
Expand Down
20 changes: 20 additions & 0 deletions v2/internal/frontend/desktop/windows/win32/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package win32

import (
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc"
"log"
"syscall"
"unsafe"
Expand Down Expand Up @@ -33,6 +34,10 @@ const (
SW_FORCEMINIMIZE = 11
)

const (
GCLP_HBRBACKGROUND int32 = -10
)

// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx
type MARGINS struct {
CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32
Expand Down Expand Up @@ -74,6 +79,12 @@ func ShowWindowMinimised(hwnd uintptr) {
showWindow(hwnd, SW_MINIMIZE)
}

func SetBackgroundColour(hwnd uintptr, r, g, b uint8) {
col := winc.RGB(r, g, b)
hbrush, _, _ := procCreateSolidBrush.Call(uintptr(col))
setClassLongPtr(hwnd, GCLP_HBRBACKGROUND, hbrush)
}

func dwmExtendFrameIntoClientArea(hwnd uintptr, margins *MARGINS) error {
ret, _, _ := procDwmExtendFrameIntoClientArea.Call(
hwnd,
Expand All @@ -86,6 +97,15 @@ func dwmExtendFrameIntoClientArea(hwnd uintptr, margins *MARGINS) error {
return nil
}

func setClassLongPtr(hwnd uintptr, param int32, val uintptr) bool {
ret, _, _ := procSetClassLongPtr.Call(
hwnd,
uintptr(param),
val,
)
return ret != 0
}

func getWindowLong(hwnd uintptr, index int) int32 {
ret, _, _ := procGetWindowLong.Call(
hwnd,
Expand Down
14 changes: 12 additions & 2 deletions v2/internal/frontend/desktop/windows/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
package windows

import (
"unsafe"

"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32"
"github.com/wailsapp/wails/v2/internal/system/operatingsystem"
"unsafe"

"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
Expand Down Expand Up @@ -66,6 +67,10 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope
}
}

if appoptions.RGBA != nil {
win32.SetBackgroundColour(result.Handle(), appoptions.RGBA.R, appoptions.RGBA.G, appoptions.RGBA.B)
}

result.SetSize(appoptions.Width, appoptions.Height)
result.SetText(appoptions.Title)
result.EnableSizable(!appoptions.DisableResize)
Expand Down Expand Up @@ -191,6 +196,8 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
// This hides the titlebar and also disables the resizing from user interaction because the standard frame is not
// shown. We still need the WS_THICKFRAME style to enable resizing from the frontend.
if wparam != 0 {
rgrc := (*w32.RECT)(unsafe.Pointer(lparam))

style := uint32(w32.GetWindowLong(w.Handle(), w32.GWL_STYLE))
if style&w32.WS_MAXIMIZE != 0 {
// If the window is maximized we must adjust the client area to the work area of the monitor. Otherwise
Expand All @@ -200,7 +207,6 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
var monitorInfo w32.MONITORINFO
monitorInfo.CbSize = uint32(unsafe.Sizeof(monitorInfo))
if w32.GetMonitorInfo(monitor, &monitorInfo) {
rgrc := (*w32.RECT)(unsafe.Pointer(lparam))
*rgrc = monitorInfo.RcWork

maxWidth := w.frontendOptions.MaxWidth
Expand All @@ -220,6 +226,10 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
}
}
}
} else {
// This is needed to workaround the resize flickering in frameless mode with WindowDecorations
// See: https://stackoverflow.com/a/6558508
rgrc.Bottom -= 1
}

return 0
Expand Down
4 changes: 4 additions & 0 deletions v2/pkg/options/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ type Options struct {

// User messages that can be customised
Messages *Messages

// ResizeDebounceMS is the amount of time to debounce redraws of webview2
// when resizing the window
ResizeDebounceMS uint16
}

func DefaultMessages() *Messages {
Expand Down
9 changes: 9 additions & 0 deletions website/docs/reference/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,15 @@ Type: `*windows.Messages`
A struct of strings used by the webview2 installer if a valid webview2 runtime is not found.
Customise this for any language you choose to support.

### ResizeDebounceMS

Name: ResizeDebounceMS

Type: uint16

ResizeDebounceMS is the amount of time to debounce redraws of webview2 when resizing the window.
The default value (0) will perform redraws as fast as it can.

## Mac Specific Options

### TitleBar
Expand Down

0 comments on commit cb16961

Please sign in to comment.