Compare commits

...

33 Commits

Author SHA1 Message Date
Lea Anthony c24aef8ea1 Initial commit. Need to fix userid write permission issues 2022-02-22 19:12:13 +11:00
Misitebao 91934d1f8e docs: synchronize and optimize documents (#1167)
* docs: sync chinese documents

* docs: optimize chinese terminology
2022-02-21 20:24:06 +11:00
Lea Anthony 2f7293e25c Add platform flag to docs 2022-02-20 18:52:41 +11:00
Lea Anthony 18c76602b5 Add platform flag to docs 2022-02-20 18:49:12 +11:00
Lea Anthony 93491eb2eb Feature/align api (#1161)
* Fix WindowSetRGBA API

* Change WindowUnFullscreen -> WindowUnfullscreen for consistency
RGBA bugfix
2022-02-19 20:29:55 +11:00
Misitebao 2ded86c369 docs: sync chinese documents (#1160) 2022-02-19 09:40:54 +11:00
Lea Anthony f059c35d9e Feature: WindowToggleMaximise (#1159)
* [windows] Add WindowToggleMaximise

* Add mac support

* Update docs

* [linux] Toggle Maximise
2022-02-18 20:28:16 +11:00
Lea Anthony 6e8d65e3aa [linux] Add stdint.h include 2022-02-17 21:23:24 +11:00
stffabi a750d2d507 [v2, windows] Invert the frameless border flag and rename it (#1157)
This is a breaking change for all users of the flag.
2022-02-16 20:28:46 +11:00
stffabi 331e0268a3 [v2, windows] Do not show caption buttons if frameless and translucent+transparency (#1152) 2022-02-16 18:53:17 +11:00
Valentin Trinqué e6424dc8ab Update icon.ico file mode (#1154)
* Add os.O_WRONLY to icon.ico to avoid bad file descriptor error

* Wrap errors coming from winres.LoadICO()

If the file exists but is empty, a blunt "Unexpected EOF" is returned, and propagated as is.

This is not super helpful when trying to pin point what's going on.

Wrapping the error helps to locate the problem.
2022-02-16 06:02:45 +11:00
Lea Anthony f923a431f7 Try to provide help when old xcode tools installed. #1142 2022-02-12 21:12:17 +11:00
Lea Anthony 00db626942 State no support for anonymous structs in binding. Fixes #1142 2022-02-12 20:59:57 +11:00
Lea Anthony eb0f22b4ee Fix appicon bug on Mac. Fixes #1143 2022-02-12 20:48:43 +11:00
Lea Anthony e068e0f2f5 Better platform support 2022-02-10 21:43:04 +11:00
Lea Anthony 771594519f [mac] Better support for multi-builds 2022-02-10 21:41:40 +11:00
Lea Anthony ec44ca58f1 Better output for build 2022-02-10 21:25:43 +11:00
Lea Anthony cb574148eb Better output for build 2022-02-10 21:24:27 +11:00
Lea Anthony 771efa527f Don't clean directory on subsequent builds 2022-02-10 21:14:02 +11:00
Lea Anthony 28e31c46c6 Fix output filename for windows builds 2022-02-10 21:11:32 +11:00
Lea Anthony c2fa4b6103 Support multiple targets for windows 2022-02-10 19:55:04 +11:00
Lea Anthony 99ca6d5e77 [Linux] Restore min/max after fullscreen 2022-02-10 19:55:04 +11:00
Lea Anthony 876b845762 [Windows] Restore min/max after fullscreen 2022-02-10 19:55:04 +11:00
stffabi e4122ce4d2 [v2, windows] Bump winc (#1134)
Fix detection if GetDpiForWindow is available
2022-02-08 19:01:38 +11:00
stffabi 7bc51725c0 [v2, windows] Apply suggested window size during DPI changed event (#1131)
* [v2, windows] Apply suggested window size during DPI changed event

This adjusts the window size if the window is moved from one
monitor to another with a different DPI scaling

* [v2, windows] Do not block processing of messages during frameless drag/resize

* [v2, windows] Bump winc

Improves the HiDPI handling by using newer APIs if available

* [v2, windows] Constrain frameless maximize to MaxWidth/MaxHeight
2022-02-08 07:56:01 +11:00
Lea Anthony 3d02a314b9 [linux] Fix min/max size after fullscreen 2022-02-08 07:04:45 +11:00
Lea Anthony 30a4f47cba [linux] Fix min/max size 2022-02-08 06:51:52 +11:00
Lea Anthony 668da3a827 [linux] Fix disabling context menu 2022-02-08 06:20:41 +11:00
Lea Anthony 322aad166b [linux] Fix fullscreen 2022-02-08 05:29:26 +11:00
Lea Anthony 3decd70319 Move more runtime methods to main thread 2022-02-07 20:17:25 +11:00
Lea Anthony 24857ec04b Only attach logger in debug mode. Fixes #1128 2022-02-07 20:00:26 +11:00
Lea Anthony a016f39e97 [linux] Move SetPosition, Center, Fullscreen and UnFullscreen to main thread 2022-02-07 08:48:21 +11:00
Lea Anthony 8699bf7521 [linux] Move SetTitle and startDrag to main thread 2022-02-07 08:47:11 +11:00
48 changed files with 2121 additions and 338 deletions
+118 -64
View File
@@ -2,7 +2,6 @@ package build
import (
"fmt"
"github.com/wailsapp/wails/v2/internal/colour"
"io"
"os"
"os/exec"
@@ -12,11 +11,13 @@ import (
"text/tabwriter"
"time"
"github.com/wailsapp/wails/v2/internal/colour"
"github.com/wailsapp/wails/v2/internal/project"
"github.com/wailsapp/wails/v2/internal/system"
"github.com/wailsapp/wails/v2/cmd/wails/internal"
"github.com/wailsapp/wails/v2/internal/gomod"
"github.com/wailsapp/wails/v2/internal/system"
"github.com/leaanthony/clir"
"github.com/leaanthony/slicer"
"github.com/wailsapp/wails/v2/pkg/clilogger"
@@ -49,8 +50,14 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
command.StringFlag("upxflags", "Flags to pass to upx", &compressFlags)
// Setup Platform flag
platform := runtime.GOOS
command.StringFlag("platform", "Platform to target", &platform)
platform := runtime.GOOS + "/"
if system.IsAppleSilicon {
platform += "arm64"
} else {
platform += runtime.GOARCH
}
command.StringFlag("platform", "Platform to target. Comma separate multiple platforms", &platform)
// Verbosity
verbosity := 1
@@ -103,28 +110,6 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
app.PrintBanner()
}
// Check platform
validPlatformArch := slicer.String([]string{
"darwin",
"darwin/amd64",
"darwin/arm64",
"darwin/universal",
"linux",
//"linux/amd64",
//"linux/arm-7",
"windows",
"windows/amd64",
"windows/arm64",
})
if !validPlatformArch.Contains(platform) {
return fmt.Errorf("platform %s is not supported. Platforms supported: %s", platform, validPlatformArch.Join(","))
}
if compress && platform == "darwin/universal" {
logger.Println("Warning: compress flag unsupported for universal binaries. Ignoring.")
compress = false
}
// Lookup compiler path
compilerPath, err := exec.LookPath(compilerCommand)
if err != nil {
@@ -174,6 +159,10 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
modeString = "Debug"
}
var targets slicer.StringSlicer
targets.AddSlice(strings.Split(platform, ","))
targets.Deduplicate()
// Create BuildOptions
buildOptions := &build.Options{
Logger: logger,
@@ -194,27 +183,13 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
WebView2Strategy: wv2rtstrategy,
}
// Calculate platform and arch
platformSplit := strings.Split(platform, "/")
buildOptions.Platform = platformSplit[0]
if system.IsAppleSilicon {
buildOptions.Arch = "arm64"
} else {
buildOptions.Arch = runtime.GOARCH
}
if len(platformSplit) == 2 {
buildOptions.Arch = platformSplit[1]
}
// Start a new tabwriter
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
// Write out the system information
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
fmt.Fprintf(w, "Platforms: \t%s\n", platform)
fmt.Fprintf(w, "Compiler: \t%s\n", compilerPath)
fmt.Fprintf(w, "Build Mode: \t%s\n", modeString)
fmt.Fprintf(w, "Skip Frontend: \t%t\n", skipFrontend)
@@ -223,7 +198,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
fmt.Fprintf(w, "LDFlags: \t\"%s\"\n", buildOptions.LDFlags)
fmt.Fprintf(w, "Tags: \t[%s]\n", strings.Join(buildOptions.UserTags, ","))
if len(buildOptions.OutputFile) > 0 {
if len(buildOptions.OutputFile) > 0 && targets.Length() == 1 {
fmt.Fprintf(w, "Output File: \t%s\n", buildOptions.OutputFile)
}
fmt.Fprintf(w, "\n")
@@ -234,30 +209,109 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
return err
}
return doBuild(buildOptions)
cwd, err := os.Getwd()
if err != nil {
return err
}
projectOptions, err := project.Load(cwd)
// Check platform
validPlatformArch := slicer.String([]string{
"darwin",
"darwin/amd64",
"darwin/arm64",
"darwin/universal",
"linux",
"linux/amd64",
"linux/arm64",
"windows",
"windows/amd64",
"windows/arm64",
})
targets.Each(func(platform string) {
if !validPlatformArch.Contains(platform) {
buildOptions.Logger.Println("platform '%s' is not supported - skipping. Supported platforms: %s", platform, validPlatformArch.Join(","))
return
}
desiredFilename := projectOptions.OutputFilename
if desiredFilename == "" {
desiredFilename = projectOptions.Name
}
desiredFilename = strings.TrimSuffix(desiredFilename, ".exe")
// Calculate platform and arch
platformSplit := strings.Split(platform, "/")
buildOptions.Platform = platformSplit[0]
if system.IsAppleSilicon {
buildOptions.Arch = "arm64"
} else {
buildOptions.Arch = runtime.GOARCH
}
if len(platformSplit) == 2 {
buildOptions.Arch = platformSplit[1]
}
banner := "Building target: " + platform
logger.Println(banner)
logger.Println(strings.Repeat("-", len(banner)))
if compress && platform == "darwin/universal" {
logger.Println("Warning: compress flag unsupported for universal binaries. Ignoring.")
compress = false
}
switch buildOptions.Platform {
case "darwin":
if runtime.GOOS != "darwin" {
logger.Println("Crosscompiling to Mac not currently supported.\n")
return
}
macTargets := targets.Filter(func(platform string) bool {
return strings.HasPrefix(platform, "darwin")
})
if macTargets.Length() == 2 {
buildOptions.BundleName = fmt.Sprintf("%s-%s.app", desiredFilename, buildOptions.Arch)
}
}
if targets.Length() > 1 {
// target filename
switch buildOptions.Platform {
case "windows":
desiredFilename = fmt.Sprintf("%s-%s", desiredFilename, buildOptions.Arch)
case "linux", "darwin":
desiredFilename = fmt.Sprintf("%s-%s-%s", desiredFilename, buildOptions.Platform, buildOptions.Arch)
}
}
if buildOptions.Platform == "windows" {
desiredFilename += ".exe"
}
buildOptions.OutputFile = desiredFilename
// Start Time
start := time.Now()
outputFilename, err := build.Build(buildOptions)
if err != nil {
logger.Println("Error: ", err.Error())
return
}
// Subsequent iterations
buildOptions.IgnoreFrontend = true
buildOptions.CleanBuildDirectory = false
// Output stats
buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.\n", outputFilename, time.Since(start).Round(time.Millisecond).String()))
})
return nil
})
}
// doBuild is our main build command
func doBuild(buildOptions *build.Options) error {
// Start Time
start := time.Now()
outputFilename, err := build.Build(buildOptions)
if err != nil {
return err
}
// Output stats
elapsed := time.Since(start)
buildOptions.Logger.Println("")
buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.", outputFilename, elapsed.Round(time.Millisecond).String()))
buildOptions.Logger.Println("")
return nil
}
func checkGoModVersion(logger *clilogger.CLILogger, updateGoMod bool) error {
cwd, err := os.Getwd()
if err != nil {
+28 -10
View File
@@ -7,15 +7,15 @@ require (
github.com/fatih/structtag v1.2.0
github.com/flytam/filenamify v1.0.0
github.com/fsnotify/fsnotify v1.4.9
github.com/fsouza/go-dockerclient v1.7.8
github.com/gabriel-vasile/mimetype v1.3.1
github.com/go-git/go-billy/v5 v5.2.0 // indirect
github.com/go-git/go-git/v5 v5.3.0
github.com/gofiber/fiber/v2 v2.17.0
github.com/gofiber/websocket/v2 v2.0.8
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.1.2 // indirect
github.com/gorilla/websocket v1.4.1
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/websocket v1.4.2
github.com/imdario/mergo v0.3.12
github.com/jackmordaunt/icns v1.0.0
github.com/leaanthony/clir v1.0.4
@@ -27,7 +27,7 @@ require (
github.com/leaanthony/idgen v1.0.0
github.com/leaanthony/slicer v1.5.0
github.com/leaanthony/typescriptify-golang-structs v0.1.7
github.com/leaanthony/winc v0.0.0-20220202120322-32d63aaf77de
github.com/leaanthony/winc v0.0.0-20220208061147-37b059b9dc3b
github.com/leaanthony/winicon v1.0.0
github.com/matryer/is v1.4.0
github.com/olekukonko/tablewriter v0.0.4
@@ -40,21 +40,29 @@ require (
github.com/tidwall/sjson v1.1.7
github.com/wzshiming/ctc v1.2.3
github.com/ztrue/tracerr v0.3.0
golang.org/x/mod v0.4.1
golang.org/x/net v0.0.0-20210510120150-4163338589ed
golang.org/x/mod v0.4.2
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
golang.org/x/tools v0.1.0
golang.org/x/tools v0.1.5
nhooyr.io/websocket v1.8.6
)
require (
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/Microsoft/hcsshim v0.9.2 // indirect
github.com/andybalholm/brotli v1.0.2 // indirect
github.com/containerd/cgroups v1.0.3 // indirect
github.com/containerd/containerd v1.6.0 // indirect
github.com/docker/docker v20.10.12+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/google/go-cmp v0.5.5 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
@@ -63,9 +71,17 @@ require (
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect
github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.5.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.0 // indirect
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/tidwall/gjson v1.8.0 // indirect
github.com/tidwall/match v1.0.3 // indirect
github.com/tidwall/pretty v1.1.0 // indirect
@@ -75,8 +91,10 @@ require (
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gotest.tools/v3 v3.1.0 // indirect
)
+1329 -18
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -81,8 +81,8 @@ func CreateApp(appoptions *options.App) (*App, error) {
debug := IsDebug()
ctx = context.WithValue(ctx, "debug", debug)
// Attach logger to context
ctx = context.WithValue(ctx, "logger", myLogger)
if debug {
ctx = context.WithValue(ctx, "logger", myLogger)
ctx = context.WithValue(ctx, "buildtype", "debug")
} else {
ctx = context.WithValue(ctx, "buildtype", "production")
+2 -2
View File
@@ -106,8 +106,8 @@ func (b BridgeClient) WindowFullscreen() {
b.session.log.Info("WindowFullscreen unsupported in Bridge mode")
}
func (b BridgeClient) WindowUnFullscreen() {
b.session.log.Info("WindowUnFullscreen unsupported in Bridge mode")
func (b BridgeClient) WindowUnfullscreen() {
b.session.log.Info("WindowUnfullscreen unsupported in Bridge mode")
}
func (b BridgeClient) WindowSetColour(colour int) {
+3 -2
View File
@@ -2,11 +2,12 @@ package bridge
import (
"fmt"
"github.com/wailsapp/wails/v2/pkg/runtime"
"os/exec"
"strconv"
"strings"
"github.com/wailsapp/wails/v2/pkg/runtime"
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
"github.com/wailsapp/wails/v2/internal/logger"
@@ -126,7 +127,7 @@ func (d *DialogClient) WindowSetMaxSize(width int, height int) {
func (d *DialogClient) WindowFullscreen() {
}
func (d *DialogClient) WindowUnFullscreen() {
func (d *DialogClient) WindowUnfullscreen() {
}
func (d *DialogClient) WindowSetColour(colour int) {
+148
View File
@@ -0,0 +1,148 @@
package docker
import (
"context"
dc "github.com/fsouza/go-dockerclient"
"io"
"strings"
)
func CrossCompile(projectPath string, outputfilename string, platform string, verbose bool, loggerWriter io.Writer) error {
client, err := dc.NewClientFromEnv()
if err != nil {
return err
}
tag := strings.ReplaceAll(platform, "/", "-")
outputStream := io.Discard
if verbose {
outputStream = loggerWriter
}
err = client.PullImage(dc.PullImageOptions{
All: false,
Repository: "wailsapp/cc",
Tag: tag,
Platform: "",
Registry: "",
OutputStream: outputStream,
RawJSONStream: false,
InactivityTimeout: 0,
Context: context.Background(),
}, dc.AuthConfiguration{})
if err != nil {
return err
}
projectDir := projectPath + ":/usr/src/myapp:rw"
env := []string{"CGO_ENABLED=1"}
if platform == "linux/arm64" {
env = append(env, "CC_FOR_TARGET=aarch64-linux-gnu-gcc", "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig")
}
container, err := client.CreateContainer(dc.CreateContainerOptions{
//Name: "wails-" + tag + "-builder",
Config: &dc.Config{
Env: env,
Cmd: []string{"go", "build", "-x", "-tags", "desktop,production", "-o", "build/bin/" + outputfilename},
Image: "wailsapp/cc:" + tag,
WorkingDir: "/usr/src/myapp",
AttachStdin: false,
AttachStdout: verbose,
AttachStderr: verbose,
ArgsEscaped: false,
},
HostConfig: &dc.HostConfig{
Binds: []string{projectDir},
Privileged: true,
AutoRemove: false,
},
NetworkingConfig: nil,
Context: nil,
})
if err != nil {
return err
}
err = client.StartContainer(container.ID, &dc.HostConfig{
Privileged: true,
AutoRemove: false,
})
if err != nil {
return err
}
statusCode, err := client.WaitContainer(container.ID)
if statusCode != 0 {
return err
}
/*
client, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return fmt.Errorf("error from Docker1: %v", err)
}
ctx := context.Background()
pulloutput, err := client.ImagePull(ctx, image, types.ImagePullOptions{})
defer pulloutput.Close()
output := loggerWriter
if output == nil {
output = os.Stdout
}
_, _ = io.Copy(output, pulloutput)
//if err != nil {
// if verbose {
// println("here")
//
//
// }
// return fmt.Errorf("error from Docker2: %v", err)
//}
resp, err := client.ContainerCreate(ctx, &container.Config{
AttachStdout: verbose,
AttachStderr: verbose,
Image: image,
Env: []string{"CGO_ENABLED=1"},
Cmd: []string{"go", "build", "-tags", "desktop,production"},
}, &container.HostConfig{
Mounts: []mount.Mount{
{
Type: mount.TypeBind,
Source: projectPath,
Target: "/usr/src/myapp",
},
},
}, nil, nil, "")
if err != nil {
return fmt.Errorf("error from Docker3: %v", err)
}
err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
if err != nil {
return fmt.Errorf("error from Docker4: %v", err)
}
statusCh, errCh := client.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
select {
case err := <-errCh:
if err != nil {
return fmt.Errorf("error from Docker5: %v", err)
}
case <-statusCh:
}
if verbose {
out, err := client.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
return fmt.Errorf("error from Docke6r: %v", err)
}
_, _ = stdcopy.StdCopy(os.Stdout, os.Stderr, out)
}
*/
return nil
}
+2 -7
View File
@@ -61,8 +61,8 @@ func (c *Client) WindowFullscreen() {
C.Fullscreen(c.app.app)
}
// WindowUnFullscreen will unfullscreen the window
func (c *Client) WindowUnFullscreen() {
// WindowUnfullscreen will unfullscreen the window
func (c *Client) WindowUnfullscreen() {
C.UnFullscreen(c.app.app)
}
@@ -141,8 +141,6 @@ func (c *Client) OpenFileDialog(dialogOptions runtime.OpenDialogOptions, callbac
c.app.string2CString(strings.Join(filters, ";")),
c.app.string2CString(dialogOptions.DefaultFilename),
c.app.string2CString(dialogOptions.DefaultDirectory),
c.app.bool2Cint(dialogOptions.AllowFiles),
c.app.bool2Cint(dialogOptions.AllowDirectories),
c.app.bool2Cint(false),
c.app.bool2Cint(dialogOptions.ShowHiddenFiles),
c.app.bool2Cint(dialogOptions.CanCreateDirectories),
@@ -189,8 +187,6 @@ func (c *Client) OpenMultipleFilesDialog(dialogOptions runtime.OpenDialogOptions
c.app.string2CString(strings.Join(filters, ";")),
c.app.string2CString(dialogOptions.DefaultFilename),
c.app.string2CString(dialogOptions.DefaultDirectory),
c.app.bool2Cint(dialogOptions.AllowFiles),
c.app.bool2Cint(dialogOptions.AllowDirectories),
c.app.bool2Cint(true),
c.app.bool2Cint(dialogOptions.ShowHiddenFiles),
c.app.bool2Cint(dialogOptions.CanCreateDirectories),
@@ -239,7 +235,6 @@ func (c *Client) MessageDialog(dialogOptions runtime.MessageDialogOptions, callb
c.app.string2CString(string(dialogOptions.Type)),
c.app.string2CString(dialogOptions.Title),
c.app.string2CString(dialogOptions.Message),
c.app.string2CString(dialogOptions.Icon),
c.app.string2CString(buttons[0]),
c.app.string2CString(buttons[1]),
c.app.string2CString(buttons[2]),
@@ -10,13 +10,14 @@ import "C"
import (
"encoding/json"
"github.com/leaanthony/go-common-file-dialog/cfd"
"github.com/wailsapp/wails/v2/pkg/runtime"
"golang.org/x/sys/windows"
"log"
"strconv"
"syscall"
"github.com/leaanthony/go-common-file-dialog/cfd"
"github.com/wailsapp/wails/v2/pkg/runtime"
"golang.org/x/sys/windows"
"github.com/wailsapp/wails/v2/internal/logger"
)
@@ -63,8 +64,8 @@ func (c *Client) WindowFullscreen() {
C.Fullscreen(c.app.app)
}
// WindowUnFullscreen will unfullscreen the window
func (c *Client) WindowUnFullscreen() {
// WindowUnfullscreen will unfullscreen the window
func (c *Client) WindowUnfullscreen() {
C.UnFullscreen(c.app.app)
}
@@ -30,6 +30,7 @@ void Fullscreen(void* ctx);
void UnFullscreen(void* ctx);
void Minimise(void* ctx);
void UnMinimise(void* ctx);
void ToggleMaximise(void* ctx);
void Maximise(void* ctx);
void UnMaximise(void* ctx);
void Hide(void* ctx);
@@ -156,6 +156,13 @@ void Maximise(void* inctx) {
);
}
void ToggleMaximise(void* inctx) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
ON_MAIN_THREAD(
[ctx ToggleMaximise];
);
}
const char* GetSize(void *inctx) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSRect frame = [ctx.mainWindow frame];
@@ -67,6 +67,7 @@
- (void) Minimise;
- (void) UnMinimise;
- (void) Maximise;
- (void) ToggleMaximise;
- (void) UnMaximise;
- (void) SetRGBA:(int)r :(int)g :(int)b :(int)a;
- (void) HideMouse;
@@ -322,11 +322,6 @@
return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
- (bool) isMaximised {
long mask = [self.mainWindow styleMask];
return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
// Fullscreen sets the main window to be fullscreen
- (void) Fullscreen {
if( ! [self isFullScreen] ) {
@@ -366,6 +361,10 @@
}
}
- (void) ToggleMaximise {
[self.mainWindow zoom:nil];
}
- (void) UnMaximise {
if ([self.mainWindow isZoomed]) {
[self.mainWindow zoom:nil];
@@ -167,7 +167,7 @@ func (f *Frontend) WindowFullscreen() {
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnFullscreen() {
func (f *Frontend) WindowUnfullscreen() {
f.mainWindow.UnFullscreen()
}
@@ -181,6 +181,9 @@ func (f *Frontend) WindowHide() {
func (f *Frontend) WindowMaximise() {
f.mainWindow.Maximise()
}
func (f *Frontend) WindowToggleMaximise() {
f.mainWindow.ToggleMaximise()
}
func (f *Frontend) WindowUnmaximise() {
f.mainWindow.UnMaximise()
}
@@ -154,6 +154,9 @@ func (w *Window) SetTitle(title string) {
func (w *Window) Maximise() {
C.Maximise(w.context)
}
func (w *Window) ToggleMaximise() {
C.ToggleMaximise(w.context)
}
func (w *Window) UnMaximise() {
C.UnMaximise(w.context)
@@ -43,8 +43,7 @@ type Frontend struct {
startURL string
// main window handle
mainWindow *Window
// minWidth, minHeight, maxWidth, maxHeight int
mainWindow *Window
bindings *binding.Bindings
dispatcher frontend.Dispatcher
servingFromDisk bool
@@ -160,7 +159,7 @@ func (f *Frontend) WindowFullscreen() {
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnFullscreen() {
func (f *Frontend) WindowUnfullscreen() {
f.mainWindow.UnFullscreen()
}
@@ -174,6 +173,9 @@ func (f *Frontend) WindowHide() {
func (f *Frontend) WindowMaximise() {
f.mainWindow.Maximise()
}
func (f *Frontend) WindowToggleMaximise() {
f.mainWindow.ToggleMaximise()
}
func (f *Frontend) WindowUnmaximise() {
f.mainWindow.UnMaximise()
}
+103 -36
View File
@@ -10,6 +10,7 @@ package linux
#include "webkit2/webkit2.h"
#include <stdio.h>
#include <limits.h>
#include "stdint.h"
void ExecuteOnMainThread(void* f, gpointer jscallback) {
@@ -32,25 +33,15 @@ static GtkBox* GTKBOX(void *pointer) {
return GTK_BOX(pointer);
}
static void SetMinSize(GtkWindow* window, int width, int height) {
GdkGeometry size;
size.min_height = height;
size.min_width = width;
gtk_window_set_geometry_hints(window, NULL, &size, GDK_HINT_MIN_SIZE);
}
static void SetMaxSize(GtkWindow* window, int width, int height) {
GdkGeometry size;
if( width == 0 ) {
width = INT_MAX;
}
if( height == 0 ) {
height = INT_MAX;
}
size.max_height = height;
size.max_width = width;
gtk_window_set_geometry_hints(window, NULL, &size, GDK_HINT_MAX_SIZE);
static void SetMinMaxSize(GtkWindow* window, int min_width, int min_height, int max_width, int max_height) {
GdkGeometry size;
size.min_width = size.min_height = size.max_width = size.max_height = 0;
int flags = GDK_HINT_MAX_SIZE | GDK_HINT_MIN_SIZE;
size.max_height = (max_height == 0 ? INT_MAX : max_height);
size.max_width = (max_width == 0 ? INT_MAX : max_width);
size.min_height = min_height;
size.min_width = min_width;
gtk_window_set_geometry_hints(window, NULL, &size, flags);
}
GdkRectangle getCurrentMonitorGeometry(GtkWindow *window) {
@@ -89,6 +80,13 @@ int IsFullscreen(GtkWidget *widget) {
return state & GDK_WINDOW_STATE_FULLSCREEN == GDK_WINDOW_STATE_FULLSCREEN;
}
int IsMaximised(GtkWidget *widget) {
GdkWindow *gdkwindow = gtk_widget_get_window(widget);
GdkWindowState state = gdk_window_get_state(GDK_WINDOW(gdkwindow));
return state & GDK_WINDOW_STATE_MAXIMIZED;
}
extern void processMessage(char*);
static void sendMessageToBackend(WebKitUserContentManager *contentManager,
@@ -120,6 +118,7 @@ ulong setupInvokeSignal(void* contentManager) {
float xroot = 0.0f;
float yroot = 0.0f;
int dragTime = -1;
bool contextMenuDisabled = false;
gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy)
{
@@ -128,12 +127,18 @@ gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy)
dragTime = -1;
return FALSE;
}
if( event->button == 3 && contextMenuDisabled ) {
return TRUE;
}
if (event->type == GDK_BUTTON_PRESS && event->button == 1)
{
xroot = event->x_root;
yroot = event->y_root;
dragTime = event->time;
}
return FALSE;
}
@@ -447,6 +452,38 @@ void SetPosition(void* window, int x, int y) {
ExecuteOnMainThread(setPosition, (gpointer)args);
}
void Show(gpointer data) {
gtk_widget_show((GtkWidget*)data);
}
void Hide(gpointer data) {
gtk_widget_hide((GtkWidget*)data);
}
void Maximise(gpointer data) {
gtk_window_maximize((GtkWindow*)data);
}
void UnMaximise(gpointer data) {
gtk_window_unmaximize((GtkWindow*)data);
}
void Minimise(gpointer data) {
gtk_window_iconify((GtkWindow*)data);
}
void UnMinimise(gpointer data) {
gtk_window_present((GtkWindow*)data);
}
bool disableContextMenu(GtkWindow* window) {
return TRUE;
}
void DisableContextMenu(void* webview) {
contextMenuDisabled = TRUE;
g_signal_connect(WEBKIT_WEB_VIEW(webview), "context-menu", G_CALLBACK(disableContextMenu), NULL);
}
*/
import "C"
@@ -466,15 +503,16 @@ func gtkBool(input bool) C.gboolean {
}
type Window struct {
appoptions *options.App
debug bool
gtkWindow unsafe.Pointer
contentManager unsafe.Pointer
webview unsafe.Pointer
applicationMenu *menu.Menu
menubar *C.GtkWidget
vbox *C.GtkWidget
accels *C.GtkAccelGroup
appoptions *options.App
debug bool
gtkWindow unsafe.Pointer
contentManager unsafe.Pointer
webview unsafe.Pointer
applicationMenu *menu.Menu
menubar *C.GtkWidget
vbox *C.GtkWidget
accels *C.GtkAccelGroup
minWidth, minHeight, maxWidth, maxHeight int
}
func bool2Cint(value bool) C.int {
@@ -489,6 +527,10 @@ func NewWindow(appoptions *options.App, debug bool) *Window {
result := &Window{
appoptions: appoptions,
debug: debug,
minHeight: appoptions.MinHeight,
minWidth: appoptions.MinWidth,
maxHeight: appoptions.MaxHeight,
maxWidth: appoptions.MaxWidth,
}
gtkWindow := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL)
@@ -512,6 +554,8 @@ func NewWindow(appoptions *options.App, debug bool) *Window {
if debug {
C.devtoolsEnabled(unsafe.Pointer(webview), C.int(1))
} else {
C.DisableContextMenu(unsafe.Pointer(webview))
}
// Set background colour
@@ -550,11 +594,17 @@ func (w *Window) cWebKitUserContentManager() *C.WebKitUserContentManager {
}
func (w *Window) Fullscreen() {
C.SetMinMaxSize(w.asGTKWindow(), C.int(0), C.int(0), C.int(0), C.int(0))
C.ExecuteOnMainThread(C.gtk_window_fullscreen, C.gpointer(w.asGTKWindow()))
}
func (w *Window) UnFullscreen() {
if !w.IsFullScreen() {
return
}
C.ExecuteOnMainThread(C.gtk_window_unfullscreen, C.gpointer(w.asGTKWindow()))
w.SetMinSize(w.minWidth, w.minHeight)
w.SetMaxSize(w.maxWidth, w.maxHeight)
}
func (w *Window) Destroy() {
@@ -587,35 +637,39 @@ func (w *Window) GetPosition() (int, int) {
}
func (w *Window) SetMaxSize(maxWidth int, maxHeight int) {
C.SetMaxSize(w.asGTKWindow(), C.int(maxWidth), C.int(maxHeight))
w.maxHeight = maxHeight
w.maxWidth = maxWidth
C.SetMinMaxSize(w.asGTKWindow(), C.int(w.minWidth), C.int(w.minHeight), C.int(w.maxWidth), C.int(w.maxHeight))
}
func (w *Window) SetMinSize(minWidth int, minHeight int) {
C.SetMinSize(w.asGTKWindow(), C.int(minWidth), C.int(minHeight))
w.minHeight = minHeight
w.minWidth = minWidth
C.SetMinMaxSize(w.asGTKWindow(), C.int(w.minWidth), C.int(w.minHeight), C.int(w.maxWidth), C.int(w.maxHeight))
}
func (w *Window) Show() {
C.gtk_widget_show(w.asGTKWidget())
C.ExecuteOnMainThread(C.Show, C.gpointer(w.asGTKWindow()))
}
func (w *Window) Hide() {
C.gtk_widget_hide(w.asGTKWidget())
C.ExecuteOnMainThread(C.Hide, C.gpointer(w.asGTKWindow()))
}
func (w *Window) Maximise() {
C.gtk_window_maximize(w.asGTKWindow())
C.ExecuteOnMainThread(C.Maximise, C.gpointer(w.asGTKWindow()))
}
func (w *Window) UnMaximise() {
C.gtk_window_unmaximize(w.asGTKWindow())
C.ExecuteOnMainThread(C.UnMaximise, C.gpointer(w.asGTKWindow()))
}
func (w *Window) Minimise() {
C.gtk_window_iconify(w.asGTKWindow())
C.ExecuteOnMainThread(C.Minimise, C.gpointer(w.asGTKWindow()))
}
func (w *Window) UnMinimise() {
C.gtk_window_present(w.asGTKWindow())
C.ExecuteOnMainThread(C.UnMinimise, C.gpointer(w.asGTKWindow()))
}
func (w *Window) IsFullScreen() bool {
@@ -626,6 +680,11 @@ func (w *Window) IsFullScreen() bool {
return false
}
func (w *Window) IsMaximised() bool {
result := C.IsMaximised(w.asGTKWidget())
return result > 0
}
func (w *Window) SetRGBA(r uint8, g uint8, b uint8, a uint8) {
data := C.RGBAOptions{
r: C.uchar(r),
@@ -766,3 +825,11 @@ func (w *Window) MessageDialog(dialogOptions frontend.MessageDialogOptions) {
}
C.ExecuteOnMainThread(C.messageDialog, C.gpointer(&data))
}
func (w *Window) ToggleMaximise() {
if w.IsMaximised() {
w.UnMaximise()
} else {
w.Maximise()
}
}
@@ -40,11 +40,10 @@ type Frontend struct {
startURL string
// main window handle
mainWindow *Window
minWidth, minHeight, maxWidth, maxHeight int
bindings *binding.Bindings
dispatcher frontend.Dispatcher
servingFromDisk bool
mainWindow *Window
bindings *binding.Bindings
dispatcher frontend.Dispatcher
servingFromDisk bool
hasStarted bool
}
@@ -57,10 +56,6 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
bindings: appBindings,
dispatcher: dispatcher,
ctx: ctx,
minHeight: appoptions.MinHeight,
minWidth: appoptions.MinWidth,
maxHeight: appoptions.MaxHeight,
maxWidth: appoptions.MaxWidth,
startURL: "file://wails/",
}
@@ -171,22 +166,18 @@ func (f *Frontend) WindowSetTitle(title string) {
func (f *Frontend) WindowFullscreen() {
runtime.LockOSThread()
f.mainWindow.SetMaxSize(0, 0)
f.mainWindow.SetMinSize(0, 0)
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = false;")
}
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnFullscreen() {
func (f *Frontend) WindowUnfullscreen() {
runtime.LockOSThread()
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = true;")
}
f.mainWindow.UnFullscreen()
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
}
func (f *Frontend) WindowShow() {
@@ -208,6 +199,18 @@ func (f *Frontend) WindowMaximise() {
f.frontendOptions.WindowStartState = options.Maximised
}
}
func (f *Frontend) WindowToggleMaximise() {
runtime.LockOSThread()
if !f.hasStarted {
return
}
if f.mainWindow.IsMaximised() {
f.WindowUnmaximise()
} else {
f.WindowMaximise()
}
}
func (f *Frontend) WindowUnmaximise() {
runtime.LockOSThread()
f.mainWindow.Restore()
@@ -227,14 +230,10 @@ func (f *Frontend) WindowUnminimise() {
func (f *Frontend) WindowSetMinSize(width int, height int) {
runtime.LockOSThread()
f.minWidth = width
f.minHeight = height
f.mainWindow.SetMinSize(width, height)
}
func (f *Frontend) WindowSetMaxSize(width int, height int) {
runtime.LockOSThread()
f.maxWidth = width
f.maxHeight = height
f.mainWindow.SetMaxSize(width, height)
}
@@ -473,7 +472,8 @@ func (f *Frontend) startDrag() error {
if !w32.ReleaseCapture() {
return fmt.Errorf("unable to release mouse capture")
}
w32.SendMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, w32.HTCAPTION, 0)
// Use PostMessage because we don't want to block the caller until dragging has been finished.
w32.PostMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, w32.HTCAPTION, 0)
return nil
}
@@ -481,7 +481,8 @@ func (f *Frontend) startResize(border uintptr) error {
if !w32.ReleaseCapture() {
return fmt.Errorf("unable to release mouse capture")
}
w32.SendMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, border, 0)
// Use PostMessage because we don't want to block the caller until resizing has been finished.
w32.PostMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, border, 0)
return nil
}
+82 -10
View File
@@ -16,14 +16,20 @@ import (
type Window struct {
winc.Form
frontendOptions *options.App
applicationMenu *menu.Menu
notifyParentWindowPositionChanged func() error
frontendOptions *options.App
applicationMenu *menu.Menu
notifyParentWindowPositionChanged func() error
minWidth, minHeight, maxWidth, maxHeight int
}
func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
result := new(Window)
result.frontendOptions = appoptions
result := &Window{
frontendOptions: appoptions,
minHeight: appoptions.MinHeight,
minWidth: appoptions.MinWidth,
maxHeight: appoptions.MaxHeight,
maxWidth: appoptions.MaxWidth,
}
result.SetIsForm(true)
var exStyle int
@@ -89,6 +95,33 @@ func (w *Window) Run() int {
return winc.RunMainLoop()
}
func (w *Window) Fullscreen() {
w.Form.SetMaxSize(0, 0)
w.Form.SetMinSize(0, 0)
w.Form.Fullscreen()
}
func (w *Window) UnFullscreen() {
if !w.IsFullScreen() {
return
}
w.Form.UnFullscreen()
w.SetMinSize(w.minWidth, w.minHeight)
w.SetMaxSize(w.maxWidth, w.maxHeight)
}
func (w *Window) SetMinSize(minWidth int, minHeight int) {
w.minWidth = minWidth
w.minHeight = minHeight
w.Form.SetMinSize(minWidth, minHeight)
}
func (w *Window) SetMaxSize(maxWidth int, maxHeight int) {
w.maxWidth = maxWidth
w.maxHeight = maxHeight
w.Form.SetMaxSize(maxWidth, maxHeight)
}
func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
@@ -98,17 +131,34 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
if w.notifyParentWindowPositionChanged != nil {
w.notifyParentWindowPositionChanged()
}
// TODO move WM_DPICHANGED handling into winc
case 0x02E0: //w32.WM_DPICHANGED
newWindowSize := (*w32.RECT)(unsafe.Pointer(lparam))
w32.SetWindowPos(w.Handle(),
uintptr(0),
int(newWindowSize.Left),
int(newWindowSize.Top),
int(newWindowSize.Right-newWindowSize.Left),
int(newWindowSize.Bottom-newWindowSize.Top),
w32.SWP_NOZORDER|w32.SWP_NOACTIVATE)
}
if w.frontendOptions.Frameless {
switch msg {
case w32.WM_ACTIVATE:
// If we want to have a frameless window but with border, extend the client area outside of the window. This
// Option is not affected by returning 0 in WM_NCCALCSIZE.
// As a result we have hidden the titlebar but still have the default border drawn.
// If we want to have a frameless window but with the default frame decorations, extend the DWM client area.
// This Option is not affected by returning 0 in WM_NCCALCSIZE.
// As a result we have hidden the titlebar but still have the default window frame styling.
// See: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea#remarks
if winoptions := w.frontendOptions.Windows; winoptions != nil && winoptions.EnableFramelessBorder {
if err := dwmExtendFrameIntoClientArea(w.Handle(), w32.MARGINS{-1, -1, -1, -1}); err != nil {
if winoptions := w.frontendOptions.Windows; winoptions == nil || !winoptions.DisableFramelessWindowDecorations {
// -1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11)
// Also shows the caption buttons if transparent ant translucent but they don't work.
// 0: Adds the default frame styling but no aero shadow, does not show the caption buttons.
// 1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11) but no caption buttons
// are shown if transparent ant translucent.
margins := w32.MARGINS{1, 1, 1, 1} // Only extend 1 pixel to have the default frame styling but no caption buttons
if err := dwmExtendFrameIntoClientArea(w.Handle(), margins); err != nil {
log.Fatal(fmt.Errorf("DwmExtendFrameIntoClientArea failed: %s", err))
}
}
@@ -130,6 +180,23 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
if w32.GetMonitorInfo(monitor, &monitorInfo) {
rgrc := (*w32.RECT)(unsafe.Pointer(lparam))
*rgrc = monitorInfo.RcWork
maxWidth := w.frontendOptions.MaxWidth
maxHeight := w.frontendOptions.MaxHeight
if maxWidth > 0 || maxHeight > 0 {
var dpiX, dpiY uint
w32.GetDPIForMonitor(monitor, w32.MDT_EFFECTIVE_DPI, &dpiX, &dpiY)
maxWidth := int32(winc.ScaleWithDPI(maxWidth, dpiX))
if maxWidth > 0 && rgrc.Right-rgrc.Left > maxWidth {
rgrc.Right = rgrc.Left + maxWidth
}
maxHeight := int32(winc.ScaleWithDPI(maxHeight, dpiY))
if maxHeight > 0 && rgrc.Bottom-rgrc.Top > maxHeight {
rgrc.Bottom = rgrc.Top + maxHeight
}
}
}
}
@@ -140,6 +207,11 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
return w.Form.WndProc(msg, wparam, lparam)
}
func (w *Window) IsMaximised() bool {
style := uint32(w32.GetWindowLong(w.Handle(), w32.GWL_STYLE))
return style&w32.WS_MAXIMIZE != 0
}
// TODO this should be put into the winc if we are happy with this solution.
var (
modkernel32 = syscall.NewLazyDLL("dwmapi.dll")
+10 -6
View File
@@ -187,6 +187,10 @@ func (d *DevWebServer) WindowMaximise() {
d.desktopFrontend.WindowMaximise()
}
func (d *DevWebServer) WindowToggleMaximise() {
d.desktopFrontend.WindowToggleMaximise()
}
func (d *DevWebServer) WindowUnmaximise() {
d.desktopFrontend.WindowUnmaximise()
}
@@ -227,8 +231,8 @@ func (d *DevWebServer) WindowFullscreen() {
d.desktopFrontend.WindowFullscreen()
}
func (d *DevWebServer) WindowUnFullscreen() {
d.desktopFrontend.WindowUnFullscreen()
func (d *DevWebServer) WindowUnfullscreen() {
d.desktopFrontend.WindowUnfullscreen()
}
func (d *DevWebServer) WindowSetRGBA(col *options.RGBA) {
@@ -304,7 +308,7 @@ func (d *DevWebServer) broadcast(message string) {
d.socketMutex.Lock()
defer d.socketMutex.Unlock()
for client, locker := range d.websocketClients {
go func() {
go func(client *websocket.Conn, locker *sync.Mutex) {
if client == nil {
d.logger.Error("Lost connection to websocket server")
return
@@ -317,7 +321,7 @@ func (d *DevWebServer) broadcast(message string) {
return
}
locker.Unlock()
}()
}(client, locker)
}
}
@@ -339,7 +343,7 @@ func (d *DevWebServer) broadcastExcludingSender(message string, sender *websocke
d.socketMutex.Lock()
defer d.socketMutex.Unlock()
for client, locker := range d.websocketClients {
go func() {
go func(client *websocket.Conn, locker *sync.Mutex) {
if client == sender {
return
}
@@ -351,7 +355,7 @@ func (d *DevWebServer) broadcastExcludingSender(message string, sender *websocke
return
}
locker.Unlock()
}()
}(client, locker)
}
}

Some files were not shown because too many files have changed in this diff Show More