mirror of
https://github.com/taigrr/wails.git
synced 2026-04-13 18:38:11 -07:00
Compare commits
2 Commits
419-encodi
...
Add-verbos
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3a13e5a0a | ||
|
|
5ea8287f1b |
6
.github/workflows/latest-pre.yml
vendored
6
.github/workflows/latest-pre.yml
vendored
@@ -13,10 +13,10 @@ jobs:
|
|||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.13
|
- name: Set up Go 1.12
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.13
|
go-version: 1.12
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
@@ -27,6 +27,6 @@ jobs:
|
|||||||
go get -v -d ./...
|
go get -v -d ./...
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./cmd/wails
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: ./wails version
|
run: ./wails version
|
||||||
|
|||||||
6
.github/workflows/pr.yml
vendored
6
.github/workflows/pr.yml
vendored
@@ -13,10 +13,10 @@ jobs:
|
|||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.13
|
- name: Set up Go 1.12
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.13
|
go-version: 1.12
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
@@ -27,6 +27,6 @@ jobs:
|
|||||||
go get -v -d ./...
|
go get -v -d ./...
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./cmd/wails
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: ./wails version
|
run: ./wails version
|
||||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -4,7 +4,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
tags:
|
tags:
|
||||||
- '!**pre**'
|
- '!**pre**'
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@@ -15,10 +15,10 @@ jobs:
|
|||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.13
|
- name: Set up Go 1.12
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.13
|
go-version: 1.12
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
@@ -29,6 +29,6 @@ jobs:
|
|||||||
go get -v -d ./...
|
go get -v -d ./...
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./cmd/wails
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: ./wails version
|
run: ./wails version
|
||||||
@@ -15,19 +15,11 @@ Wails is what it is because of the time and effort given by these great people.
|
|||||||
* [admin_3.exe](https://github.com/bh90210)
|
* [admin_3.exe](https://github.com/bh90210)
|
||||||
* [iceleo-com](https://github.com/iceleo-com)
|
* [iceleo-com](https://github.com/iceleo-com)
|
||||||
* [fallendusk](https://github.com/fallendusk)
|
* [fallendusk](https://github.com/fallendusk)
|
||||||
|
* [Florian Didran](https://github.com/fdidron)
|
||||||
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
||||||
* [Toyam Cox](https://github.com/Vaelatern)
|
* [Toyam Cox](https://github.com/Vaelatern)
|
||||||
* [Robin Eklind](https://github.com/mewmew)
|
* [Robin Eklind](https://github.com/mewmew)
|
||||||
* [Kris Raney](https://github.com/kraney)
|
* [Kris Raney](https://github.com/kraney)
|
||||||
* [Jack Mordaunt](https://github.com/JackMordaunt)
|
* [Jack Mordaunt](https://github.com/JackMordaunt)
|
||||||
* [Michael Hipp](https://github.com/MichaelHipp)
|
* [Michael Hipp](https://github.com/MichaelHipp)
|
||||||
* [Travis McLane](https://github.com/tmclane)
|
* [Travis McLane](https://github.com/tmclane)
|
||||||
* [Reuben Thomas-Davis](https://github.com/Rested)
|
|
||||||
* [Jarek](https://github.com/Jarek-SRT)
|
|
||||||
* [Konez2k](https://github.com/konez2k)
|
|
||||||
* [msms](https://github.com/sayuthisobri)
|
|
||||||
* [dedo1911](https://github.com/dedo1911)
|
|
||||||
* [Florian Didron](https://github.com/fdidron)
|
|
||||||
* [Christopher Murphy](https://github.com/Splode)
|
|
||||||
* [Zámbó, Levente](https://github.com/Lyimmi)
|
|
||||||
* [artem](https://github.com/Unix4ever)
|
|
||||||
@@ -36,7 +36,7 @@ The official docs can be found at [https://wails.app](https://wails.app).
|
|||||||
|
|
||||||
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
|
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
|
||||||
|
|
||||||
- Go 1.13
|
- Go 1.12
|
||||||
- npm
|
- npm
|
||||||
|
|
||||||
### MacOS
|
### MacOS
|
||||||
@@ -55,9 +55,9 @@ _Debian: 8, 9, 10_
|
|||||||
|
|
||||||
_Ubuntu: 16.04, 18.04, 19.04_
|
_Ubuntu: 16.04, 18.04, 19.04_
|
||||||
|
|
||||||
_Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neon_, Pop!_OS
|
_Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neon_
|
||||||
|
|
||||||
#### Arch Linux / ArchLabs
|
#### Arch Linux
|
||||||
|
|
||||||
`sudo pacman -S webkit2gtk gtk3`
|
`sudo pacman -S webkit2gtk gtk3`
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// +build linux darwin !windows
|
// +build +linux +darwin !windows
|
||||||
|
|
||||||
package wails
|
package wails
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
21
cmd/fs.go
21
cmd/fs.go
@@ -12,7 +12,6 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
)
|
)
|
||||||
@@ -48,22 +47,6 @@ func (fs *FSHelper) FileExists(path string) bool {
|
|||||||
return fi.Mode().IsRegular()
|
return fi.Mode().IsRegular()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindFile returns the first occurrence of match inside path.
|
|
||||||
func (fs *FSHelper) FindFile(path, match string) (string, error) {
|
|
||||||
files, err := ioutil.ReadDir(path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range files {
|
|
||||||
if !f.IsDir() && strings.Contains(f.Name(), match) {
|
|
||||||
return f.Name(), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", fmt.Errorf("file not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateFile creates a file at the given filename location with the contents
|
// CreateFile creates a file at the given filename location with the contents
|
||||||
// set to the given data. It will create intermediary directories if needed.
|
// set to the given data. It will create intermediary directories if needed.
|
||||||
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
||||||
@@ -117,10 +100,10 @@ func (fs *FSHelper) RemoveFile(filename string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFiles removes the given filenames
|
// RemoveFiles removes the given filenames
|
||||||
func (fs *FSHelper) RemoveFiles(files []string, continueOnError bool) error {
|
func (fs *FSHelper) RemoveFiles(files []string) error {
|
||||||
for _, filename := range files {
|
for _, filename := range files {
|
||||||
err := os.Remove(filename)
|
err := os.Remove(filename)
|
||||||
if err != nil && !continueOnError {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
287
cmd/helpers.go
287
cmd/helpers.go
@@ -5,15 +5,12 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/leaanthony/mewn"
|
"github.com/leaanthony/mewn"
|
||||||
"github.com/leaanthony/mewn/lib"
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
)
|
)
|
||||||
@@ -59,141 +56,21 @@ func InstallGoDependencies(verbose bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmbedAssets will embed the built frontend assets via mewn.
|
// BuildApplication will attempt to build the project based on the given inputs
|
||||||
func EmbedAssets() ([]string, error) {
|
func BuildApplication(binaryName string, forceRebuild bool, buildMode string, packageApp bool, projectOptions *ProjectOptions) error {
|
||||||
mewnFiles := lib.GetMewnFiles([]string{}, false)
|
|
||||||
|
|
||||||
referencedAssets, err := lib.GetReferencedAssets(mewnFiles)
|
// Generate Windows assets if needed
|
||||||
if err != nil {
|
if runtime.GOOS == "windows" {
|
||||||
return []string{}, err
|
cleanUp := !packageApp
|
||||||
}
|
err := NewPackageHelper().PackageWindows(projectOptions, cleanUp)
|
||||||
|
|
||||||
targetFiles := []string{}
|
|
||||||
|
|
||||||
for _, referencedAsset := range referencedAssets {
|
|
||||||
packfileData, err := lib.GeneratePackFileString(referencedAsset, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, err
|
return err
|
||||||
}
|
}
|
||||||
targetFile := filepath.Join(referencedAsset.BaseDir, referencedAsset.PackageName+"-mewn.go")
|
|
||||||
targetFiles = append(targetFiles, targetFile)
|
|
||||||
ioutil.WriteFile(targetFile, []byte(packfileData), 0644)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetFiles, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitializeCrossCompilation(verbose bool) error {
|
|
||||||
// Check Docker
|
|
||||||
if err := CheckIfInstalled("docker"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var packSpinner *spinner.Spinner
|
|
||||||
if !verbose {
|
|
||||||
packSpinner = spinner.New("Pulling wailsapp/xgo:latest docker image... (may take a while)")
|
|
||||||
packSpinner.SetSpinSpeed(50)
|
|
||||||
packSpinner.Start()
|
|
||||||
} else {
|
|
||||||
println("Pulling wailsapp/xgo:latest docker image... (may take a while)")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := NewProgramHelper(verbose).RunCommandArray([]string{"docker",
|
|
||||||
"pull", "wailsapp/xgo:latest"})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if packSpinner != nil {
|
|
||||||
packSpinner.Error()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if packSpinner != nil {
|
|
||||||
packSpinner.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildDocker builds the project using the cross compiling wailsapp/xgo:latest container
|
|
||||||
func BuildDocker(binaryName string, buildMode string, projectOptions *ProjectOptions) error {
|
|
||||||
var packSpinner *spinner.Spinner
|
|
||||||
if buildMode == BuildModeBridge {
|
|
||||||
return fmt.Errorf("you cant serve the application in cross-compilation")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check build directory
|
|
||||||
buildDirectory := filepath.Join(fs.Cwd(), "build")
|
|
||||||
if !fs.DirExists(buildDirectory) {
|
|
||||||
fs.MkDir(buildDirectory)
|
|
||||||
}
|
|
||||||
|
|
||||||
buildCommand := slicer.String()
|
|
||||||
userid := 1000
|
|
||||||
user, _ := user.Current()
|
|
||||||
if i, err := strconv.Atoi(user.Uid); err == nil {
|
|
||||||
userid = i
|
|
||||||
}
|
|
||||||
for _, arg := range []string{
|
|
||||||
"docker",
|
|
||||||
"run",
|
|
||||||
"--rm",
|
|
||||||
"-v", fmt.Sprintf("%s:/build", filepath.Join(fs.Cwd(), "build")),
|
|
||||||
"-v", fmt.Sprintf("%s:/source", fs.Cwd()),
|
|
||||||
"-e", fmt.Sprintf("LOCAL_USER_ID=%v", userid),
|
|
||||||
"-e", fmt.Sprintf("FLAG_LDFLAGS=%s", ldFlags(projectOptions, buildMode)),
|
|
||||||
"-e", "FLAG_V=false",
|
|
||||||
"-e", "FLAG_X=false",
|
|
||||||
"-e", "FLAG_RACE=false",
|
|
||||||
"-e", "FLAG_BUILDMODE=default",
|
|
||||||
"-e", "FLAG_TRIMPATH=false",
|
|
||||||
"-e", fmt.Sprintf("TARGETS=%s", projectOptions.Platform+"/"+projectOptions.Architecture),
|
|
||||||
"-e", "GOPROXY=",
|
|
||||||
"-e", "GO111MODULE=on",
|
|
||||||
"wailsapp/xgo:latest",
|
|
||||||
".",
|
|
||||||
} {
|
|
||||||
buildCommand.Add(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
compileMessage := fmt.Sprintf(
|
|
||||||
"Packing + Compiling project for %s/%s using docker image wailsapp/xgo:latest",
|
|
||||||
projectOptions.Platform, projectOptions.Architecture)
|
|
||||||
|
|
||||||
if buildMode == BuildModeDebug {
|
|
||||||
compileMessage += " (Debug Mode)"
|
|
||||||
}
|
|
||||||
|
|
||||||
if !projectOptions.Verbose {
|
|
||||||
packSpinner = spinner.New(compileMessage + "...")
|
|
||||||
packSpinner.SetSpinSpeed(50)
|
|
||||||
packSpinner.Start()
|
|
||||||
} else {
|
|
||||||
println(compileMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := NewProgramHelper(projectOptions.Verbose).RunCommandArray(buildCommand.AsSlice())
|
|
||||||
if err != nil {
|
|
||||||
if packSpinner != nil {
|
|
||||||
packSpinner.Error()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if packSpinner != nil {
|
|
||||||
packSpinner.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildNative builds on the target platform itself.
|
|
||||||
func BuildNative(binaryName string, forceRebuild bool, buildMode string, projectOptions *ProjectOptions) error {
|
|
||||||
|
|
||||||
// Check Mewn is installed
|
// Check Mewn is installed
|
||||||
if err := CheckMewn(projectOptions.Verbose); err != nil {
|
err := CheckMewn(projectOptions.Verbose)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
if err := CheckWindres(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,17 +90,18 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildCommand := slicer.String()
|
buildCommand := slicer.String()
|
||||||
buildCommand.Add("go")
|
buildCommand.Add("mewn")
|
||||||
|
|
||||||
buildCommand.Add("build")
|
|
||||||
if buildMode == BuildModeBridge {
|
if buildMode == BuildModeBridge {
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
buildCommand.Add("-i")
|
buildCommand.Add("-i")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildCommand.Add("build")
|
||||||
|
|
||||||
if binaryName != "" {
|
if binaryName != "" {
|
||||||
// Alter binary name based on OS
|
// Alter binary name based on OS
|
||||||
switch projectOptions.Platform {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
if !strings.HasSuffix(binaryName, ".exe") {
|
if !strings.HasSuffix(binaryName, ".exe") {
|
||||||
binaryName += ".exe"
|
binaryName += ".exe"
|
||||||
@@ -233,7 +111,7 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
|
|||||||
binaryName = strings.TrimSuffix(binaryName, ".exe")
|
binaryName = strings.TrimSuffix(binaryName, ".exe")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildCommand.Add("-o", filepath.Join("build", binaryName))
|
buildCommand.Add("-o", binaryName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are forcing a rebuild
|
// If we are forcing a rebuild
|
||||||
@@ -241,13 +119,31 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
|
|||||||
buildCommand.Add("-a")
|
buildCommand.Add("-a")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCommand.AddSlice([]string{"-ldflags", ldFlags(projectOptions, buildMode)})
|
// Setup ld flags
|
||||||
|
ldflags := "-w -s "
|
||||||
if projectOptions.Verbose {
|
if buildMode == BuildModeDebug {
|
||||||
fmt.Printf("Command: %v\n", buildCommand.AsSlice())
|
ldflags = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
err := NewProgramHelper(projectOptions.Verbose).RunCommandArray(buildCommand.AsSlice())
|
// Add windows flags
|
||||||
|
if runtime.GOOS == "windows" && buildMode == BuildModeProd {
|
||||||
|
ldflags += "-H windowsgui "
|
||||||
|
}
|
||||||
|
|
||||||
|
ldflags += "-X github.com/wailsapp/wails.BuildMode=" + buildMode
|
||||||
|
|
||||||
|
// If we wish to generate typescript
|
||||||
|
if projectOptions.typescriptDefsFilename != "" {
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
filename := filepath.Join(cwd, projectOptions.FrontEnd.Dir, projectOptions.typescriptDefsFilename)
|
||||||
|
ldflags += " -X github.com/wailsapp/wails/lib/binding.typescriptDefinitionFilename=" + filename
|
||||||
|
}
|
||||||
|
|
||||||
|
buildCommand.AddSlice([]string{"-ldflags", ldflags})
|
||||||
|
err = NewProgramHelper(projectOptions.Verbose).RunCommandArray(buildCommand.AsSlice())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if packSpinner != nil {
|
if packSpinner != nil {
|
||||||
packSpinner.Error()
|
packSpinner.Error()
|
||||||
@@ -258,57 +154,7 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
|
|||||||
packSpinner.Success()
|
packSpinner.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// packageApp
|
||||||
}
|
|
||||||
|
|
||||||
// BuildApplication will attempt to build the project based on the given inputs
|
|
||||||
func BuildApplication(binaryName string, forceRebuild bool, buildMode string, packageApp bool, projectOptions *ProjectOptions) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// embed resources
|
|
||||||
targetFiles, err := EmbedAssets()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if projectOptions.CrossCompile {
|
|
||||||
if err := InitializeCrossCompilation(projectOptions.Verbose); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
helper := NewPackageHelper(projectOptions.Platform)
|
|
||||||
|
|
||||||
// Generate windows resources
|
|
||||||
if projectOptions.Platform == "windows" {
|
|
||||||
if err := helper.PackageWindows(projectOptions, false); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup temporary embedded assets
|
|
||||||
defer func() {
|
|
||||||
for _, filename := range targetFiles {
|
|
||||||
if err := os.Remove(filename); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Removed by popular demand
|
|
||||||
// TODO: Potentially add a flag to cleanup
|
|
||||||
// if projectOptions.Platform == "windows" {
|
|
||||||
// helper.CleanWindows(projectOptions)
|
|
||||||
// }
|
|
||||||
}()
|
|
||||||
|
|
||||||
if projectOptions.CrossCompile {
|
|
||||||
err = BuildDocker(binaryName, buildMode, projectOptions)
|
|
||||||
} else {
|
|
||||||
err = BuildNative(binaryName, forceRebuild, buildMode, projectOptions)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if packageApp {
|
if packageApp {
|
||||||
err = PackageApplication(projectOptions)
|
err = PackageApplication(projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -321,14 +167,22 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
|
|
||||||
// PackageApplication will attempt to package the application in a platform dependent way
|
// PackageApplication will attempt to package the application in a platform dependent way
|
||||||
func PackageApplication(projectOptions *ProjectOptions) error {
|
func PackageApplication(projectOptions *ProjectOptions) error {
|
||||||
|
// Package app
|
||||||
|
message := "Generating .app"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
err := CheckWindres()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
message = "Generating resource bundle"
|
||||||
|
}
|
||||||
var packageSpinner *spinner.Spinner
|
var packageSpinner *spinner.Spinner
|
||||||
if projectOptions.Verbose {
|
if projectOptions.Verbose {
|
||||||
packageSpinner = spinner.New("Packaging application...")
|
packageSpinner = spinner.New(message)
|
||||||
packageSpinner.SetSpinSpeed(50)
|
packageSpinner.SetSpinSpeed(50)
|
||||||
packageSpinner.Start()
|
packageSpinner.Start()
|
||||||
}
|
}
|
||||||
|
err := NewPackageHelper().Package(projectOptions)
|
||||||
err := NewPackageHelper(projectOptions.Platform).Package(projectOptions)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if packageSpinner != nil {
|
if packageSpinner != nil {
|
||||||
packageSpinner.Error()
|
packageSpinner.Error()
|
||||||
@@ -390,7 +244,7 @@ func CheckMewn(verbose bool) (err error) {
|
|||||||
|
|
||||||
// CheckWindres checks if Windres is installed and if not, aborts
|
// CheckWindres checks if Windres is installed and if not, aborts
|
||||||
func CheckWindres() (err error) {
|
func CheckWindres() (err error) {
|
||||||
if runtime.GOOS != "windows" { // FIXME: Handle windows cross-compile for windows!
|
if runtime.GOOS != "windows" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
programHelper := NewProgramHelper()
|
programHelper := NewProgramHelper()
|
||||||
@@ -400,15 +254,6 @@ func CheckWindres() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckIfInstalled returns if application is installed
|
|
||||||
func CheckIfInstalled(application string) (err error) {
|
|
||||||
programHelper := NewProgramHelper()
|
|
||||||
if !programHelper.IsInstalled(application) {
|
|
||||||
return fmt.Errorf("%s not installed. Ensure you have installed %s correctly", application, application)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstallFrontendDeps attempts to install the frontend dependencies based on the given options
|
// InstallFrontendDeps attempts to install the frontend dependencies based on the given options
|
||||||
func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forceRebuild bool, caller string) error {
|
func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forceRebuild bool, caller string) error {
|
||||||
|
|
||||||
@@ -532,7 +377,7 @@ func ServeProject(projectOptions *ProjectOptions, logger *Logger) error {
|
|||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<")
|
logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<")
|
||||||
}()
|
}()
|
||||||
location, err := filepath.Abs(filepath.Join("build", projectOptions.BinaryName))
|
location, err := filepath.Abs(projectOptions.BinaryName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -548,33 +393,3 @@ func ServeProject(projectOptions *ProjectOptions, logger *Logger) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldFlags(po *ProjectOptions, buildMode string) string {
|
|
||||||
// Setup ld flags
|
|
||||||
ldflags := "-w -s "
|
|
||||||
if buildMode == BuildModeDebug {
|
|
||||||
ldflags = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add windows flags
|
|
||||||
if po.Platform == "windows" && buildMode == BuildModeProd {
|
|
||||||
ldflags += "-H windowsgui "
|
|
||||||
}
|
|
||||||
|
|
||||||
ldflags += "-X github.com/wailsapp/wails.BuildMode=" + buildMode
|
|
||||||
|
|
||||||
// Add additional ldflags passed in via the `ldflags` cli flag
|
|
||||||
if len(po.LdFlags) > 0 {
|
|
||||||
ldflags += " " + po.LdFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we wish to generate typescript
|
|
||||||
if po.typescriptDefsFilename != "" {
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
if err == nil {
|
|
||||||
filename := filepath.Join(cwd, po.FrontEnd.Dir, po.typescriptDefsFilename)
|
|
||||||
ldflags += " -X github.com/wailsapp/wails/lib/binding.typescriptDefinitionFilename=" + filename
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ldflags
|
|
||||||
}
|
|
||||||
|
|||||||
37
cmd/linux.go
37
cmd/linux.go
@@ -53,16 +53,6 @@ const (
|
|||||||
Deepin
|
Deepin
|
||||||
// Raspbian distribution
|
// Raspbian distribution
|
||||||
Raspbian
|
Raspbian
|
||||||
// Tumbleweed (OpenSUSE) distribution
|
|
||||||
Tumbleweed
|
|
||||||
// Leap (OpenSUSE) distribution
|
|
||||||
Leap
|
|
||||||
// ArchLabs distribution
|
|
||||||
ArchLabs
|
|
||||||
// PopOS distribution
|
|
||||||
PopOS
|
|
||||||
// Solus distribution
|
|
||||||
Solus
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DistroInfo contains all the information relating to a linux distribution
|
// DistroInfo contains all the information relating to a linux distribution
|
||||||
@@ -111,7 +101,7 @@ func parseOsRelease(osRelease string) *DistroInfo {
|
|||||||
}
|
}
|
||||||
switch splitLine[0] {
|
switch splitLine[0] {
|
||||||
case "ID":
|
case "ID":
|
||||||
osID = strings.ToLower(strings.Trim(splitLine[1], "\""))
|
osID = strings.Trim(splitLine[1], "\"")
|
||||||
case "NAME":
|
case "NAME":
|
||||||
osNAME = strings.Trim(splitLine[1], "\"")
|
osNAME = strings.Trim(splitLine[1], "\"")
|
||||||
case "VERSION_ID":
|
case "VERSION_ID":
|
||||||
@@ -127,8 +117,6 @@ func parseOsRelease(osRelease string) *DistroInfo {
|
|||||||
result.Distribution = CentOS
|
result.Distribution = CentOS
|
||||||
case "arch":
|
case "arch":
|
||||||
result.Distribution = Arch
|
result.Distribution = Arch
|
||||||
case "archlabs":
|
|
||||||
result.Distribution = ArchLabs
|
|
||||||
case "debian":
|
case "debian":
|
||||||
result.Distribution = Debian
|
result.Distribution = Debian
|
||||||
case "ubuntu":
|
case "ubuntu":
|
||||||
@@ -159,14 +147,6 @@ func parseOsRelease(osRelease string) *DistroInfo {
|
|||||||
result.Distribution = Deepin
|
result.Distribution = Deepin
|
||||||
case "raspbian":
|
case "raspbian":
|
||||||
result.Distribution = Raspbian
|
result.Distribution = Raspbian
|
||||||
case "opensuse-tumbleweed":
|
|
||||||
result.Distribution = Tumbleweed
|
|
||||||
case "opensuse-leap":
|
|
||||||
result.Distribution = Leap
|
|
||||||
case "pop":
|
|
||||||
result.Distribution = PopOS
|
|
||||||
case "solus":
|
|
||||||
result.Distribution = Solus
|
|
||||||
default:
|
default:
|
||||||
result.Distribution = Unknown
|
result.Distribution = Unknown
|
||||||
}
|
}
|
||||||
@@ -203,17 +183,6 @@ func DpkgInstalled(packageName string) (bool, error) {
|
|||||||
return exitCode == 0, nil
|
return exitCode == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOpkgInstalled uses dpkg to see if a package is installed
|
|
||||||
func EOpkgInstalled(packageName string) (bool, error) {
|
|
||||||
program := NewProgramHelper()
|
|
||||||
eopkg := program.FindProgram("eopkg")
|
|
||||||
if eopkg == nil {
|
|
||||||
return false, fmt.Errorf("cannot check dependencies: eopkg not found")
|
|
||||||
}
|
|
||||||
stdout, _, _, _ := eopkg.Run("info", packageName)
|
|
||||||
return strings.HasPrefix(stdout, "Installed"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PacmanInstalled uses pacman to see if a package is installed.
|
// PacmanInstalled uses pacman to see if a package is installed.
|
||||||
func PacmanInstalled(packageName string) (bool, error) {
|
func PacmanInstalled(packageName string) (bool, error) {
|
||||||
program := NewProgramHelper()
|
program := NewProgramHelper()
|
||||||
@@ -285,9 +254,5 @@ func RequestSupportForDistribution(distroInfo *DistroInfo) error {
|
|||||||
|
|
||||||
fmt.Println("Opening browser to file request.")
|
fmt.Println("Opening browser to file request.")
|
||||||
browser.OpenURL(fullURL + url.PathEscape(params))
|
browser.OpenURL(fullURL + url.PathEscape(params))
|
||||||
result = Prompt("We have a guide for adding support for your distribution. Would you like to view it?", "yes")
|
|
||||||
if strings.ToLower(result) == "yes" {
|
|
||||||
browser.OpenURL("https://wails.app/guides/distro/")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,25 +22,5 @@ UBUNTU_CODENAME=bionic
|
|||||||
if result.Distribution != Ubuntu {
|
if result.Distribution != Ubuntu {
|
||||||
t.Errorf("expected 'Ubuntu' ID but got '%d'", result.Distribution)
|
t.Errorf("expected 'Ubuntu' ID but got '%d'", result.Distribution)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func TestTumbleweedDetection(t *testing.T) {
|
|
||||||
osrelease := `
|
|
||||||
NAME="openSUSE Tumbleweed"
|
|
||||||
# VERSION="20200414"
|
|
||||||
ID="opensuse-tumbleweed"
|
|
||||||
ID_LIKE="opensuse suse"
|
|
||||||
VERSION_ID="20200414"
|
|
||||||
PRETTY_NAME="openSUSE Tumbleweed"
|
|
||||||
ANSI_COLOR="0;32"
|
|
||||||
CPE_NAME="cpe:/o:opensuse:tumbleweed:20200414"
|
|
||||||
BUG_REPORT_URL="https://bugs.opensuse.org"
|
|
||||||
HOME_URL="https://www.opensuse.org/"
|
|
||||||
LOGO="distributor-logo"
|
|
||||||
`
|
|
||||||
|
|
||||||
result := parseOsRelease(osrelease)
|
|
||||||
if result.Distribution != Tumbleweed {
|
|
||||||
t.Errorf("expected 'Tumbleweed' ID but got '%d'", result.Distribution)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,6 @@ distributions:
|
|||||||
gccversioncommand: &gccdumpfullversion -dumpfullversion
|
gccversioncommand: &gccdumpfullversion -dumpfullversion
|
||||||
programs: *debiandefaultprograms
|
programs: *debiandefaultprograms
|
||||||
libraries: *debiandefaultlibraries
|
libraries: *debiandefaultlibraries
|
||||||
pop:
|
|
||||||
id: pop
|
|
||||||
releases:
|
|
||||||
default:
|
|
||||||
version: default
|
|
||||||
name: Pop!_OS
|
|
||||||
gccversioncommand: &gccdumpfullversion -dumpfullversion
|
|
||||||
programs: *debiandefaultprograms
|
|
||||||
libraries: *debiandefaultlibraries
|
|
||||||
kali:
|
kali:
|
||||||
id: kali
|
id: kali
|
||||||
releases:
|
releases:
|
||||||
@@ -185,15 +176,6 @@ distributions:
|
|||||||
gccversioncommand: *gccdumpversion
|
gccversioncommand: *gccdumpversion
|
||||||
programs: *archdefaultprograms
|
programs: *archdefaultprograms
|
||||||
libraries: *archdefaultlibraries
|
libraries: *archdefaultlibraries
|
||||||
archlabs:
|
|
||||||
id: archlabs
|
|
||||||
releases:
|
|
||||||
default:
|
|
||||||
version: default
|
|
||||||
name: ArchLabs
|
|
||||||
gccversioncommand: *gccdumpversion
|
|
||||||
programs: *archdefaultprograms
|
|
||||||
libraries: *archdefaultlibraries
|
|
||||||
manjaro:
|
manjaro:
|
||||||
id: manjaro
|
id: manjaro
|
||||||
releases:
|
releases:
|
||||||
@@ -241,51 +223,3 @@ distributions:
|
|||||||
gccversioncommand: *gccdumpfullversion
|
gccversioncommand: *gccdumpfullversion
|
||||||
programs: *debiandefaultprograms
|
programs: *debiandefaultprograms
|
||||||
libraries: *debiandefaultlibraries
|
libraries: *debiandefaultlibraries
|
||||||
solus:
|
|
||||||
id: solus
|
|
||||||
releases:
|
|
||||||
default:
|
|
||||||
version: default
|
|
||||||
name: Solus
|
|
||||||
gccversioncommand: *gccdumpfullversion
|
|
||||||
programs: &solusdefaultprograms
|
|
||||||
- name: gcc
|
|
||||||
help: Please install with `sudo eopkg it -c system.devel` and try again
|
|
||||||
- name: pkg-config
|
|
||||||
help: Please install with `sudo eopkg it -c system.devel` and try again
|
|
||||||
- name: npm
|
|
||||||
help: Please install with `sudo eopkg it nodejs` and try again
|
|
||||||
libraries: &solusdefaultlibraries
|
|
||||||
- name: libgtk-3-devel
|
|
||||||
help: Please install with `sudo eopkg it libgtk-3-devel` and try again
|
|
||||||
- name: libwebkit-gtk-devel
|
|
||||||
help: Please install with `sudo eopkg it libwebkit-gtk-devel` and try again
|
|
||||||
|
|
||||||
opensuse-tumbleweed:
|
|
||||||
id: opensuse-tumbleweed
|
|
||||||
releases:
|
|
||||||
default:
|
|
||||||
version: default
|
|
||||||
name: openSUSE Tumbleweed
|
|
||||||
gccversioncommand: *gccdumpfullversion
|
|
||||||
programs: &opensusedefaultprograms
|
|
||||||
- name: gcc
|
|
||||||
help: Please install with `sudo zypper in gcc-c++` and try again
|
|
||||||
- name: pkg-config
|
|
||||||
help: Please install with `sudo zypper in pkgconf-pkg-config` and try again
|
|
||||||
- name: npm
|
|
||||||
help: Please install `sudo zypper in nodejs` and try again
|
|
||||||
libraries: &opensusedefaultlibraries
|
|
||||||
- name: gtk3-devel
|
|
||||||
help: Please install with `sudo zypper in gtk3-devel` and try again
|
|
||||||
- name: webkit2gtk3-devel
|
|
||||||
help: Please install with `sudo zypper in webkit2gtk3-devel` and try again
|
|
||||||
opensuse-leap:
|
|
||||||
id: opensuse-leap
|
|
||||||
releases:
|
|
||||||
default:
|
|
||||||
version: default
|
|
||||||
name: openSUSE Leap
|
|
||||||
gccversioncommand: *gccdumpfullversion
|
|
||||||
programs: *opensusedefaultprograms
|
|
||||||
libraries: *opensusedefaultlibraries
|
|
||||||
|
|||||||
240
cmd/package.go
240
cmd/package.go
@@ -1,12 +1,9 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/png"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -17,24 +14,21 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackmordaunt/icns"
|
"github.com/jackmordaunt/icns"
|
||||||
"golang.org/x/image/draw"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageHelper helps with the 'wails package' command
|
// PackageHelper helps with the 'wails package' command
|
||||||
type PackageHelper struct {
|
type PackageHelper struct {
|
||||||
platform string
|
fs *FSHelper
|
||||||
fs *FSHelper
|
log *Logger
|
||||||
log *Logger
|
system *SystemHelper
|
||||||
system *SystemHelper
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPackageHelper creates a new PackageHelper!
|
// NewPackageHelper creates a new PackageHelper!
|
||||||
func NewPackageHelper(platform string) *PackageHelper {
|
func NewPackageHelper() *PackageHelper {
|
||||||
return &PackageHelper{
|
return &PackageHelper{
|
||||||
platform: platform,
|
fs: NewFSHelper(),
|
||||||
fs: NewFSHelper(),
|
log: NewLogger(),
|
||||||
log: NewLogger(),
|
system: NewSystemHelper(),
|
||||||
system: NewSystemHelper(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,111 +53,6 @@ func newPlistData(title, exe, packageID, version, author string) *plistData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type windowsIcoHeader struct {
|
|
||||||
_ uint16
|
|
||||||
imageType uint16
|
|
||||||
imageCount uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type windowsIcoDescriptor struct {
|
|
||||||
width uint8
|
|
||||||
height uint8
|
|
||||||
colours uint8
|
|
||||||
_ uint8
|
|
||||||
planes uint16
|
|
||||||
bpp uint16
|
|
||||||
size uint32
|
|
||||||
offset uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type windowsIcoContainer struct {
|
|
||||||
Header windowsIcoDescriptor
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateWindowsIcon(pngFilename string, iconfile string) error {
|
|
||||||
sizes := []int{256, 128, 64, 48, 32, 16}
|
|
||||||
|
|
||||||
pngfile, err := os.Open(pngFilename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer pngfile.Close()
|
|
||||||
|
|
||||||
pngdata, err := png.Decode(pngfile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
icons := []windowsIcoContainer{}
|
|
||||||
|
|
||||||
for _, size := range sizes {
|
|
||||||
rect := image.Rect(0, 0, int(size), int(size))
|
|
||||||
rawdata := image.NewRGBA(rect)
|
|
||||||
scale := draw.CatmullRom
|
|
||||||
scale.Scale(rawdata, rect, pngdata, pngdata.Bounds(), draw.Over, nil)
|
|
||||||
|
|
||||||
icondata := new(bytes.Buffer)
|
|
||||||
writer := bufio.NewWriter(icondata)
|
|
||||||
err = png.Encode(writer, rawdata)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
imgSize := size
|
|
||||||
if imgSize >= 256 {
|
|
||||||
imgSize = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
data := icondata.Bytes()
|
|
||||||
|
|
||||||
icn := windowsIcoContainer{
|
|
||||||
Header: windowsIcoDescriptor{
|
|
||||||
width: uint8(imgSize),
|
|
||||||
height: uint8(imgSize),
|
|
||||||
planes: 1,
|
|
||||||
bpp: 32,
|
|
||||||
size: uint32(len(data)),
|
|
||||||
},
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
icons = append(icons, icn)
|
|
||||||
}
|
|
||||||
|
|
||||||
outfile, err := os.Create(iconfile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer outfile.Close()
|
|
||||||
|
|
||||||
ico := windowsIcoHeader{
|
|
||||||
imageType: 1,
|
|
||||||
imageCount: uint16(len(sizes)),
|
|
||||||
}
|
|
||||||
err = binary.Write(outfile, binary.LittleEndian, ico)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := uint32(6 + 16*len(sizes))
|
|
||||||
for _, icon := range icons {
|
|
||||||
icon.Header.offset = offset
|
|
||||||
err = binary.Write(outfile, binary.LittleEndian, icon.Header)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
offset += icon.Header.size
|
|
||||||
}
|
|
||||||
for _, icon := range icons {
|
|
||||||
_, err = outfile.Write(icon.Data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultString(val string, defaultVal string) string {
|
func defaultString(val string, defaultVal string) string {
|
||||||
if val != "" {
|
if val != "" {
|
||||||
return val
|
return val
|
||||||
@@ -174,30 +63,29 @@ func defaultString(val string, defaultVal string) string {
|
|||||||
func (b *PackageHelper) getPackageFileBaseDir() string {
|
func (b *PackageHelper) getPackageFileBaseDir() string {
|
||||||
// Calculate template base dir
|
// Calculate template base dir
|
||||||
_, filename, _, _ := runtime.Caller(1)
|
_, filename, _, _ := runtime.Caller(1)
|
||||||
return filepath.Join(path.Dir(filename), "packages", b.platform)
|
return filepath.Join(path.Dir(filename), "packages", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package the application into a platform specific package
|
// Package the application into a platform specific package
|
||||||
func (b *PackageHelper) Package(po *ProjectOptions) error {
|
func (b *PackageHelper) Package(po *ProjectOptions) error {
|
||||||
switch b.platform {
|
switch runtime.GOOS {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
|
// Check we have the exe
|
||||||
|
if !b.fs.FileExists(po.BinaryName) {
|
||||||
|
return fmt.Errorf("cannot bundle non-existent binary file '%s'. Please build with 'wails build' first", po.BinaryName)
|
||||||
|
}
|
||||||
return b.packageOSX(po)
|
return b.packageOSX(po)
|
||||||
case "windows":
|
case "windows":
|
||||||
return b.PackageWindows(po, true)
|
return b.PackageWindows(po, false)
|
||||||
case "linux":
|
case "linux":
|
||||||
return b.packageLinux(po)
|
return fmt.Errorf("linux is not supported at this time. Please see https://github.com/wailsapp/wails/issues/2")
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("platform '%s' not supported for bundling yet", b.platform)
|
return fmt.Errorf("platform '%s' not supported for bundling yet", runtime.GOOS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PackageHelper) packageLinux(po *ProjectOptions) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Package the application for OSX
|
// Package the application for OSX
|
||||||
func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
||||||
build := path.Join(b.fs.Cwd(), "build")
|
|
||||||
|
|
||||||
system := NewSystemHelper()
|
system := NewSystemHelper()
|
||||||
config, err := system.LoadConfig()
|
config, err := system.LoadConfig()
|
||||||
@@ -214,25 +102,18 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
appname := po.Name + ".app"
|
appname := po.Name + ".app"
|
||||||
|
|
||||||
// Check binary exists
|
// Check binary exists
|
||||||
source := path.Join(build, exe)
|
source := path.Join(b.fs.Cwd(), exe)
|
||||||
if po.CrossCompile == true {
|
|
||||||
file, err := b.fs.FindFile(build, "darwin")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
source = path.Join(build, file)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !b.fs.FileExists(source) {
|
if !b.fs.FileExists(source) {
|
||||||
// We need to build!
|
// We need to build!
|
||||||
return fmt.Errorf("Target '%s' not available. Has it been compiled yet?", source)
|
return fmt.Errorf("Target '%s' not available. Has it been compiled yet?", exe)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the existing package
|
// Remove the existing package
|
||||||
os.RemoveAll(appname)
|
os.RemoveAll(appname)
|
||||||
|
|
||||||
exeDir := path.Join(build, appname, "/Contents/MacOS")
|
exeDir := path.Join(b.fs.Cwd(), appname, "/Contents/MacOS")
|
||||||
b.fs.MkDirs(exeDir, 0755)
|
b.fs.MkDirs(exeDir, 0755)
|
||||||
resourceDir := path.Join(build, appname, "/Contents/Resources")
|
resourceDir := path.Join(b.fs.Cwd(), appname, "/Contents/Resources")
|
||||||
b.fs.MkDirs(resourceDir, 0755)
|
b.fs.MkDirs(resourceDir, 0755)
|
||||||
tmpl := template.New("infoPlist")
|
tmpl := template.New("infoPlist")
|
||||||
plistFile := filepath.Join(b.getPackageFileBaseDir(), "info.plist")
|
plistFile := filepath.Join(b.getPackageFileBaseDir(), "info.plist")
|
||||||
@@ -248,7 +129,7 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filename := path.Join(build, appname, "Contents", "Info.plist")
|
filename := path.Join(b.fs.Cwd(), appname, "Contents", "Info.plist")
|
||||||
err = ioutil.WriteFile(filename, tpl.Bytes(), 0644)
|
err = ioutil.WriteFile(filename, tpl.Bytes(), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -269,37 +150,22 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanWindows removes any windows related files found in the directory
|
|
||||||
func (b *PackageHelper) CleanWindows(po *ProjectOptions) {
|
|
||||||
pdir := b.fs.Cwd()
|
|
||||||
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
|
||||||
exts := []string{".ico", ".exe.manifest", ".rc", "-res.syso"}
|
|
||||||
rsrcs := []string{}
|
|
||||||
for _, ext := range exts {
|
|
||||||
rsrcs = append(rsrcs, filepath.Join(pdir, basename+ext))
|
|
||||||
}
|
|
||||||
b.fs.RemoveFiles(rsrcs, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PackageWindows packages the application for windows platforms
|
// PackageWindows packages the application for windows platforms
|
||||||
func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
||||||
outputDir := b.fs.Cwd()
|
|
||||||
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
||||||
|
|
||||||
// Copy default icon if needed
|
// Copy icon
|
||||||
icon, err := b.copyIcon()
|
tgtIconFile := filepath.Join(b.fs.Cwd(), basename+".ico")
|
||||||
if err != nil {
|
if !b.fs.FileExists(tgtIconFile) {
|
||||||
return err
|
srcIconfile := filepath.Join(b.getPackageFileBaseDir(), "wails.ico")
|
||||||
}
|
err := b.fs.CopyFile(srcIconfile, tgtIconFile)
|
||||||
|
if err != nil {
|
||||||
// Generate icon from PNG
|
return err
|
||||||
err = generateWindowsIcon(icon, basename+".ico")
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy manifest
|
// Copy manifest
|
||||||
tgtManifestFile := filepath.Join(outputDir, basename+".exe.manifest")
|
tgtManifestFile := filepath.Join(b.fs.Cwd(), basename+".exe.manifest")
|
||||||
if !b.fs.FileExists(tgtManifestFile) {
|
if !b.fs.FileExists(tgtManifestFile) {
|
||||||
srcManifestfile := filepath.Join(b.getPackageFileBaseDir(), "wails.exe.manifest")
|
srcManifestfile := filepath.Join(b.getPackageFileBaseDir(), "wails.exe.manifest")
|
||||||
err := b.fs.CopyFile(srcManifestfile, tgtManifestFile)
|
err := b.fs.CopyFile(srcManifestfile, tgtManifestFile)
|
||||||
@@ -309,7 +175,7 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy rc file
|
// Copy rc file
|
||||||
tgtRCFile := filepath.Join(outputDir, basename+".rc")
|
tgtRCFile := filepath.Join(b.fs.Cwd(), basename+".rc")
|
||||||
if !b.fs.FileExists(tgtRCFile) {
|
if !b.fs.FileExists(tgtRCFile) {
|
||||||
srcRCfile := filepath.Join(b.getPackageFileBaseDir(), "wails.rc")
|
srcRCfile := filepath.Join(b.getPackageFileBaseDir(), "wails.rc")
|
||||||
rcfilebytes, err := ioutil.ReadFile(srcRCfile)
|
rcfilebytes, err := ioutil.ReadFile(srcRCfile)
|
||||||
@@ -324,37 +190,33 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build syso
|
// Build syso
|
||||||
sysofile := filepath.Join(outputDir, basename+"-res.syso")
|
sysofile := filepath.Join(b.fs.Cwd(), basename+"-res.syso")
|
||||||
|
|
||||||
// cross-compile
|
batfile, err := fs.LocalDir(".")
|
||||||
if b.platform != runtime.GOOS {
|
if err != nil {
|
||||||
args := []string{
|
return err
|
||||||
"docker", "run", "--rm",
|
}
|
||||||
"-v", outputDir + ":/build",
|
|
||||||
"--entrypoint", "/bin/sh",
|
|
||||||
"wailsapp/xgo:latest",
|
|
||||||
"-c", "/usr/bin/x86_64-w64-mingw32-windres -o /build/" + basename + "-res.syso /build/" + basename + ".rc",
|
|
||||||
}
|
|
||||||
if err := NewProgramHelper().RunCommandArray(args); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
batfile, err := fs.LocalDir(".")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
windresBatFile := filepath.Join(batfile.fullPath, "windres.bat")
|
windresBatFile := filepath.Join(batfile.fullPath, "windres.bat")
|
||||||
windresCommand := []string{windresBatFile, sysofile, tgtRCFile}
|
windresCommand := []string{windresBatFile, sysofile, tgtRCFile}
|
||||||
err = NewProgramHelper().RunCommandArray(windresCommand)
|
err = NewProgramHelper().RunCommandArray(windresCommand)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
if cleanUp {
|
||||||
|
filesToDelete := []string{tgtIconFile, tgtManifestFile, tgtRCFile, sysofile}
|
||||||
|
err := b.fs.RemoveFiles(filesToDelete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PackageHelper) copyIcon() (string, error) {
|
func (b *PackageHelper) copyIcon(resourceDir string) (string, error) {
|
||||||
|
|
||||||
// TODO: Read this from project.json
|
// TODO: Read this from project.json
|
||||||
const appIconFilename = "appicon.png"
|
const appIconFilename = "appicon.png"
|
||||||
@@ -379,7 +241,7 @@ func (b *PackageHelper) copyIcon() (string, error) {
|
|||||||
|
|
||||||
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
||||||
|
|
||||||
srcIcon, err := b.copyIcon()
|
srcIcon, err := b.copyIcon(resourceDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0"><dict>
|
<plist version="1.0"><dict>
|
||||||
<key>CFBundlePackageType</key><string>APPL</string>
|
|
||||||
<key>CFBundleName</key><string>{{.Title}}</string>
|
<key>CFBundleName</key><string>{{.Title}}</string>
|
||||||
<key>CFBundleExecutable</key><string>{{.Exe}}</string>
|
<key>CFBundleExecutable</key><string>{{.Exe}}</string>
|
||||||
<key>CFBundleIdentifier</key><string>{{.PackageID}}</string>
|
<key>CFBundleIdentifier</key><string>{{.PackageID}}</string>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
100 ICON "$NAME$.ico"
|
100 ICON "$NAME$.ico"
|
||||||
110 24 "$NAME$.exe.manifest"
|
100 24 "$NAME$.exe.manifest"
|
||||||
@@ -138,11 +138,11 @@ func (p *ProgramHelper) RunCommand(command string) error {
|
|||||||
|
|
||||||
// RunCommandArray runs the command specified in the array
|
// RunCommandArray runs the command specified in the array
|
||||||
func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
|
func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
|
||||||
programCommand := args[0]
|
program := args[0]
|
||||||
// TODO: Run FindProgram here and get the full path to the exe
|
// TODO: Run FindProgram here and get the full path to the exe
|
||||||
program, err := exec.LookPath(programCommand)
|
program, err := exec.LookPath(program)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", programCommand)
|
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", program)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -158,10 +159,6 @@ type ProjectOptions struct {
|
|||||||
WailsVersion string
|
WailsVersion string
|
||||||
typescriptDefsFilename string
|
typescriptDefsFilename string
|
||||||
Verbose bool `json:"-"`
|
Verbose bool `json:"-"`
|
||||||
CrossCompile bool
|
|
||||||
Platform string
|
|
||||||
Architecture string
|
|
||||||
LdFlags string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defaults sets the default project template
|
// Defaults sets the default project template
|
||||||
@@ -336,6 +333,11 @@ func processBinaryName(po *ProjectOptions) {
|
|||||||
if po.BinaryName == "" {
|
if po.BinaryName == "" {
|
||||||
var binaryNameComputed = computeBinaryName(po.Name)
|
var binaryNameComputed = computeBinaryName(po.Name)
|
||||||
po.BinaryName = Prompt("The output binary name", binaryNameComputed)
|
po.BinaryName = Prompt("The output binary name", binaryNameComputed)
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
if !strings.HasSuffix(po.BinaryName, ".exe") {
|
||||||
|
po.BinaryName += ".exe"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Output binary Name: " + po.BinaryName)
|
fmt.Println("Output binary Name: " + po.BinaryName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SystemHelper - Defines everything related to the system
|
// SystemHelper - Defines everything related to the system
|
||||||
@@ -37,13 +38,12 @@ func NewSystemHelper() *SystemHelper {
|
|||||||
// setSystemDirs calculates the system directories it is interested in
|
// setSystemDirs calculates the system directories it is interested in
|
||||||
func (s *SystemHelper) setSystemDirs() {
|
func (s *SystemHelper) setSystemDirs() {
|
||||||
var err error
|
var err error
|
||||||
s.homeDir, err = os.UserConfigDir()
|
s.homeDir, err = homedir.Dir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Cannot find home directory! Please file a bug report!")
|
log.Fatal("Cannot find home directory! Please file a bug report!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: A better config system
|
// TODO: A better config system
|
||||||
s.wailsSystemDir = filepath.Join(s.homeDir, "wails")
|
s.wailsSystemDir = filepath.Join(s.homeDir, ".wails")
|
||||||
s.wailsSystemConfig = filepath.Join(s.wailsSystemDir, s.configFilename)
|
s.wailsSystemConfig = filepath.Join(s.wailsSystemDir, s.configFilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ func (s *SystemHelper) setup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const introText = `
|
const introText = `
|
||||||
Wails is a lightweight framework for creating web-like desktop apps in Go.
|
Wails is a lightweight framework for creating web-like desktop apps in Go.
|
||||||
I'll need to ask you a few questions so I can fill in your project templates and then I will try and see if you have the correct dependencies installed. If you don't have the right tools installed, I'll try and suggest how to install them.
|
I'll need to ask you a few questions so I can fill in your project templates and then I will try and see if you have the correct dependencies installed. If you don't have the right tools installed, I'll try and suggest how to install them.
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -274,18 +274,16 @@ func CheckDependencies(logger *Logger) (bool, error) {
|
|||||||
distroInfo := GetLinuxDistroInfo()
|
distroInfo := GetLinuxDistroInfo()
|
||||||
|
|
||||||
switch distroInfo.Distribution {
|
switch distroInfo.Distribution {
|
||||||
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian, PopOS:
|
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian:
|
||||||
libraryChecker = DpkgInstalled
|
libraryChecker = DpkgInstalled
|
||||||
case Arch, ArcoLinux, ArchLabs, Manjaro, ManjaroARM:
|
case Arch, ArcoLinux, Manjaro, ManjaroARM:
|
||||||
libraryChecker = PacmanInstalled
|
libraryChecker = PacmanInstalled
|
||||||
case CentOS, Fedora, Tumbleweed, Leap:
|
case CentOS, Fedora:
|
||||||
libraryChecker = RpmInstalled
|
libraryChecker = RpmInstalled
|
||||||
case Gentoo:
|
case Gentoo:
|
||||||
libraryChecker = EqueryInstalled
|
libraryChecker = EqueryInstalled
|
||||||
case VoidLinux:
|
case VoidLinux:
|
||||||
libraryChecker = XbpsInstalled
|
libraryChecker = XbpsInstalled
|
||||||
case Solus:
|
|
||||||
libraryChecker = EOpkgInstalled
|
|
||||||
default:
|
default:
|
||||||
return false, RequestSupportForDistribution(distroInfo)
|
return false, RequestSupportForDistribution(distroInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.6.4",
|
"core-js": "^3.1.4",
|
||||||
"react": "^16.13.0",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.13.0",
|
"react-dom": "^16.8.6",
|
||||||
"wails-react-scripts": "3.0.1-2",
|
"wails-react-scripts": "3.0.1-2",
|
||||||
"react-modal": "3.11.2",
|
"react-modal": "3.8.1",
|
||||||
"@wailsapp/runtime": "^1.0.10"
|
"@wailsapp/runtime": "^1.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# README
|
|
||||||
|
|
||||||
This is an experimental template for vanilla HTML/JS/CSS.
|
|
||||||
|
|
||||||
The webpack rules may need to be adjusted to correctly embed all assets. Babel may also need to be setup correctly.
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "vanilla",
|
|
||||||
"author": "Lea<l>",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"serve": "webpack-dev-server",
|
|
||||||
"build": "npx webpack"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": "^3.6.4",
|
|
||||||
"regenerator-runtime": "^0.13.3",
|
|
||||||
"@wailsapp/runtime": "^1.0.10"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"babel-eslint": "^10.1.0",
|
|
||||||
"copy-webpack-plugin": "^6.0.2",
|
|
||||||
"eslint": "^6.8.0",
|
|
||||||
"eventsource-polyfill": "^0.9.6",
|
|
||||||
"webpack": "^4.43.0",
|
|
||||||
"webpack-cli": "^3.3.11",
|
|
||||||
"webpack-dev-server": "^3.11.0",
|
|
||||||
"webpack-hot-middleware": "^2.25.0"
|
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"root": true,
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended"
|
|
||||||
],
|
|
||||||
"rules": {},
|
|
||||||
"parserOptions": {
|
|
||||||
"parser": "babel-eslint"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
"> 1%",
|
|
||||||
"last 2 versions",
|
|
||||||
"not ie <= 8"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="main.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script src="main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,30 +0,0 @@
|
|||||||
import 'core-js/stable';
|
|
||||||
const runtime = require('@wailsapp/runtime');
|
|
||||||
|
|
||||||
// Main entry point
|
|
||||||
function start() {
|
|
||||||
|
|
||||||
// Ensure the default app div is 100% wide/high
|
|
||||||
var app = document.getElementById('app');
|
|
||||||
app.style.width = '100%';
|
|
||||||
app.style.height = '100%';
|
|
||||||
|
|
||||||
// Inject html
|
|
||||||
app.innerHTML = `
|
|
||||||
<div class='logo'></div>
|
|
||||||
<div class='container'>
|
|
||||||
<button id='button'>Click Me!</button>
|
|
||||||
<div id='result'/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Connect button to Go method
|
|
||||||
document.getElementById('button').onclick = function() {
|
|
||||||
window.backend.basic().then( function(result) {
|
|
||||||
document.getElementById('result').innerText = result;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// We provide our entrypoint as a callback for runtime.Init
|
|
||||||
runtime.Init(start);
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
||||||
|
|
||||||
let imageSizeLimit = 9007199254740991; // Number.MAX_SAFE_INTEGER
|
|
||||||
let sourceDir = path.resolve(__dirname, 'src');
|
|
||||||
let buildDir = path.resolve(__dirname, 'build');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: {
|
|
||||||
index: path.resolve(sourceDir, 'main.js')
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
path: buildDir,
|
|
||||||
filename: 'main.js'
|
|
||||||
},
|
|
||||||
optimization: {
|
|
||||||
splitChunks: false
|
|
||||||
},
|
|
||||||
devServer: {
|
|
||||||
disableHostCheck: true,
|
|
||||||
contentBase: path.join(__dirname, 'src'),
|
|
||||||
compress: true,
|
|
||||||
open: true,
|
|
||||||
port: 8090
|
|
||||||
},
|
|
||||||
mode: 'production',
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.(png|gif|jpg|woff2?|eot|ttf|otf|svg)(\?.*)?$/i,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'url-loader',
|
|
||||||
options: {
|
|
||||||
limit: imageSizeLimit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new CopyWebpackPlugin({
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
from: path.resolve(sourceDir, 'main.css'),
|
|
||||||
to: path.resolve(buildDir, 'main.css')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: path.resolve(sourceDir, 'index.html'),
|
|
||||||
to: path.resolve(buildDir, 'index.html')
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
module {{.BinaryName}}
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/wailsapp/wails {{.WailsVersion}}
|
|
||||||
)
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/leaanthony/mewn"
|
|
||||||
"github.com/wailsapp/wails"
|
|
||||||
)
|
|
||||||
|
|
||||||
func basic() string {
|
|
||||||
return "Hello World!"
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
js := mewn.String("./frontend/build/main.js")
|
|
||||||
css := mewn.String("./frontend/build/main.css")
|
|
||||||
|
|
||||||
app := wails.CreateApp(&wails.AppConfig{
|
|
||||||
Width: 1024,
|
|
||||||
Height: 768,
|
|
||||||
Title: "{{.Name}}",
|
|
||||||
JS: js,
|
|
||||||
CSS: css,
|
|
||||||
Colour: "#131313",
|
|
||||||
})
|
|
||||||
app.Bind(basic)
|
|
||||||
app.Run()
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Vanilla",
|
|
||||||
"shortdescription": "A Vanilla HTML/JS template",
|
|
||||||
"description": "A basic template using plain html/js and bundled using Webpack 4",
|
|
||||||
"author": "Lea Anthony<lea.anthony@gmail.com>",
|
|
||||||
"created": "2020-06-14",
|
|
||||||
"frontenddir": "frontend",
|
|
||||||
"install": "npm install",
|
|
||||||
"build": "npm run build",
|
|
||||||
"serve": "npm run serve",
|
|
||||||
"bridge": "src"
|
|
||||||
}
|
|
||||||
@@ -8,21 +8,21 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.6.4",
|
"core-js": "^3.6.1",
|
||||||
"regenerator-runtime": "^0.13.3",
|
"regenerator-runtime": "^0.13.3",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.5.22",
|
||||||
"@wailsapp/runtime": "^1.0.10"
|
"@wailsapp/runtime": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.2.3",
|
"@vue/cli-plugin-babel": "^3.4.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.2.3",
|
"@vue/cli-plugin-eslint": "^3.4.0",
|
||||||
"@vue/cli-service": "^4.2.3",
|
"@vue/cli-service": "^3.4.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.0.1",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^5.8.0",
|
||||||
"eslint-plugin-vue": "^6.2.1",
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"vue-template-compiler": "^2.6.11",
|
"vue-template-compiler": "^2.5.21",
|
||||||
"webpack-hot-middleware": "^2.25.0"
|
"webpack-hot-middleware": "^2.24.3"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.6.4",
|
"core-js": "^3.6.1",
|
||||||
"regenerator-runtime": "^0.13.3",
|
"regenerator-runtime": "^0.13.3",
|
||||||
"material-design-icons-iconfont": "^5.0.1",
|
"material-design-icons-iconfont": "^5.0.1",
|
||||||
"vue": "^2.5.22",
|
"vue": "^2.5.22",
|
||||||
"vuetify": "^1.5.14",
|
"vuetify": "^1.5.14",
|
||||||
"@wailsapp/runtime": "^1.0.10"
|
"@wailsapp/runtime": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.2.3",
|
"@vue/cli-plugin-babel": "^3.4.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.2.3",
|
"@vue/cli-plugin-eslint": "^3.4.0",
|
||||||
"@vue/cli-service": "^4.2.3",
|
"@vue/cli-service": "^3.4.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.0.1",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^5.8.0",
|
||||||
"eslint-plugin-vue": "^6.2.1",
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"vue-template-compiler": "^2.6.11",
|
"vue-template-compiler": "^2.5.21",
|
||||||
"webpack-hot-middleware": "^2.25.0"
|
"webpack-hot-middleware": "^2.24.3"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -8,23 +8,23 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.6.4",
|
"core-js": "^3.6.1",
|
||||||
"regenerator-runtime": "^0.13.3",
|
"regenerator-runtime": "^0.13.3",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.5.22",
|
||||||
"vuetify": "^2.2.15",
|
"vuetify": "^2.0.15",
|
||||||
"@wailsapp/runtime": "^1.0.10"
|
"@wailsapp/runtime": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mdi/font": "^4.9.95",
|
"@mdi/font": "^4.3.95",
|
||||||
"@vue/cli-plugin-babel": "^4.2.3",
|
"@vue/cli-plugin-babel": "^3.4.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.2.3",
|
"@vue/cli-plugin-eslint": "^3.4.0",
|
||||||
"@vue/cli-service": "^4.2.3",
|
"@vue/cli-service": "^3.4.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.0.1",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^5.8.0",
|
||||||
"eslint-plugin-vue": "^6.2.1",
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"vue-template-compiler": "^2.6.11",
|
"vue-template-compiler": "^2.5.21",
|
||||||
"webpack-hot-middleware": "^2.25.0"
|
"webpack-hot-middleware": "^2.24.3"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
// Version - Wails version
|
// Version - Wails version
|
||||||
const Version = "v1.7.2-pre2"
|
const Version = "v1.0.2"
|
||||||
|
|||||||
@@ -3,24 +3,11 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getSupportedPlatforms returns a slice of platform/architecture
|
|
||||||
// targets that are buildable using the cross-platform 'x' option.
|
|
||||||
func getSupportedPlatforms() []string {
|
|
||||||
return []string{
|
|
||||||
"darwin/amd64",
|
|
||||||
"linux/amd64",
|
|
||||||
"linux/arm-7",
|
|
||||||
"windows/amd64",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
var packageApp = false
|
var packageApp = false
|
||||||
@@ -28,8 +15,6 @@ func init() {
|
|||||||
var debugMode = false
|
var debugMode = false
|
||||||
var typescriptFilename = ""
|
var typescriptFilename = ""
|
||||||
var verbose = false
|
var verbose = false
|
||||||
var platform = ""
|
|
||||||
var ldflags = ""
|
|
||||||
|
|
||||||
buildSpinner := spinner.NewSpinner()
|
buildSpinner := spinner.NewSpinner()
|
||||||
buildSpinner.SetSpinSpeed(50)
|
buildSpinner.SetSpinSpeed(50)
|
||||||
@@ -41,16 +26,7 @@ func init() {
|
|||||||
BoolFlag("f", "Force rebuild of application components", &forceRebuild).
|
BoolFlag("f", "Force rebuild of application components", &forceRebuild).
|
||||||
BoolFlag("d", "Build in Debug mode", &debugMode).
|
BoolFlag("d", "Build in Debug mode", &debugMode).
|
||||||
BoolFlag("verbose", "Verbose output", &verbose).
|
BoolFlag("verbose", "Verbose output", &verbose).
|
||||||
StringFlag("t", "Generate Typescript definitions to given file (at runtime)", &typescriptFilename).
|
StringFlag("t", "Generate Typescript definitions to given file (at runtime)", &typescriptFilename)
|
||||||
StringFlag("ldflags", "Extra options for -ldflags", &ldflags)
|
|
||||||
|
|
||||||
var b strings.Builder
|
|
||||||
for _, plat := range getSupportedPlatforms() {
|
|
||||||
fmt.Fprintf(&b, " - %s\n", plat)
|
|
||||||
}
|
|
||||||
initCmd.StringFlag("x",
|
|
||||||
fmt.Sprintf("Cross-compile application to specified platform via xgo\n%s", b.String()),
|
|
||||||
&platform)
|
|
||||||
|
|
||||||
initCmd.Action(func() error {
|
initCmd.Action(func() error {
|
||||||
|
|
||||||
@@ -76,28 +52,6 @@ func init() {
|
|||||||
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set cross-compile
|
|
||||||
projectOptions.Platform = runtime.GOOS
|
|
||||||
if len(platform) > 0 {
|
|
||||||
supported := false
|
|
||||||
for _, plat := range getSupportedPlatforms() {
|
|
||||||
if plat == platform {
|
|
||||||
supported = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !supported {
|
|
||||||
return fmt.Errorf("unsupported platform '%s' specified.\nPlease run `wails build -h` to see the supported platform/architecture options", platform)
|
|
||||||
}
|
|
||||||
|
|
||||||
projectOptions.CrossCompile = true
|
|
||||||
plat := strings.Split(platform, "/")
|
|
||||||
projectOptions.Platform = plat[0]
|
|
||||||
projectOptions.Architecture = plat[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add ldflags
|
|
||||||
projectOptions.LdFlags = ldflags
|
|
||||||
|
|
||||||
// Validate config
|
// Validate config
|
||||||
// Check if we have a frontend
|
// Check if we have a frontend
|
||||||
err = cmd.ValidateFrontendConfig(projectOptions)
|
err = cmd.ValidateFrontendConfig(projectOptions)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
@@ -35,6 +34,7 @@ func init() {
|
|||||||
|
|
||||||
// Project options
|
// Project options
|
||||||
projectOptions := &cmd.ProjectOptions{}
|
projectOptions := &cmd.ProjectOptions{}
|
||||||
|
projectOptions.Verbose = verbose
|
||||||
|
|
||||||
// Check we are in project directory
|
// Check we are in project directory
|
||||||
// Check project.json loads correctly
|
// Check project.json loads correctly
|
||||||
@@ -44,10 +44,6 @@ func init() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set project options
|
|
||||||
projectOptions.Verbose = verbose
|
|
||||||
projectOptions.Platform = runtime.GOOS
|
|
||||||
|
|
||||||
// Save project directory
|
// Save project directory
|
||||||
projectDir := fs.Cwd()
|
projectDir := fs.Cwd()
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ func updateToVersion(targetVersion *cmd.SemanticVersion, force bool) error {
|
|||||||
updateSpinner.Start("Installing Wails " + desiredVersion)
|
updateSpinner.Start("Installing Wails " + desiredVersion)
|
||||||
|
|
||||||
// Run command in non module directory
|
// Run command in non module directory
|
||||||
homeDir, err := os.UserHomeDir()
|
homeDir, err := homedir.Dir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Cannot find home directory! Please file a bug report!")
|
log.Fatal("Cannot find home directory! Please file a bug report!")
|
||||||
}
|
}
|
||||||
|
|||||||
9
go.mod
9
go.mod
@@ -14,18 +14,19 @@ require (
|
|||||||
github.com/leaanthony/spinner v0.5.3
|
github.com/leaanthony/spinner v0.5.3
|
||||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
||||||
golang.org/x/text v0.3.0
|
golang.org/x/text v0.3.0
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
||||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.13
|
go 1.12
|
||||||
|
|||||||
16
go.sum
16
go.sum
@@ -46,6 +46,8 @@ github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc
|
|||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
||||||
@@ -66,21 +68,19 @@ github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba h1:2DHfQOxcpWdGf5
|
|||||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ type Renderer interface {
|
|||||||
NotifyEvent(eventData *messages.EventData) error
|
NotifyEvent(eventData *messages.EventData) error
|
||||||
|
|
||||||
// Dialog Runtime
|
// Dialog Runtime
|
||||||
SelectFile(title string, filter string) string
|
SelectFile() string
|
||||||
SelectDirectory() string
|
SelectDirectory() string
|
||||||
SelectSaveFile(title string, filter string) string
|
SelectSaveFile() string
|
||||||
|
|
||||||
// Window Runtime
|
// Window Runtime
|
||||||
SetColour(string) error
|
SetColour(string) error
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ type Bridge struct {
|
|||||||
server *http.Server
|
server *http.Server
|
||||||
|
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
sessions map[string]*session
|
sessions map[string]session
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise the Bridge Renderer
|
// Initialise the Bridge Renderer
|
||||||
func (h *Bridge) Initialise(appConfig interfaces.AppConfig, ipcManager interfaces.IPCManager, eventManager interfaces.EventManager) error {
|
func (h *Bridge) Initialise(appConfig interfaces.AppConfig, ipcManager interfaces.IPCManager, eventManager interfaces.EventManager) error {
|
||||||
h.sessions = map[string]*session{}
|
h.sessions = map[string]session{}
|
||||||
h.ipcManager = ipcManager
|
h.ipcManager = ipcManager
|
||||||
h.appConfig = appConfig
|
h.appConfig = appConfig
|
||||||
h.eventManager = eventManager
|
h.eventManager = eventManager
|
||||||
@@ -70,11 +70,13 @@ func (h *Bridge) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Bridge) startSession(conn *websocket.Conn) {
|
func (h *Bridge) startSession(conn *websocket.Conn) {
|
||||||
s := newSession(conn,
|
s := session{
|
||||||
h.bindingCache,
|
conn: conn,
|
||||||
h.ipcManager,
|
bindingCache: h.bindingCache,
|
||||||
logger.NewCustomLogger("BridgeSession"),
|
ipc: h.ipcManager,
|
||||||
h.eventManager)
|
log: h.log,
|
||||||
|
eventManager: h.eventManager,
|
||||||
|
}
|
||||||
|
|
||||||
conn.SetCloseHandler(func(int, string) error {
|
conn.SetCloseHandler(func(int, string) error {
|
||||||
h.log.Infof("Connection dropped [%s].", s.Identifier())
|
h.log.Infof("Connection dropped [%s].", s.Identifier())
|
||||||
@@ -114,7 +116,7 @@ func (h *Bridge) NewBinding(methodName string) error {
|
|||||||
|
|
||||||
// SelectFile is unsupported for Bridge but required
|
// SelectFile is unsupported for Bridge but required
|
||||||
// for the Renderer interface
|
// for the Renderer interface
|
||||||
func (h *Bridge) SelectFile(title string, filter string) string {
|
func (h *Bridge) SelectFile() string {
|
||||||
h.log.Warn("SelectFile() unsupported in bridge mode")
|
h.log.Warn("SelectFile() unsupported in bridge mode")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -128,7 +130,7 @@ func (h *Bridge) SelectDirectory() string {
|
|||||||
|
|
||||||
// SelectSaveFile is unsupported for Bridge but required
|
// SelectSaveFile is unsupported for Bridge but required
|
||||||
// for the Renderer interface
|
// for the Renderer interface
|
||||||
func (h *Bridge) SelectSaveFile(title string, filter string) string {
|
func (h *Bridge) SelectSaveFile() string {
|
||||||
h.log.Warn("SelectSaveFile() unsupported in bridge mode")
|
h.log.Warn("SelectSaveFile() unsupported in bridge mode")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -152,20 +154,13 @@ func (h *Bridge) NotifyEvent(event *messages.EventData) error {
|
|||||||
// Marshall the data
|
// Marshall the data
|
||||||
data, err = json.Marshal(event.Data)
|
data, err = json.Marshal(event.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Errorf("Cannot marshal JSON data in event: %s ", err.Error())
|
h.log.Errorf("Cannot unmarshall JSON data in event: %s ", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double encode data to ensure everything is escaped correctly.
|
message := fmt.Sprintf("window.wails._.Notify('%s','%s')", event.Name, data)
|
||||||
data, err = json.Marshal(string(data))
|
dead := []session{}
|
||||||
if err != nil {
|
|
||||||
h.log.Errorf("Cannot marshal JSON data in event: %s ", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
message := "window.wails._.Notify('" + event.Name + "'," + string(data) + ")"
|
|
||||||
dead := []*session{}
|
|
||||||
for _, session := range h.sessions {
|
for _, session := range h.sessions {
|
||||||
err := session.evalJS(message, notifyMessage)
|
err := session.evalJS(message, notifyMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -212,9 +207,6 @@ func (h *Bridge) SetTitle(title string) {
|
|||||||
// for the Renderer interface
|
// for the Renderer interface
|
||||||
func (h *Bridge) Close() {
|
func (h *Bridge) Close() {
|
||||||
h.log.Debug("Shutting down")
|
h.log.Debug("Shutting down")
|
||||||
for _, session := range h.sessions {
|
|
||||||
session.Shutdown()
|
|
||||||
}
|
|
||||||
err := h.server.Close()
|
err := h.server.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Errorf(err.Error())
|
h.log.Errorf(err.Error())
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"sync"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/leaanthony/mewn"
|
"github.com/leaanthony/mewn"
|
||||||
@@ -21,22 +20,7 @@ type session struct {
|
|||||||
ipc interfaces.IPCManager
|
ipc interfaces.IPCManager
|
||||||
|
|
||||||
// Mutex for writing to the socket
|
// Mutex for writing to the socket
|
||||||
shutdown chan bool
|
lock sync.Mutex
|
||||||
writeChan chan []byte
|
|
||||||
|
|
||||||
done bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSession(conn *websocket.Conn, bindingCache []string, ipc interfaces.IPCManager, logger *logger.CustomLogger, eventMgr interfaces.EventManager) *session {
|
|
||||||
return &session{
|
|
||||||
conn: conn,
|
|
||||||
bindingCache: bindingCache,
|
|
||||||
ipc: ipc,
|
|
||||||
log: logger,
|
|
||||||
eventManager: eventMgr,
|
|
||||||
shutdown: make(chan bool),
|
|
||||||
writeChan: make(chan []byte, 100),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identifier returns a string identifier for the remote connection.
|
// Identifier returns a string identifier for the remote connection.
|
||||||
@@ -49,15 +33,19 @@ func (s *session) Identifier() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) sendMessage(msg string) error {
|
func (s *session) sendMessage(msg string) error {
|
||||||
if !s.done {
|
s.lock.Lock()
|
||||||
s.writeChan <- *(*[]byte)(unsafe.Pointer(&msg))
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
if err := s.conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
|
||||||
|
s.log.Debug(err.Error())
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) start(firstSession bool) {
|
func (s *session) start(firstSession bool) {
|
||||||
s.log.Infof("Connected to frontend.")
|
s.log.Infof("Connected to frontend.")
|
||||||
go s.writePump()
|
|
||||||
|
|
||||||
wailsRuntime := mewn.String("../../runtime/assets/wails.js")
|
wailsRuntime := mewn.String("../../runtime/assets/wails.js")
|
||||||
s.evalJS(wailsRuntime, wailsRuntimeMessage)
|
s.evalJS(wailsRuntime, wailsRuntimeMessage)
|
||||||
@@ -86,10 +74,6 @@ func (s *session) start(firstSession bool) {
|
|||||||
s.log.Debugf("Got message: %#v\n", string(buffer))
|
s.log.Debugf("Got message: %#v\n", string(buffer))
|
||||||
|
|
||||||
s.ipc.Dispatch(string(buffer), s.Callback)
|
s.ipc.Dispatch(string(buffer), s.Callback)
|
||||||
|
|
||||||
if s.done {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,38 +83,8 @@ func (s *session) Callback(data string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) evalJS(js string, mtype messageType) error {
|
func (s *session) evalJS(js string, mtype messageType) error {
|
||||||
|
|
||||||
// Prepend message type to message
|
// Prepend message type to message
|
||||||
return s.sendMessage(mtype.toString() + js)
|
return s.sendMessage(mtype.toString() + js)
|
||||||
}
|
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
func (s *session) Shutdown() {
|
|
||||||
s.done = true
|
|
||||||
s.shutdown <- true
|
|
||||||
s.log.Debugf("session %v exit", s.Identifier())
|
|
||||||
}
|
|
||||||
|
|
||||||
// writePump pulls messages from the writeChan and sends them to the client
|
|
||||||
// since it uses a channel to read the messages the socket is protected without locks
|
|
||||||
func (s *session) writePump() {
|
|
||||||
s.log.Debugf("Session %v - writePump start", s.Identifier())
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case msg, ok := <-s.writeChan:
|
|
||||||
s.conn.SetWriteDeadline(time.Now().Add(1 * time.Second))
|
|
||||||
if !ok {
|
|
||||||
s.log.Debug("writeChan was closed!")
|
|
||||||
s.conn.WriteMessage(websocket.CloseMessage, []byte{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.conn.WriteMessage(websocket.TextMessage, msg); err != nil {
|
|
||||||
s.log.Debug(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case <-s.shutdown:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.log.Debug("writePump exiting...")
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -245,7 +245,7 @@ func (w *WebView) NewBinding(methodName string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SelectFile opens a dialog that allows the user to select a file
|
// SelectFile opens a dialog that allows the user to select a file
|
||||||
func (w *WebView) SelectFile(title string, filter string) string {
|
func (w *WebView) SelectFile() string {
|
||||||
var result string
|
var result string
|
||||||
|
|
||||||
// We need to run this on the main thread, however Dispatch is
|
// We need to run this on the main thread, however Dispatch is
|
||||||
@@ -255,7 +255,7 @@ func (w *WebView) SelectFile(title string, filter string) string {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
w.window.Dispatch(func() {
|
w.window.Dispatch(func() {
|
||||||
result = w.window.Dialog(wv.DialogTypeOpen, 0, title, "", filter)
|
result = w.window.Dialog(wv.DialogTypeOpen, 0, "Select File", "")
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
}()
|
}()
|
||||||
@@ -273,7 +273,7 @@ func (w *WebView) SelectDirectory() string {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
w.window.Dispatch(func() {
|
w.window.Dispatch(func() {
|
||||||
result = w.window.Dialog(wv.DialogTypeOpen, wv.DialogFlagDirectory, "Select Directory", "", "")
|
result = w.window.Dialog(wv.DialogTypeOpen, wv.DialogFlagDirectory, "Select Directory", "")
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
}()
|
}()
|
||||||
@@ -282,7 +282,7 @@ func (w *WebView) SelectDirectory() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SelectSaveFile opens a dialog that allows the user to select a file to save
|
// SelectSaveFile opens a dialog that allows the user to select a file to save
|
||||||
func (w *WebView) SelectSaveFile(title string, filter string) string {
|
func (w *WebView) SelectSaveFile() string {
|
||||||
var result string
|
var result string
|
||||||
// We need to run this on the main thread, however Dispatch is
|
// We need to run this on the main thread, however Dispatch is
|
||||||
// non-blocking so we launch this in a goroutine and wait for
|
// non-blocking so we launch this in a goroutine and wait for
|
||||||
@@ -291,7 +291,7 @@ func (w *WebView) SelectSaveFile(title string, filter string) string {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
w.window.Dispatch(func() {
|
w.window.Dispatch(func() {
|
||||||
result = w.window.Dialog(wv.DialogTypeSave, 0, title, "", filter)
|
result = w.window.Dialog(wv.DialogTypeSave, 0, "Save file", "")
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
}()
|
}()
|
||||||
@@ -329,14 +329,7 @@ func (w *WebView) NotifyEvent(event *messages.EventData) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double encode data to ensure everything is escaped correctly.
|
message := fmt.Sprintf("wails._.Notify('%s','%s')", event.Name, data)
|
||||||
data, err = json.Marshal(string(data))
|
|
||||||
if err != nil {
|
|
||||||
w.log.Errorf("Cannot marshal JSON data in event: %s ", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
message := "window.wails._.Notify('" + event.Name + "'," + string(data) + ")"
|
|
||||||
return w.evalJS(message)
|
return w.evalJS(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ static inline void CgoWebViewSetColor(void *w, uint8_t r, uint8_t g, uint8_t b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void CgoDialog(void *w, int dlgtype, int flags,
|
static inline void CgoDialog(void *w, int dlgtype, int flags,
|
||||||
char *title, char *arg, char *res, size_t ressz, char *filter) {
|
char *title, char *arg, char *res, size_t ressz) {
|
||||||
webview_dialog(w, dlgtype, flags,
|
webview_dialog(w, dlgtype, flags,
|
||||||
(const char*)title, (const char*) arg, res, ressz, filter);
|
(const char*)title, (const char*) arg, res, ressz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int CgoWebViewEval(void *w, char *js) {
|
static inline int CgoWebViewEval(void *w, char *js) {
|
||||||
@@ -186,7 +186,7 @@ type WebView interface {
|
|||||||
// Dialog() opens a system dialog of the given type and title. String
|
// Dialog() opens a system dialog of the given type and title. String
|
||||||
// argument can be provided for certain dialogs, such as alert boxes. For
|
// argument can be provided for certain dialogs, such as alert boxes. For
|
||||||
// alert boxes argument is a message inside the dialog box.
|
// alert boxes argument is a message inside the dialog box.
|
||||||
Dialog(dlgType DialogType, flags int, title string, arg string, filter string) string
|
Dialog(dlgType DialogType, flags int, title string, arg string) string
|
||||||
// Terminate() breaks the main UI loop. This method must be called from the main thread
|
// Terminate() breaks the main UI loop. This method must be called from the main thread
|
||||||
// only. See Dispatch() for more details.
|
// only. See Dispatch() for more details.
|
||||||
Terminate()
|
Terminate()
|
||||||
@@ -311,7 +311,7 @@ func (w *webview) SetFullscreen(fullscreen bool) {
|
|||||||
C.CgoWebViewSetFullscreen(w.w, C.int(boolToInt(fullscreen)))
|
C.CgoWebViewSetFullscreen(w.w, C.int(boolToInt(fullscreen)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string, filter string) string {
|
func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string) string {
|
||||||
const maxPath = 4096
|
const maxPath = 4096
|
||||||
titlePtr := C.CString(title)
|
titlePtr := C.CString(title)
|
||||||
defer C.free(unsafe.Pointer(titlePtr))
|
defer C.free(unsafe.Pointer(titlePtr))
|
||||||
@@ -319,10 +319,8 @@ func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string
|
|||||||
defer C.free(unsafe.Pointer(argPtr))
|
defer C.free(unsafe.Pointer(argPtr))
|
||||||
resultPtr := (*C.char)(C.calloc((C.size_t)(unsafe.Sizeof((*C.char)(nil))), (C.size_t)(maxPath)))
|
resultPtr := (*C.char)(C.calloc((C.size_t)(unsafe.Sizeof((*C.char)(nil))), (C.size_t)(maxPath)))
|
||||||
defer C.free(unsafe.Pointer(resultPtr))
|
defer C.free(unsafe.Pointer(resultPtr))
|
||||||
filterPtr := C.CString(filter)
|
|
||||||
defer C.free(unsafe.Pointer(filterPtr))
|
|
||||||
C.CgoDialog(w.w, C.int(dlgType), C.int(flags), titlePtr,
|
C.CgoDialog(w.w, C.int(dlgType), C.int(flags), titlePtr,
|
||||||
argPtr, resultPtr, C.size_t(maxPath), filterPtr)
|
argPtr, resultPtr, C.size_t(maxPath))
|
||||||
return C.GoString(resultPtr)
|
return C.GoString(resultPtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ struct webview_priv
|
|||||||
#define DEFAULT_URL \
|
#define DEFAULT_URL \
|
||||||
"data:text/" \
|
"data:text/" \
|
||||||
"html,%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang=%22en%22%3E%0A%3Chead%3E%" \
|
"html,%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang=%22en%22%3E%0A%3Chead%3E%" \
|
||||||
"3Cmeta%20charset=%22utf-8%22%3E%3Cmeta%20http-equiv=%22IE=edge%22%" \
|
"3Cmeta%20charset=%22utf-8%22%3E%3Cmeta%20http-equiv=%22IE=edge%22%" \
|
||||||
"20content=%22IE=edge%22%3E%3C%2Fhead%3E%0A%3Cbody%3E%3Cdiv%20id=%22app%22%" \
|
"20content=%22IE=edge%22%3E%3C%2Fhead%3E%0A%3Cbody%3E%3Cdiv%20id=%22app%22%" \
|
||||||
"3E%3C%2Fdiv%3E%3Cscript%20type=%22text%2Fjavascript%22%3E%3C%2Fscript%3E%" \
|
"3E%3C%2Fdiv%3E%3Cscript%20type=%22text%2Fjavascript%22%3E%3C%2Fscript%3E%" \
|
||||||
"3C%2Fbody%3E%0A%3C%2Fhtml%3E"
|
"3C%2Fbody%3E%0A%3C%2Fhtml%3E"
|
||||||
@@ -174,7 +174,7 @@ struct webview_priv
|
|||||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||||
enum webview_dialog_type dlgtype, int flags,
|
enum webview_dialog_type dlgtype, int flags,
|
||||||
const char *title, const char *arg,
|
const char *title, const char *arg,
|
||||||
char *result, size_t resultsz, char *filter);
|
char *result, size_t resultsz);
|
||||||
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
||||||
void *arg);
|
void *arg);
|
||||||
WEBVIEW_API void webview_terminate(struct webview *w);
|
WEBVIEW_API void webview_terminate(struct webview *w);
|
||||||
@@ -418,7 +418,7 @@ struct webview_priv
|
|||||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||||
enum webview_dialog_type dlgtype, int flags,
|
enum webview_dialog_type dlgtype, int flags,
|
||||||
const char *title, const char *arg,
|
const char *title, const char *arg,
|
||||||
char *result, size_t resultsz, char *filter)
|
char *result, size_t resultsz)
|
||||||
{
|
{
|
||||||
GtkWidget *dlg;
|
GtkWidget *dlg;
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
@@ -438,17 +438,6 @@ struct webview_priv
|
|||||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||||
(dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ? "_Open" : "_Save"),
|
(dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ? "_Open" : "_Save"),
|
||||||
GTK_RESPONSE_ACCEPT, NULL);
|
GTK_RESPONSE_ACCEPT, NULL);
|
||||||
if (filter[0] != '\0') {
|
|
||||||
GtkFileFilter *file_filter = gtk_file_filter_new();
|
|
||||||
gchar **filters = g_strsplit(filter, ",", -1);
|
|
||||||
gint i;
|
|
||||||
for(i = 0; filters && filters[i]; i++) {
|
|
||||||
gtk_file_filter_add_pattern(file_filter, filters[i]);
|
|
||||||
}
|
|
||||||
gtk_file_filter_set_name(file_filter, filter);
|
|
||||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), file_filter);
|
|
||||||
g_strfreev(filters);
|
|
||||||
}
|
|
||||||
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dlg), FALSE);
|
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dlg), FALSE);
|
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||||
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dlg), TRUE);
|
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dlg), TRUE);
|
||||||
@@ -1238,7 +1227,7 @@ struct webview_priv
|
|||||||
}
|
}
|
||||||
VariantInit(&myURL);
|
VariantInit(&myURL);
|
||||||
myURL.vt = VT_BSTR;
|
myURL.vt = VT_BSTR;
|
||||||
// #ifndef UNICODE
|
// #ifndef UNICODE
|
||||||
{
|
{
|
||||||
wchar_t *buffer = webview_to_utf16(webPageName);
|
wchar_t *buffer = webview_to_utf16(webPageName);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -1248,9 +1237,9 @@ struct webview_priv
|
|||||||
myURL.bstrVal = SysAllocString(buffer);
|
myURL.bstrVal = SysAllocString(buffer);
|
||||||
GlobalFree(buffer);
|
GlobalFree(buffer);
|
||||||
}
|
}
|
||||||
// #else
|
// #else
|
||||||
// myURL.bstrVal = SysAllocString(webPageName);
|
// myURL.bstrVal = SysAllocString(webPageName);
|
||||||
// #endif
|
// #endif
|
||||||
if (!myURL.bstrVal)
|
if (!myURL.bstrVal)
|
||||||
{
|
{
|
||||||
badalloc:
|
badalloc:
|
||||||
@@ -1288,7 +1277,7 @@ struct webview_priv
|
|||||||
if (!SafeArrayAccessData(sfArray, (void **)&pVar))
|
if (!SafeArrayAccessData(sfArray, (void **)&pVar))
|
||||||
{
|
{
|
||||||
pVar->vt = VT_BSTR;
|
pVar->vt = VT_BSTR;
|
||||||
// #ifndef UNICODE
|
// #ifndef UNICODE
|
||||||
{
|
{
|
||||||
wchar_t *buffer = webview_to_utf16(url);
|
wchar_t *buffer = webview_to_utf16(url);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -1298,9 +1287,9 @@ struct webview_priv
|
|||||||
bstr = SysAllocString(buffer);
|
bstr = SysAllocString(buffer);
|
||||||
GlobalFree(buffer);
|
GlobalFree(buffer);
|
||||||
}
|
}
|
||||||
// #else
|
// #else
|
||||||
// bstr = SysAllocString(url);
|
// bstr = SysAllocString(url);
|
||||||
// #endif
|
// #endif
|
||||||
if ((pVar->bstrVal = bstr))
|
if ((pVar->bstrVal = bstr))
|
||||||
{
|
{
|
||||||
htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
|
htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
|
||||||
@@ -1421,8 +1410,6 @@ struct webview_priv
|
|||||||
wc.hInstance = hInstance;
|
wc.hInstance = hInstance;
|
||||||
wc.lpfnWndProc = wndproc;
|
wc.lpfnWndProc = wndproc;
|
||||||
wc.lpszClassName = classname;
|
wc.lpszClassName = classname;
|
||||||
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100));
|
|
||||||
wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(100));
|
|
||||||
RegisterClassEx(&wc);
|
RegisterClassEx(&wc);
|
||||||
|
|
||||||
style = WS_OVERLAPPEDWINDOW;
|
style = WS_OVERLAPPEDWINDOW;
|
||||||
@@ -1457,12 +1444,12 @@ struct webview_priv
|
|||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
||||||
#else
|
#else
|
||||||
w->priv.hwnd =
|
w->priv.hwnd =
|
||||||
CreateWindowEx(0, classname, w->title, style, rect.left, rect.top,
|
CreateWindowEx(0, classname, w->title, style, rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (w->priv.hwnd == 0)
|
if (w->priv.hwnd == 0)
|
||||||
{
|
{
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
@@ -1479,7 +1466,8 @@ struct webview_priv
|
|||||||
#else
|
#else
|
||||||
SetWindowText(w->priv.hwnd, w->title);
|
SetWindowText(w->priv.hwnd, w->title);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ShowWindow(w->priv.hwnd, SW_SHOWDEFAULT);
|
ShowWindow(w->priv.hwnd, SW_SHOWDEFAULT);
|
||||||
UpdateWindow(w->priv.hwnd);
|
UpdateWindow(w->priv.hwnd);
|
||||||
SetFocus(w->priv.hwnd);
|
SetFocus(w->priv.hwnd);
|
||||||
@@ -1506,11 +1494,6 @@ struct webview_priv
|
|||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
{
|
{
|
||||||
// Disable refresh when pressing F5 on windows
|
|
||||||
if (msg.wParam == VK_F5)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HRESULT r = S_OK;
|
HRESULT r = S_OK;
|
||||||
IWebBrowser2 *webBrowser2;
|
IWebBrowser2 *webBrowser2;
|
||||||
IOleObject *browser = *w->priv.browser;
|
IOleObject *browser = *w->priv.browser;
|
||||||
@@ -1620,7 +1603,7 @@ struct webview_priv
|
|||||||
|
|
||||||
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
||||||
{
|
{
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
wchar_t *u16title = webview_to_utf16(title);
|
wchar_t *u16title = webview_to_utf16(title);
|
||||||
if (u16title == NULL)
|
if (u16title == NULL)
|
||||||
{
|
{
|
||||||
@@ -1628,11 +1611,12 @@ struct webview_priv
|
|||||||
}
|
}
|
||||||
SetWindowText(w->priv.hwnd, u16title);
|
SetWindowText(w->priv.hwnd, u16title);
|
||||||
GlobalFree(u16title);
|
GlobalFree(u16title);
|
||||||
#else
|
#else
|
||||||
SetWindowText(w->priv.hwnd, title);
|
SetWindowText(w->priv.hwnd, title);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
||||||
{
|
{
|
||||||
if (w->priv.is_fullscreen == !!fullscreen)
|
if (w->priv.is_fullscreen == !!fullscreen)
|
||||||
@@ -1793,7 +1777,7 @@ struct webview_priv
|
|||||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||||
enum webview_dialog_type dlgtype, int flags,
|
enum webview_dialog_type dlgtype, int flags,
|
||||||
const char *title, const char *arg,
|
const char *title, const char *arg,
|
||||||
char *result, size_t resultsz, char *filter)
|
char *result, size_t resultsz)
|
||||||
{
|
{
|
||||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
||||||
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
||||||
@@ -1833,32 +1817,6 @@ struct webview_priv
|
|||||||
FOS_NOTESTFILECREATE | FOS_NODEREFERENCELINKS |
|
FOS_NOTESTFILECREATE | FOS_NODEREFERENCELINKS |
|
||||||
FOS_FORCESHOWHIDDEN | FOS_DEFAULTNOMINIMODE;
|
FOS_FORCESHOWHIDDEN | FOS_DEFAULTNOMINIMODE;
|
||||||
}
|
}
|
||||||
if (filter[0] != '\0')
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int i=0;
|
|
||||||
char* token;
|
|
||||||
char* filter_dup = strdup(filter);
|
|
||||||
for (count=1; filter[count]; filter[count]==',' ? count++ : *filter++);
|
|
||||||
COMDLG_FILTERSPEC rgSpec[count];
|
|
||||||
char* filters[count];
|
|
||||||
token = strtok(filter_dup, ",");
|
|
||||||
while(token != NULL)
|
|
||||||
{
|
|
||||||
filters[i] = token;
|
|
||||||
token = strtok(NULL, ",");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
for (int i=0; i < count; i++) {
|
|
||||||
wchar_t *wFilter = (wchar_t *)malloc(4096);
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, filters[i], -1, wFilter, 4096);
|
|
||||||
rgSpec[i].pszName = wFilter;
|
|
||||||
rgSpec[i].pszSpec = wFilter;
|
|
||||||
}
|
|
||||||
if (dlg->lpVtbl->SetFileTypes(dlg, count, rgSpec) != S_OK) {
|
|
||||||
goto error_dlg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dlg->lpVtbl->GetOptions(dlg, &opts) != S_OK)
|
if (dlg->lpVtbl->GetOptions(dlg, &opts) != S_OK)
|
||||||
{
|
{
|
||||||
goto error_dlg;
|
goto error_dlg;
|
||||||
@@ -1969,26 +1927,22 @@ struct webview_priv
|
|||||||
[script setValue:self forKey:@"external"];
|
[script setValue:self forKey:@"external"];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void webview_run_input_open_panel(id self, SEL cmd, id webview,
|
static void webview_run_input_open_panel(id self, SEL cmd, id webview,
|
||||||
id listener, BOOL allowMultiple)
|
id listener, BOOL allowMultiple) {
|
||||||
{
|
|
||||||
char filename[256] = "";
|
char filename[256] = "";
|
||||||
struct webview *w =
|
struct webview *w =
|
||||||
(struct webview *)objc_getAssociatedObject(self, "webview");
|
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||||
|
|
||||||
webview_dialog(w, WEBVIEW_DIALOG_TYPE_OPEN, WEBVIEW_DIALOG_FLAG_FILE, "", "",
|
webview_dialog(w, WEBVIEW_DIALOG_TYPE_OPEN, WEBVIEW_DIALOG_FLAG_FILE, "", "",
|
||||||
filename, 255, "");
|
filename, 255);
|
||||||
filename[255] = '\0';
|
if (strlen(filename)) {
|
||||||
if (strlen(filename) > 0)
|
|
||||||
{
|
|
||||||
[listener chooseFilename:[NSString stringWithUTF8String:filename]];
|
[listener chooseFilename:[NSString stringWithUTF8String:filename]];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
[listener cancel];
|
[listener cancel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void webview_external_invoke(id self, SEL cmd, id arg)
|
static void webview_external_invoke(id self, SEL cmd, id arg)
|
||||||
{
|
{
|
||||||
struct webview *w =
|
struct webview *w =
|
||||||
@@ -2001,7 +1955,7 @@ struct webview_priv
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
w->external_invoke_cb(w, [(NSString *)(arg) UTF8String]);
|
w->external_invoke_cb(w, [(NSString *)(arg)UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
WEBVIEW_API int webview_init(struct webview *w)
|
WEBVIEW_API int webview_init(struct webview *w)
|
||||||
@@ -2240,16 +2194,12 @@ struct webview_priv
|
|||||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||||
enum webview_dialog_type dlgtype, int flags,
|
enum webview_dialog_type dlgtype, int flags,
|
||||||
const char *title, const char *arg,
|
const char *title, const char *arg,
|
||||||
char *result, size_t resultsz, char *filter)
|
char *result, size_t resultsz)
|
||||||
{
|
{
|
||||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
||||||
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
||||||
{
|
{
|
||||||
NSSavePanel *panel;
|
NSSavePanel *panel;
|
||||||
NSString *filter_str = [NSString stringWithUTF8String:filter];
|
|
||||||
filter_str = [filter_str stringByReplacingOccurrencesOfString:@"*."
|
|
||||||
withString:@""];
|
|
||||||
NSArray *fileTypes = [filter_str componentsSeparatedByString:@","];
|
|
||||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN)
|
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN)
|
||||||
{
|
{
|
||||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||||
@@ -2262,10 +2212,6 @@ struct webview_priv
|
|||||||
{
|
{
|
||||||
[openPanel setCanChooseFiles:YES];
|
[openPanel setCanChooseFiles:YES];
|
||||||
[openPanel setCanChooseDirectories:NO];
|
[openPanel setCanChooseDirectories:NO];
|
||||||
if(filter[0] != NULL)
|
|
||||||
{
|
|
||||||
[openPanel setAllowedFileTypes:fileTypes];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[openPanel setResolvesAliases:NO];
|
[openPanel setResolvesAliases:NO];
|
||||||
[openPanel setAllowsMultipleSelection:NO];
|
[openPanel setAllowsMultipleSelection:NO];
|
||||||
@@ -2279,10 +2225,6 @@ struct webview_priv
|
|||||||
[panel setShowsHiddenFiles:YES];
|
[panel setShowsHiddenFiles:YES];
|
||||||
[panel setExtensionHidden:NO];
|
[panel setExtensionHidden:NO];
|
||||||
[panel setCanSelectHiddenExtension:NO];
|
[panel setCanSelectHiddenExtension:NO];
|
||||||
if(filter[0] != NULL)
|
|
||||||
{
|
|
||||||
[panel setAllowedFileTypes:fileTypes];
|
|
||||||
}
|
|
||||||
[panel setTreatsFilePackagesAsDirectories:YES];
|
[panel setTreatsFilePackagesAsDirectories:YES];
|
||||||
[panel beginSheetModalForWindow:w->priv.window
|
[panel beginSheetModalForWindow:w->priv.window
|
||||||
completionHandler:^(NSInteger result) {
|
completionHandler:^(NSInteger result) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "github.com/wailsapp/wails/lib/interfaces"
|
import "github.com/wailsapp/wails/lib/interfaces"
|
||||||
import "strings"
|
|
||||||
|
|
||||||
// Dialog exposes an interface to native dialogs
|
// Dialog exposes an interface to native dialogs
|
||||||
type Dialog struct {
|
type Dialog struct {
|
||||||
@@ -16,16 +15,8 @@ func NewDialog(renderer interfaces.Renderer) *Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SelectFile prompts the user to select a file
|
// SelectFile prompts the user to select a file
|
||||||
func (r *Dialog) SelectFile(params ...string) string {
|
func (r *Dialog) SelectFile() string {
|
||||||
title := "Select File"
|
return r.renderer.SelectFile()
|
||||||
filter := ""
|
|
||||||
if len(params) > 0 {
|
|
||||||
title = params[0]
|
|
||||||
}
|
|
||||||
if len(params) > 1 {
|
|
||||||
filter = strings.Replace(params[1], " ", "", -1)
|
|
||||||
}
|
|
||||||
return r.renderer.SelectFile(title, filter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectDirectory prompts the user to select a directory
|
// SelectDirectory prompts the user to select a directory
|
||||||
@@ -34,14 +25,6 @@ func (r *Dialog) SelectDirectory() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SelectSaveFile prompts the user to select a file for saving
|
// SelectSaveFile prompts the user to select a file for saving
|
||||||
func (r *Dialog) SelectSaveFile(params ...string) string {
|
func (r *Dialog) SelectSaveFile() string {
|
||||||
title := "Select Save"
|
return r.renderer.SelectSaveFile()
|
||||||
filter := ""
|
|
||||||
if len(params) > 0 {
|
|
||||||
title = params[0]
|
|
||||||
}
|
|
||||||
if len(params) > 1 {
|
|
||||||
filter = strings.Replace(params[1], " ", "", -1)
|
|
||||||
}
|
|
||||||
return r.renderer.SelectSaveFile(title, filter)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "os"
|
import homedir "github.com/mitchellh/go-homedir"
|
||||||
|
|
||||||
// FileSystem exposes file system utilities to the runtime
|
// FileSystem exposes file system utilities to the runtime
|
||||||
type FileSystem struct{}
|
type FileSystem struct {}
|
||||||
|
|
||||||
// NewFileSystem creates a new FileSystem struct
|
// NewFileSystem creates a new FileSystem struct
|
||||||
func NewFileSystem() *FileSystem {
|
func NewFileSystem() *FileSystem {
|
||||||
@@ -12,5 +12,5 @@ func NewFileSystem() *FileSystem {
|
|||||||
|
|
||||||
// HomeDir returns the user's home directory
|
// HomeDir returns the user's home directory
|
||||||
func (r *FileSystem) HomeDir() (string, error) {
|
func (r *FileSystem) HomeDir() (string, error) {
|
||||||
return os.UserHomeDir()
|
return homedir.Dir()
|
||||||
}
|
}
|
||||||
|
|||||||
2799
runtime/js/package-lock.json
generated
2799
runtime/js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wailsapp/runtime",
|
"name": "@wailsapp/runtime",
|
||||||
"version": "1.0.11",
|
"version": "1.0.10",
|
||||||
"description": "Wails Javascript runtime library",
|
"description": "Wails Javascript runtime library",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"types": "runtime.d.ts",
|
"types": "runtime.d.ts",
|
||||||
@@ -25,4 +25,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dts-gen": "^0.5.8"
|
"dts-gen": "^0.5.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
runtime/js/runtime/runtime.d.ts
vendored
12
runtime/js/runtime/runtime.d.ts
vendored
@@ -6,12 +6,12 @@ declare const wailsapp__runtime: {
|
|||||||
OpenURL(url: string): Promise<any>;
|
OpenURL(url: string): Promise<any>;
|
||||||
};
|
};
|
||||||
Events: {
|
Events: {
|
||||||
Acknowledge(eventName: string): void;
|
Acknowledge(eventName: string): void;
|
||||||
Emit(eventName: string, data?: any): void;
|
Emit(eventName: string): void;
|
||||||
Heartbeat(eventName: string, timeInMilliseconds: number, callback: (data?: any) => void): void;
|
Heartbeat(eventName: string, timeInMilliseconds: number, callback: () => void): void;
|
||||||
On(eventName: string, callback: (data?: any) => void): void;
|
On(eventName: string, callback: () => void): void;
|
||||||
OnMultiple(eventName: string, callback: (data?: any) => void, maxCallbacks: number): void;
|
OnMultiple(eventName: string, callback: () => void, maxCallbacks: number): void;
|
||||||
Once(eventName: string, callback: (data?: any) => void): void;
|
Once(eventName: string, callback: () => void): void;
|
||||||
};
|
};
|
||||||
Init(callback: () => void): void;
|
Init(callback: () => void): void;
|
||||||
Log: {
|
Log: {
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
echo "**** Checking if Wails passes unit tests ****"
|
|
||||||
if ! go test ./...
|
|
||||||
then
|
|
||||||
echo ""
|
|
||||||
echo "ERROR: Unit tests failed!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build runtime
|
# Build runtime
|
||||||
echo "**** Building Runtime ****"
|
echo "**** Building Runtime ****"
|
||||||
cd runtime/js
|
cd runtime/js
|
||||||
@@ -23,23 +15,9 @@ cd lib/renderer
|
|||||||
mewn
|
mewn
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
|
|
||||||
cd cmd/wails
|
|
||||||
echo "**** Checking if Wails compiles ****"
|
|
||||||
if ! go build .
|
|
||||||
then
|
|
||||||
echo ""
|
|
||||||
echo "ERROR: Build failed!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "**** Installing Wails locally ****"
|
echo "**** Installing Wails locally ****"
|
||||||
if ! go install
|
cd cmd/wails
|
||||||
then
|
go install
|
||||||
echo ""
|
|
||||||
echo "ERROR: Install failed!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
echo "**** Tidying the mods! ****"
|
echo "**** Tidying the mods! ****"
|
||||||
|
|||||||
Reference in New Issue
Block a user