diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index c70050276..760fd277f 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -56,7 +56,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-22.04, windows-latest, macos-latest, ubuntu-24.04]
- go-version: ['1.21']
+ go-version: ['1.23']
steps:
- name: Checkout code
diff --git a/v2/cmd/wails/internal/dev/dev.go b/v2/cmd/wails/internal/dev/dev.go
index 2f6b10a73..5cb62421b 100644
--- a/v2/cmd/wails/internal/dev/dev.go
+++ b/v2/cmd/wails/internal/dev/dev.go
@@ -153,7 +153,7 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error {
}()
// Watch for changes and trigger restartApp()
- debugBinaryProcess, err = doWatcherLoop(cwd, buildOptions, debugBinaryProcess, f, exitCodeChannel, quitChannel, f.DevServerURL(), legacyUseDevServerInsteadofCustomScheme)
+ debugBinaryProcess, err = doWatcherLoop(cwd, projectConfig.ReloadDirectories, buildOptions, debugBinaryProcess, f, exitCodeChannel, quitChannel, f.DevServerURL(), legacyUseDevServerInsteadofCustomScheme)
if err != nil {
return err
}
@@ -326,9 +326,9 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process
}
// doWatcherLoop is the main watch loop that runs while dev is active
-func doWatcherLoop(cwd string, buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL, legacyUseDevServerInsteadofCustomScheme bool) (*process.Process, error) {
+func doWatcherLoop(cwd string, reloadDirs string, buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL, legacyUseDevServerInsteadofCustomScheme bool) (*process.Process, error) {
// create the project files watcher
- watcher, err := initialiseWatcher(cwd)
+ watcher, err := initialiseWatcher(cwd, reloadDirs)
if err != nil {
logutils.LogRed("Unable to create filesystem watcher. Reloads will not occur.")
return nil, err
diff --git a/v2/cmd/wails/internal/dev/watcher.go b/v2/cmd/wails/internal/dev/watcher.go
index 4e7457ef9..e1161f87c 100644
--- a/v2/cmd/wails/internal/dev/watcher.go
+++ b/v2/cmd/wails/internal/dev/watcher.go
@@ -4,6 +4,7 @@ import (
"bufio"
"os"
"path/filepath"
+ "strings"
"github.com/wailsapp/wails/v2/internal/fs"
@@ -17,7 +18,7 @@ type Watcher interface {
}
// initialiseWatcher creates the project directory watcher that will trigger recompile
-func initialiseWatcher(cwd string) (*fsnotify.Watcher, error) {
+func initialiseWatcher(cwd, reloadDirs string) (*fsnotify.Watcher, error) {
// Ignore dot files, node_modules and build directories by default
ignoreDirs := getIgnoreDirs(cwd)
@@ -27,12 +28,22 @@ func initialiseWatcher(cwd string) (*fsnotify.Watcher, error) {
return nil, err
}
+ customDirs := dirs.AsSlice()
+ seperatedDirs := strings.Split(reloadDirs, ",")
+ for _, dir := range seperatedDirs {
+ customSub, err := fs.GetSubdirectories(filepath.Join(cwd, dir))
+ if err != nil {
+ return nil, err
+ }
+ customDirs = append(customDirs, customSub.AsSlice()...)
+ }
+
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
- for _, dir := range processDirectories(dirs.AsSlice(), ignoreDirs) {
+ for _, dir := range processDirectories(customDirs, ignoreDirs) {
err := watcher.Add(dir)
if err != nil {
return nil, err
diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go
index 58cd94ef0..89265c9b9 100644
--- a/v2/internal/app/app_dev.go
+++ b/v2/internal/app/app_dev.go
@@ -75,7 +75,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
loglevel := os.Getenv("loglevel")
if loglevel == "" {
- loglevelFlag = devFlags.String("loglevel", "debug", "Loglevel to use - Trace, Debug, Info, Warning, Error")
+ loglevelFlag = devFlags.String("loglevel", appoptions.LogLevel.String(), "Loglevel to use - Trace, Debug, Info, Warning, Error")
}
// If we weren't given the assetdir in the environment variables
@@ -91,8 +91,15 @@ func CreateApp(appoptions *options.App) (*App, error) {
if frontendDevServerURLFlag != nil {
frontendDevServerURL = *frontendDevServerURLFlag
}
- if loglevelFlag != nil {
- loglevel = *loglevelFlag
+ // Only override LogLevel if the flag was explicitly set
+ if loglevelFlag != nil && devFlags.Lookup("loglevel").Value.String() != appoptions.LogLevel.String() {
+ loggerLevel, err := pkglogger.StringToLogLevel(*loglevelFlag)
+ if err != nil {
+ return nil, err
+ }
+ if loggerLevel != appoptions.LogLevel {
+ myLogger.SetLogLevel(loggerLevel)
+ }
}
}
@@ -169,14 +176,6 @@ func CreateApp(appoptions *options.App) (*App, error) {
ctx = context.WithValue(ctx, "devserver", devServer)
}
- if loglevel != "" {
- level, err := pkglogger.StringToLogLevel(loglevel)
- if err != nil {
- return nil, err
- }
- myLogger.SetLogLevel(level)
- }
-
// Attach logger to context
ctx = context.WithValue(ctx, "logger", myLogger)
ctx = context.WithValue(ctx, "buildtype", "dev")
diff --git a/v2/internal/go-common-file-dialog/cfd/CommonFileDialog_nonWindows.go b/v2/internal/go-common-file-dialog/cfd/CommonFileDialog_nonWindows.go
index 04c7cbcfe..3ab969850 100644
--- a/v2/internal/go-common-file-dialog/cfd/CommonFileDialog_nonWindows.go
+++ b/v2/internal/go-common-file-dialog/cfd/CommonFileDialog_nonWindows.go
@@ -5,24 +5,24 @@ package cfd
import "fmt"
-var errUnsupported = fmt.Errorf("common file dialogs are only available on windows")
+var unsupportedError = fmt.Errorf("common file dialogs are only available on windows")
// TODO doc
func NewOpenFileDialog(config DialogConfig) (OpenFileDialog, error) {
- return nil, errUnsupported
+ return nil, unsupportedError
}
// TODO doc
func NewOpenMultipleFilesDialog(config DialogConfig) (OpenMultipleFilesDialog, error) {
- return nil, errUnsupported
+ return nil, unsupportedError
}
// TODO doc
func NewSelectFolderDialog(config DialogConfig) (SelectFolderDialog, error) {
- return nil, errUnsupported
+ return nil, unsupportedError
}
// TODO doc
func NewSaveFileDialog(config DialogConfig) (SaveFileDialog, error) {
- return nil, errUnsupported
+ return nil, unsupportedError
}
diff --git a/v2/internal/go-common-file-dialog/cfd/DialogConfig.go b/v2/internal/go-common-file-dialog/cfd/DialogConfig.go
index edefd4e13..9e06fb503 100644
--- a/v2/internal/go-common-file-dialog/cfd/DialogConfig.go
+++ b/v2/internal/go-common-file-dialog/cfd/DialogConfig.go
@@ -2,7 +2,11 @@
package cfd
-import "fmt"
+import (
+ "fmt"
+ "os"
+ "reflect"
+)
type FileFilter struct {
// The display name of the filter (That is shown to the user)
@@ -11,6 +15,9 @@ type FileFilter struct {
Pattern string
}
+// Never obfuscate the FileFilter type.
+var _ = reflect.TypeOf(FileFilter{})
+
type DialogConfig struct {
// The title of the dialog
Title string
@@ -69,6 +76,10 @@ func (config *DialogConfig) apply(dialog Dialog) (err error) {
}
if config.Folder != "" {
+ _, err = os.Stat(config.Folder)
+ if err != nil {
+ return
+ }
err = dialog.SetFolder(config.Folder)
if err != nil {
return
@@ -76,6 +87,10 @@ func (config *DialogConfig) apply(dialog Dialog) (err error) {
}
if config.DefaultFolder != "" {
+ _, err = os.Stat(config.DefaultFolder)
+ if err != nil {
+ return
+ }
err = dialog.SetDefaultFolder(config.DefaultFolder)
if err != nil {
return
diff --git a/v2/internal/go-common-file-dialog/cfd/errors.go b/v2/internal/go-common-file-dialog/cfd/errors.go
index 6f21fedbf..c097c8eb2 100644
--- a/v2/internal/go-common-file-dialog/cfd/errors.go
+++ b/v2/internal/go-common-file-dialog/cfd/errors.go
@@ -2,4 +2,6 @@ package cfd
import "errors"
-var ErrCancelled = errors.New("cancelled by user")
+var (
+ ErrorCancelled = errors.New("cancelled by user")
+)
diff --git a/v2/internal/go-common-file-dialog/cfd/iFileOpenDialog.go b/v2/internal/go-common-file-dialog/cfd/iFileOpenDialog.go
index f94a9c7ed..404dedc22 100644
--- a/v2/internal/go-common-file-dialog/cfd/iFileOpenDialog.go
+++ b/v2/internal/go-common-file-dialog/cfd/iFileOpenDialog.go
@@ -5,7 +5,7 @@ package cfd
import (
"github.com/go-ole/go-ole"
- "github.com/wailsapp/wails/v2/internal/go-common-file-dialog/util"
+ "github.com/google/uuid"
"syscall"
"unsafe"
)
@@ -106,7 +106,7 @@ func (fileOpenDialog *iFileOpenDialog) SetFileFilters(filter []FileFilter) error
}
func (fileOpenDialog *iFileOpenDialog) SetRole(role string) error {
- return fileOpenDialog.vtbl.setClientGuid(unsafe.Pointer(fileOpenDialog), util.StringToUUID(role))
+ return fileOpenDialog.vtbl.setClientGuid(unsafe.Pointer(fileOpenDialog), StringToUUID(role))
}
// This should only be callable when the user asks for a multi select because
@@ -177,7 +177,7 @@ func (vtbl *iFileOpenDialogVtbl) getResultsStrings(objPtr unsafe.Pointer) ([]str
return nil, err
}
if shellItemArray == nil {
- return nil, ErrCancelled
+ return nil, ErrorCancelled
}
defer shellItemArray.vtbl.release(unsafe.Pointer(shellItemArray))
count, err := shellItemArray.vtbl.getCount(unsafe.Pointer(shellItemArray))
@@ -194,3 +194,7 @@ func (vtbl *iFileOpenDialogVtbl) getResultsStrings(objPtr unsafe.Pointer) ([]str
}
return results, nil
}
+
+func StringToUUID(str string) *ole.GUID {
+ return ole.NewGUID(uuid.NewSHA1(uuid.Nil, []byte(str)).String())
+}
diff --git a/v2/internal/go-common-file-dialog/cfd/iFileSaveDialog.go b/v2/internal/go-common-file-dialog/cfd/iFileSaveDialog.go
index 3effeda25..ddee7b246 100644
--- a/v2/internal/go-common-file-dialog/cfd/iFileSaveDialog.go
+++ b/v2/internal/go-common-file-dialog/cfd/iFileSaveDialog.go
@@ -5,7 +5,6 @@ package cfd
import (
"github.com/go-ole/go-ole"
- "github.com/wailsapp/wails/v2/internal/go-common-file-dialog/util"
"unsafe"
)
@@ -77,7 +76,7 @@ func (fileSaveDialog *iFileSaveDialog) SetFileFilters(filter []FileFilter) error
}
func (fileSaveDialog *iFileSaveDialog) SetRole(role string) error {
- return fileSaveDialog.vtbl.setClientGuid(unsafe.Pointer(fileSaveDialog), util.StringToUUID(role))
+ return fileSaveDialog.vtbl.setClientGuid(unsafe.Pointer(fileSaveDialog), StringToUUID(role))
}
func (fileSaveDialog *iFileSaveDialog) SetDefaultExtension(defaultExtension string) error {
diff --git a/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go b/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go
index c548160d1..bdd459402 100644
--- a/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go
+++ b/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go
@@ -4,6 +4,7 @@
package cfd
import (
+ "fmt"
"github.com/go-ole/go-ole"
"syscall"
"unsafe"
@@ -57,7 +58,7 @@ func (vtbl *iShellItemArrayVtbl) getItemAt(objPtr unsafe.Pointer, index uintptr)
return "", err
}
if shellItem == nil {
- return "", ErrCancelled
+ return "", fmt.Errorf("shellItem is nil")
}
defer shellItem.vtbl.release(unsafe.Pointer(shellItem))
return shellItem.vtbl.getDisplayName(unsafe.Pointer(shellItem))
diff --git a/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go b/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go
index 8c88c297c..9107c1904 100644
--- a/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go
+++ b/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go
@@ -168,7 +168,7 @@ func (vtbl *iFileDialogVtbl) getResultString(objPtr unsafe.Pointer) (string, err
return "", err
}
if shellItem == nil {
- return "", ErrCancelled
+ return "", fmt.Errorf("shellItem is nil")
}
defer shellItem.vtbl.release(unsafe.Pointer(shellItem))
return shellItem.vtbl.getDisplayName(unsafe.Pointer(shellItem))
diff --git a/v2/internal/go-common-file-dialog/cfdutil/CFDUtil.go b/v2/internal/go-common-file-dialog/cfdutil/CFDUtil.go
index 655266bc3..bde52d743 100644
--- a/v2/internal/go-common-file-dialog/cfdutil/CFDUtil.go
+++ b/v2/internal/go-common-file-dialog/cfdutil/CFDUtil.go
@@ -10,9 +10,7 @@ func ShowOpenFileDialog(config cfd.DialogConfig) (string, error) {
if err != nil {
return "", err
}
- defer func() {
- _ = dialog.Release()
- }()
+ defer dialog.Release()
return dialog.ShowAndGetResult()
}
@@ -22,9 +20,7 @@ func ShowOpenMultipleFilesDialog(config cfd.DialogConfig) ([]string, error) {
if err != nil {
return nil, err
}
- defer func() {
- _ = dialog.Release()
- }()
+ defer dialog.Release()
return dialog.ShowAndGetResults()
}
@@ -34,9 +30,7 @@ func ShowPickFolderDialog(config cfd.DialogConfig) (string, error) {
if err != nil {
return "", err
}
- defer func() {
- _ = dialog.Release()
- }()
+ defer dialog.Release()
return dialog.ShowAndGetResult()
}
@@ -46,8 +40,6 @@ func ShowSaveFileDialog(config cfd.DialogConfig) (string, error) {
if err != nil {
return "", err
}
- defer func() {
- _ = dialog.Release()
- }()
+ defer dialog.Release()
return dialog.ShowAndGetResult()
}
diff --git a/v2/pkg/logger/logger.go b/v2/pkg/logger/logger.go
index abc288265..990dffe75 100644
--- a/v2/pkg/logger/logger.go
+++ b/v2/pkg/logger/logger.go
@@ -41,6 +41,24 @@ func StringToLogLevel(input string) (LogLevel, error) {
return result, nil
}
+// String returns the string representation of the LogLevel
+func (l LogLevel) String() string {
+ switch l {
+ case TRACE:
+ return "trace"
+ case DEBUG:
+ return "debug"
+ case INFO:
+ return "info"
+ case WARNING:
+ return "warning"
+ case ERROR:
+ return "error"
+ default:
+ return "debug"
+ }
+}
+
// Logger specifies the methods required to attach
// a logger to a Wails application
type Logger interface {
diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx
index 1fc21a5ff..023a2e89d 100644
--- a/website/src/pages/changelog.mdx
+++ b/website/src/pages/changelog.mdx
@@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added "Branding" section to `wails doctor` to correctly identify Windows 11 [#3891](https://github.com/wailsapp/wails/pull/3891) by [@ronen25](https://github.com/ronen25)
### Fixed
+- Fixed dev mode logging bug by @attperac in [#3972](https://wailsapp/wails/pull/3972)
+- Fixed `reloaddirs` wails.json config options by @atterpac in [#4005](https//github.com/wailsapp/wails/pull/4005)
- Fixed cross compilation failed with CGO [PR](https://github.com/wailsapp/wails/pull/3795) by [@fcying](https://github.com/fcying)
- Using go-webview2 v0.1.17 to fix native webview2loader issue, by @leaanthony
- Fixed example for macOS menu by @takuyahara in [PR](https://github.com/wailsapp/wails/pull/3847)
@@ -33,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed failed models.ts build due to non-json-encodable Go types [PR](https://github.com/wailsapp/wails/pull/3975) by [@pbnjay](https://github.com/pbnjay)
- Fixed more binding and typescript export bugs [PR](https://github.com/wailsapp/wails/pull/3978) by [@pbnjay](https://github.com/pbnjay)
- Fixed Dispatcher.ProcessMessage crash process instead of return error [PR](https://github.com/wailsapp/wails/pull/4016) [#4015](https://github.com/wailsapp/wails/issues/4015) by [@ronaldinho_x86](https://github.com/RonaldinhoL)
+- Fixed Windows SaveDialog crash by [@leaanthony](https://github.com/leaanthony)
### Changed
- Allow to specify macos-min-version externally. Implemented by @APshenkin in [PR](https://github.com/wailsapp/wails/pull/3756)
diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg
index be891bad3..1a5ace6f6 100644
--- a/website/static/img/sponsors.svg
+++ b/website/static/img/sponsors.svg
@@ -41,7 +41,7 @@ text {