mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
[v3 windows] Initial webview2 working
This commit is contained in:
+8
-9
@@ -183,6 +183,8 @@ An 'X' indicates that the option is not supported by the platform.
|
||||
| Hidden | Y | | | |
|
||||
| EnableFraudulentWebsiteWarnings | | | | |
|
||||
| Zoom | | | | |
|
||||
| ZoomControlEnabled | | | | |
|
||||
| OpenInspectorOnStartup | | | | |
|
||||
| EnableDragAndDrop | | | | |
|
||||
| Windows | Y | - | - | |
|
||||
| Focused | Y | | | |
|
||||
@@ -286,15 +288,14 @@ Built-in plugin support:
|
||||
|
||||
### Mac Options
|
||||
|
||||
| Feature | Default | Notes |
|
||||
|-------------------|-------------------|------------------------------------------------------|
|
||||
| Backdrop | MacBackdropNormal | Standard solid window |
|
||||
| DisableShadow | false | |
|
||||
| TitleBar | | Standard window decorations by default |
|
||||
| Appearance | DefaultAppearance | |
|
||||
| Feature | Default | Notes |
|
||||
|-------------------------|-------------------|------------------------------------------------------|
|
||||
| Backdrop | MacBackdropNormal | Standard solid window |
|
||||
| DisableShadow | false | |
|
||||
| TitleBar | | Standard window decorations by default |
|
||||
| Appearance | DefaultAppearance | |
|
||||
| InvisibleTitleBarHeight | 0 | Creates an invisible title bar for frameless windows |
|
||||
|
||||
|
||||
## Windows Specific
|
||||
|
||||
- [x] Translucency
|
||||
@@ -311,6 +312,4 @@ Built-in plugin support:
|
||||
| DisableFramelessWindowDecorations | | |
|
||||
| WindowMask | nil | Makes the window the contents of the bitmap |
|
||||
|
||||
|
||||
|
||||
## Linux Specific
|
||||
|
||||
@@ -5,16 +5,20 @@ go 1.20
|
||||
require github.com/wailsapp/wails/v3 v3.0.0-alpha.0
|
||||
|
||||
require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/samber/lo v1.37.0 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.1 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 // indirect
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/wailsapp/wails/v3 => ../..
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
|
||||
@@ -18,6 +24,8 @@ github.com/samber/lo v1.37.0/go.mod h1:9vaz2O4o8oOnK23pd2TrXufcbdbJIa3b6cstBWKpo
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II=
|
||||
github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4=
|
||||
@@ -25,10 +33,12 @@ golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
+250
-256
File diff suppressed because it is too large
Load Diff
@@ -18,8 +18,9 @@ require (
|
||||
github.com/pterm/pterm v0.12.51
|
||||
github.com/samber/lo v1.37.0
|
||||
github.com/tc-hib/winres v0.1.6
|
||||
github.com/wailsapp/go-webview2 v1.0.1
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6
|
||||
golang.org/x/sys v0.7.0
|
||||
golang.org/x/sys v0.8.0
|
||||
modernc.org/sqlite v1.21.0
|
||||
)
|
||||
|
||||
@@ -31,6 +32,7 @@ require (
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/gookit/color v1.5.2 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
github.com/joho/godotenv v1.4.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
|
||||
@@ -41,6 +41,8 @@ github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
|
||||
github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
|
||||
github.com/jackmordaunt/icns/v2 v2.2.1 h1:MGklwYP2yohKn2Bw7XxlF69LZe98S1vUfl5OvAulPwg=
|
||||
github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -140,6 +142,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/tc-hib/winres v0.1.6 h1:qgsYHze+BxQPEYilxIz/KCQGaClvI2+yLBAZs+3+0B8=
|
||||
github.com/tc-hib/winres v0.1.6/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
|
||||
github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II=
|
||||
github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
@@ -172,6 +176,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -185,8 +190,8 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
||||
@@ -23,6 +23,9 @@ import (
|
||||
|
||||
var globalApplication *App
|
||||
|
||||
// isDebugMode is true if the application is running in debug mode
|
||||
var isDebugMode func() bool
|
||||
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
@@ -53,6 +56,13 @@ func New(appOptions Options) *App {
|
||||
result.log.AddOutput(&logger.Console{})
|
||||
}
|
||||
|
||||
// Patch isDebug if we aren't in prod mode
|
||||
if isDebugMode == nil {
|
||||
isDebugMode = func() bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
result.Events = NewWailsEventProcessor(result.dispatchEventToWindows)
|
||||
|
||||
opts := assetserveroptions.Options{
|
||||
@@ -206,7 +216,8 @@ type App struct {
|
||||
contextMenus map[string]*Menu
|
||||
contextMenusLock sync.Mutex
|
||||
|
||||
assets *assetserver.AssetServer
|
||||
assets *assetserver.AssetServer
|
||||
startURL string
|
||||
|
||||
// Hooks
|
||||
windowCreatedCallbacks []func(window *WebviewWindow)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
//go:build production
|
||||
|
||||
package application
|
||||
|
||||
// We use this to patch the application to production mode.
|
||||
func init() {
|
||||
isDebugMode = func() bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,9 @@ type WebviewWindowOptions struct {
|
||||
Hidden bool
|
||||
EnableFraudulentWebsiteWarnings bool
|
||||
Zoom float64
|
||||
ZoomControlEnabled bool
|
||||
EnableDragAndDrop bool
|
||||
OpenInspectorOnStartup bool
|
||||
Mac MacWindow
|
||||
Windows WindowsWindow
|
||||
Focused bool
|
||||
|
||||
@@ -38,6 +38,16 @@ type WindowsWindow struct {
|
||||
// WindowMask is used to set the window shape. Use a PNG with an alpha channel to create a custom shape.
|
||||
WindowMask []byte
|
||||
WindowMaskDraggable bool
|
||||
|
||||
// Path where the WebView2 stores the user data. If empty %APPDATA%\[BinaryName.exe] will be used.
|
||||
// If the path is not valid, a messagebox will be displayed with the error and the app will exit with error code.
|
||||
WebviewUserDataPath string
|
||||
|
||||
// Path to the directory with WebView2 executables. If empty WebView2 installed in the system will be used.
|
||||
WebviewBrowserPath string
|
||||
|
||||
// WebviewGpuIsDisabled is used to enable / disable GPU acceleration for the webview
|
||||
WebviewGpuIsDisabled bool
|
||||
}
|
||||
|
||||
type Theme int
|
||||
|
||||
@@ -1111,7 +1111,9 @@ func (w *macosWebviewWindow) run() {
|
||||
w.setMaxSize(w.parent.options.MaxWidth, w.parent.options.MaxHeight)
|
||||
}
|
||||
//w.setZoom(w.parent.options.Zoom)
|
||||
w.enableDevTools()
|
||||
if isDebugMode() {
|
||||
w.enableDevTools()
|
||||
}
|
||||
w.setBackgroundColour(w.parent.options.BackgroundColour)
|
||||
|
||||
macOptions := w.parent.options.Mac
|
||||
|
||||
@@ -5,12 +5,19 @@ package application
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/wailsapp/go-webview2/pkg/edge"
|
||||
"github.com/wailsapp/wails/v3/pkg/events"
|
||||
"github.com/wailsapp/wails/v3/pkg/w32"
|
||||
)
|
||||
@@ -27,6 +34,10 @@ type windowsWebviewWindow struct {
|
||||
previousWindowStyle uint32
|
||||
previousWindowExStyle uint32
|
||||
previousWindowPlacement w32.WINDOWPLACEMENT
|
||||
|
||||
// Webview
|
||||
chromium *edge.Chromium
|
||||
hasStarted bool
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) nativeWindowHandle() uintptr {
|
||||
@@ -89,6 +100,8 @@ func (w *windowsWebviewWindow) run() {
|
||||
|
||||
options := w.parent.options
|
||||
|
||||
w.chromium = edge.NewChromium()
|
||||
|
||||
var exStyle uint
|
||||
exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW
|
||||
if options.BackgroundType != BackgroundTypeSolid {
|
||||
@@ -197,6 +210,8 @@ func (w *windowsWebviewWindow) run() {
|
||||
w.Focus()
|
||||
}
|
||||
|
||||
w.setupChromium()
|
||||
|
||||
if !options.Hidden {
|
||||
w.show()
|
||||
w.update()
|
||||
@@ -622,6 +637,10 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
|
||||
// Unregister the window with the application
|
||||
windowsApp := globalApplication.impl.(*windowsApp)
|
||||
windowsApp.unregisterWindow(w)
|
||||
case w32.WM_NCLBUTTONDOWN:
|
||||
w32.SetFocus(w.hwnd)
|
||||
case w32.WM_MOVE, w32.WM_MOVING:
|
||||
_ = w.chromium.NotifyParentWindowPositionChanged()
|
||||
case w32.WM_GETMINMAXINFO:
|
||||
mmi := (*w32.MINMAXINFO)(unsafe.Pointer(lparam))
|
||||
hasConstraints := false
|
||||
@@ -742,7 +761,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
|
||||
// In Full-Screen mode we don't need to adjust anything
|
||||
// It essential we have the flag here, that is set before SetWindowPos in fullscreen/unfullscreen
|
||||
// because the native size might not yet reflect we are in fullscreen during this event!
|
||||
// TODO: w.chromium.SetPadding(edge.Rect{})
|
||||
w.chromium.SetPadding(edge.Rect{})
|
||||
} else if w.isMaximised() {
|
||||
// If the window is maximized we must adjust the client area to the work area of the monitor. Otherwise
|
||||
// some content goes beyond the visible part of the monitor.
|
||||
@@ -773,7 +792,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: w.chromium.SetPadding(edge.Rect{})
|
||||
w.chromium.SetPadding(edge.Rect{})
|
||||
} else {
|
||||
// This is needed to workaround the resize flickering in frameless mode with WindowDecorations
|
||||
// See: https://stackoverflow.com/a/6558508
|
||||
@@ -782,7 +801,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
|
||||
// Increasing the bottom also worksaround the flickering but we would loose 1px of the WebView content
|
||||
// therefore let's pad the content with 1px at the bottom.
|
||||
rgrc.Bottom += 1
|
||||
// TODO: w.chromium.SetPadding(edge.Rect{Bottom: 1})
|
||||
w.chromium.SetPadding(edge.Rect{Bottom: 1})
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -878,6 +897,304 @@ func (w *windowsWebviewWindow) isAlwaysOnTop() bool {
|
||||
return w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE)&w32.WS_EX_TOPMOST != 0
|
||||
}
|
||||
|
||||
// processMessage is given a message sent from JS via the postMessage API
|
||||
// We put it on the global window message buffer to be processed centrally
|
||||
func (w *windowsWebviewWindow) processMessage(message string) {
|
||||
// We send all messages to the centralised window message buffer
|
||||
windowMessageBuffer <- &windowMessage{
|
||||
windowId: w.parent.id,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func coreWebview2RequestToHttpRequest(coreReq *edge.ICoreWebView2WebResourceRequest) func() (*http.Request, error) {
|
||||
return func() (r *http.Request, err error) {
|
||||
header := http.Header{}
|
||||
headers, err := coreReq.GetHeaders()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetHeaders Error: %s", err)
|
||||
}
|
||||
defer headers.Release()
|
||||
|
||||
headersIt, err := headers.GetIterator()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetIterator Error: %s", err)
|
||||
}
|
||||
defer headersIt.Release()
|
||||
|
||||
for {
|
||||
has, err := headersIt.HasCurrentHeader()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("HasCurrentHeader Error: %s", err)
|
||||
}
|
||||
if !has {
|
||||
break
|
||||
}
|
||||
|
||||
name, value, err := headersIt.GetCurrentHeader()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetCurrentHeader Error: %s", err)
|
||||
}
|
||||
|
||||
header.Set(name, value)
|
||||
if _, err := headersIt.MoveNext(); err != nil {
|
||||
return nil, fmt.Errorf("MoveNext Error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
method, err := coreReq.GetMethod()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetMethod Error: %s", err)
|
||||
}
|
||||
|
||||
uri, err := coreReq.GetUri()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUri Error: %s", err)
|
||||
}
|
||||
|
||||
var body io.ReadCloser
|
||||
if content, err := coreReq.GetContent(); err != nil {
|
||||
return nil, fmt.Errorf("GetContent Error: %s", err)
|
||||
} else if content != nil {
|
||||
body = &iStreamReleaseCloser{stream: content}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, uri, body)
|
||||
if err != nil {
|
||||
if body != nil {
|
||||
body.Close()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
req.Header = header
|
||||
return req, nil
|
||||
}
|
||||
}
|
||||
|
||||
type iStreamReleaseCloser struct {
|
||||
stream *edge.IStream
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (i *iStreamReleaseCloser) Read(p []byte) (int, error) {
|
||||
if i.closed {
|
||||
return 0, io.ErrClosedPipe
|
||||
}
|
||||
return i.stream.Read(p)
|
||||
}
|
||||
|
||||
func (i *iStreamReleaseCloser) Close() error {
|
||||
if i.closed {
|
||||
return nil
|
||||
}
|
||||
i.closed = true
|
||||
return i.stream.Release()
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) processRequest(req *edge.ICoreWebView2WebResourceRequest, args *edge.ICoreWebView2WebResourceRequestedEventArgs) {
|
||||
/*
|
||||
webviewRequests <- &webViewAssetRequest{
|
||||
Request: webview.NewRequest(wkUrlSchemeTask),
|
||||
windowId: uint(windowID),
|
||||
windowName: globalApplication.getWindowForID(uint(windowID)).Name(),
|
||||
}
|
||||
*/
|
||||
// Setting the UserAgent on the CoreWebView2Settings clears the whole default UserAgent of the Edge browser, but
|
||||
// we want to just append our ApplicationIdentifier. So we adjust the UserAgent for every request.
|
||||
if reqHeaders, err := req.GetHeaders(); err == nil {
|
||||
useragent, _ := reqHeaders.GetHeader(assetserver.HeaderUserAgent)
|
||||
useragent = strings.Join([]string{useragent, assetserver.WailsUserAgentValue}, " ")
|
||||
reqHeaders.SetHeader(assetserver.HeaderUserAgent, useragent)
|
||||
reqHeaders.Release()
|
||||
}
|
||||
|
||||
if globalApplication.assets == nil {
|
||||
// We are using the devServer let the WebView2 handle the request with its default handler
|
||||
return
|
||||
}
|
||||
|
||||
//Get the request
|
||||
uri, _ := req.GetUri()
|
||||
reqUri, err := url.ParseRequestURI(uri)
|
||||
if err != nil {
|
||||
globalApplication.error("Unable to parse request uri %s: %s", uri, err)
|
||||
return
|
||||
}
|
||||
|
||||
if reqUri.Scheme != "http" {
|
||||
// Let the WebView2 handle the request with its default handler
|
||||
return
|
||||
} else if reqUri.Host != "wails.localhost" {
|
||||
// Let the WebView2 handle the request with its default handler
|
||||
return
|
||||
}
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
globalApplication.assets.ProcessHTTPRequestLegacy(rw, coreWebview2RequestToHttpRequest(req))
|
||||
|
||||
headers := []string{}
|
||||
for k, v := range rw.Header() {
|
||||
headers = append(headers, fmt.Sprintf("%s: %s", k, strings.Join(v, ",")))
|
||||
}
|
||||
|
||||
env := w.chromium.Environment()
|
||||
response, err := env.CreateWebResourceResponse(rw.Body.Bytes(), rw.Code, http.StatusText(rw.Code), strings.Join(headers, "\n"))
|
||||
if err != nil {
|
||||
globalApplication.error("CreateWebResourceResponse Error: %s", err)
|
||||
return
|
||||
}
|
||||
defer response.Release()
|
||||
|
||||
// Send response back
|
||||
err = args.PutResponse(response)
|
||||
if err != nil {
|
||||
globalApplication.error("PutResponse Error: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) setupChromium() {
|
||||
chromium := w.chromium
|
||||
debugMode := isDebugMode()
|
||||
|
||||
disableFeatues := []string{}
|
||||
|
||||
if !w.parent.options.EnableFraudulentWebsiteWarnings {
|
||||
disableFeatues = append(disableFeatues, "msSmartScreenProtection")
|
||||
}
|
||||
|
||||
opts := w.parent.options.Windows
|
||||
chromium.DataPath = opts.WebviewUserDataPath
|
||||
chromium.BrowserPath = opts.WebviewBrowserPath
|
||||
|
||||
if opts.WebviewGpuIsDisabled {
|
||||
chromium.AdditionalBrowserArgs = append(chromium.AdditionalBrowserArgs, "--disable-gpu")
|
||||
}
|
||||
|
||||
if len(disableFeatues) > 0 {
|
||||
arg := fmt.Sprintf("--disable-features=%s", strings.Join(disableFeatues, ","))
|
||||
chromium.AdditionalBrowserArgs = append(chromium.AdditionalBrowserArgs, arg)
|
||||
}
|
||||
|
||||
chromium.MessageCallback = w.processMessage
|
||||
chromium.WebResourceRequestedCallback = w.processRequest
|
||||
chromium.NavigationCompletedCallback = w.navigationCompleted
|
||||
chromium.AcceleratorKeyCallback = func(vkey uint) bool {
|
||||
w32.PostMessage(w.hwnd, w32.WM_KEYDOWN, uintptr(vkey), 0)
|
||||
return false
|
||||
}
|
||||
|
||||
chromium.Embed(w.hwnd)
|
||||
chromium.Resize()
|
||||
settings, err := chromium.GetSettings()
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
err = settings.PutAreDefaultContextMenusEnabled(debugMode)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
err = settings.PutAreDevToolsEnabled(debugMode)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
|
||||
if w.parent.options.Zoom > 0.0 {
|
||||
chromium.PutZoomFactor(w.parent.options.Zoom)
|
||||
}
|
||||
err = settings.PutIsZoomControlEnabled(w.parent.options.ZoomControlEnabled)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
|
||||
err = settings.PutIsStatusBarEnabled(false)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
err = settings.PutAreBrowserAcceleratorKeysEnabled(false)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
err = settings.PutIsSwipeNavigationEnabled(false)
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
|
||||
if debugMode && w.parent.options.OpenInspectorOnStartup {
|
||||
chromium.OpenDevToolsWindow()
|
||||
}
|
||||
|
||||
//TODO: Setup focus event handler
|
||||
//onFocus := f.mainWindow.OnSetFocus()
|
||||
//onFocus.Bind(f.onFocus)
|
||||
|
||||
// Set background colour
|
||||
w.setBackgroundColour(w.parent.options.BackgroundColour)
|
||||
|
||||
chromium.SetGlobalPermission(edge.CoreWebView2PermissionStateAllow)
|
||||
chromium.AddWebResourceRequestedFilter("*", edge.COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL)
|
||||
chromium.Navigate("http://wails.localhost")
|
||||
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) navigationCompleted(sender *edge.ICoreWebView2, args *edge.ICoreWebView2NavigationCompletedEventArgs) {
|
||||
|
||||
// TODO: DomReady Event
|
||||
|
||||
// Todo: Resize hacks
|
||||
/*
|
||||
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
|
||||
f.ExecJS("window.wails.flags.enableResize = true;")
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: Work out why we need this
|
||||
//if w.hasStarted {
|
||||
// return
|
||||
//}
|
||||
//w.hasStarted = true
|
||||
|
||||
// Hack to make it visible: https://github.com/MicrosoftEdge/WebView2Feedback/issues/1077#issuecomment-825375026
|
||||
err := w.chromium.Hide()
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
}
|
||||
if w.parent.options.Hidden {
|
||||
return
|
||||
}
|
||||
err = w.chromium.Show()
|
||||
if err != nil {
|
||||
globalApplication.fatal(err.Error())
|
||||
|
||||
}
|
||||
|
||||
//if w.parent.options.Hidden {
|
||||
// return
|
||||
//}
|
||||
|
||||
//switch f.frontendOptions.WindowStartState {
|
||||
//case options.Maximised:
|
||||
// if !f.frontendOptions.DisableResize {
|
||||
// win32.ShowWindowMaximised(f.mainWindow.Handle())
|
||||
// } else {
|
||||
// win32.ShowWindow(f.mainWindow.Handle())
|
||||
// }
|
||||
//case options.Minimised:
|
||||
// win32.ShowWindowMinimised(f.mainWindow.Handle())
|
||||
//case options.Fullscreen:
|
||||
// f.mainWindow.Fullscreen()
|
||||
// win32.ShowWindow(f.mainWindow.Handle())
|
||||
//default:
|
||||
// if f.frontendOptions.Fullscreen {
|
||||
// f.mainWindow.Fullscreen()
|
||||
// }
|
||||
// win32.ShowWindow(f.mainWindow.Handle())
|
||||
//}
|
||||
//
|
||||
//f.mainWindow.hasBeenShown = true
|
||||
|
||||
}
|
||||
|
||||
func ScaleWithDPI(pixels int, dpi uint) int {
|
||||
return (pixels * int(dpi)) / 96
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user