diff --git a/v2/go.mod b/v2/go.mod index 60bf75abc1e..b9aff0612a3 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -1,6 +1,8 @@ module github.com/wailsapp/wails/v2 -go 1.18 +go 1.21 + +toolchain go1.21.1 require ( github.com/Masterminds/semver v1.5.0 diff --git a/v2/go.sum b/v2/go.sum index 7769626feec..dec24d1da9f 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -12,6 +12,7 @@ github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzX github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= github.com/MarvinJWendt/testza v0.4.3 h1:u2XaM4IqGp9dsdUmML8/Z791fu4yjQYzOiufOtJwTII= +github.com/MarvinJWendt/testza v0.4.3/go.mod h1:CpXaOfceNEYnLDtNIyTrPPcCpDJYqzZnu2aiA2Wp33U= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -69,6 +70,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -94,6 +96,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= +github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -119,8 +122,6 @@ github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRC github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js= github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8= -github.com/leaanthony/u v1.0.1 h1:tJLpf9EsuCgSB02ojRxg8KRqMgRN6mCTvFwI55kxRFE= -github.com/leaanthony/u v1.0.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI= github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ= @@ -262,6 +263,7 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/v2/internal/app/app_hybrid_server.go b/v2/internal/app/app_hybrid_server.go index a9a7b135ec6..f1880edcf7c 100644 --- a/v2/internal/app/app_hybrid_server.go +++ b/v2/internal/app/app_hybrid_server.go @@ -5,12 +5,7 @@ package app import ( "context" - "embed" "fmt" - iofs "io/fs" - "os" - "path/filepath" - "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" @@ -18,10 +13,8 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend/dispatcher" "github.com/wailsapp/wails/v2/internal/frontend/hybrid" "github.com/wailsapp/wails/v2/internal/frontend/runtime" - "github.com/wailsapp/wails/v2/internal/fs" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" - "github.com/wailsapp/wails/v2/internal/project" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -42,6 +35,10 @@ type App struct { ctx context.Context } +func (a *App) Shutdown() { + a.frontend.Quit() +} + func (a *App) Run() error { err := a.frontend.Run(a.ctx) if a.shutdownCallback != nil { @@ -50,75 +47,49 @@ func (a *App) Run() error { return err } -func (a *App) Shutdown() { - if a.shutdownCallback != nil { - a.shutdownCallback(a.ctx) - } - a.frontend.Quit() -} - // CreateApp creates the app! func CreateApp(appoptions *options.App) (*App, error) { - // Set up logger - myLogger := logger.New(appoptions.Logger) - myLogger.SetLogLevel(appoptions.LogLevel) + var err error - // If no assetdir has been defined, let's try to infer it from the project root and the asset FS. - assetdir, err := tryInferAssetDirFromFS(appoptions.Assets) - if err != nil { - return nil, err - } + ctx := context.Background() - host := "localhost" - port := int32(3112) + host, port := "localhost", int32(3112) if appoptions.Server != nil { host = appoptions.Server.Host port = appoptions.Server.Port } serverURI := fmt.Sprintf("%s:%d", host, port) - ctx := context.Background() ctx = context.WithValue(ctx, "starturl", serverURI) - - // This is to enable a backend server - // ctx = context.WithValue(ctx, "frontenddevserverurl", serverURI) - - myLogger.Info("Frontend available at '%s'", serverURI) - - // configure devserver ctx = context.WithValue(ctx, "devserver", fmt.Sprintf("%s:%d", host, port)) - // Let's override the assets to serve from on disk, if needed - absdir, err := filepath.Abs(assetdir) - if err != nil { - return nil, err - } - - myLogger.Info("Serving assets from disk: %s", absdir) - appoptions.Assets = os.DirFS(absdir) + // Merge default options + options.MergeDefaults(appoptions) - ctx = context.WithValue(ctx, "assetdir", assetdir) + debug := IsDebug() + ctx = context.WithValue(ctx, "debug", debug) - // Attach logger to context + // Set up logger + myLogger := logger.New(appoptions.Logger) + myLogger.Info("Frontend available at 'http://%s'", serverURI) + if IsDebug() { + myLogger.SetLogLevel(appoptions.LogLevel) + } else { + myLogger.SetLogLevel(appoptions.LogLevelProduction) + } ctx = context.WithValue(ctx, "logger", myLogger) - ctx = context.WithValue(ctx, "buildtype", "hybrid") - // Preflight checks + // Preflight Checks err = PreflightChecks(appoptions, myLogger) if err != nil { return nil, err } - // Merge default options - - options.MergeDefaults(appoptions) - - var menuManager *menumanager.Manager + // Create the menu manager + menuManager := menumanager.NewManager() // Process the application menu if appoptions.Menu != nil { - // Create the menu manager - menuManager = menumanager.NewManager() err = menuManager.SetApplicationMenu(appoptions.Menu) if err != nil { return nil, err @@ -128,13 +99,15 @@ func CreateApp(appoptions *options.App) (*App, error) { // Create binding exemptions - Ugly hack. There must be a better way bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady} appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions) - - err = generateBindings(appBindings) - if err != nil { - return nil, err - } eventHandler := runtime.NewEvents(myLogger) ctx = context.WithValue(ctx, "events", eventHandler) + // Attach logger to context + if debug { + ctx = context.WithValue(ctx, "buildtype", "debug") + } else { + ctx = context.WithValue(ctx, "buildtype", "production") + } + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler) appFrontend := hybrid.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) eventHandler.AddFrontend(appFrontend) @@ -146,64 +119,10 @@ func CreateApp(appoptions *options.App) (*App, error) { menuManager: menuManager, startupCallback: appoptions.OnStartup, shutdownCallback: appoptions.OnShutdown, + debug: debug, + options: appoptions, } - result.options = appoptions - return result, nil } - -func generateBindings(bindings *binding.Bindings) error { - - cwd, err := os.Getwd() - if err != nil { - return err - } - projectConfig, err := project.Load(cwd) - if err != nil { - return err - } - - targetDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "go") - err = os.RemoveAll(targetDir) - if err != nil { - return err - } - _ = fs.MkDirs(targetDir) - - err = bindings.GenerateGoBindings(targetDir) - if err != nil { - return err - } - return nil -} - -func tryInferAssetDirFromFS(assets iofs.FS) (string, error) { - if _, isEmbedFs := assets.(embed.FS); !isEmbedFs { - // We only infer the assetdir for embed.FS assets - return "", nil - } - - path, err := fs.FindPathToFile(assets, "index.html") - if err != nil { - return "", err - } - - path, err = filepath.Abs(path) - if err != nil { - return "", err - } - - if _, err := os.Stat(filepath.Join(path, "index.html")); err != nil { - if os.IsNotExist(err) { - err = fmt.Errorf( - "inferred assetdir '%s' does not exist or does not contain an 'index.html' file, "+ - "please specify it with -assetdir or set it in wails.json", - path) - } - return "", err - } - - return path, nil -} diff --git a/v2/internal/frontend/desktop/null/frontend.go b/v2/internal/frontend/desktop/null/frontend.go index fe19907af1b..b09a56b26d5 100644 --- a/v2/internal/frontend/desktop/null/frontend.go +++ b/v2/internal/frontend/desktop/null/frontend.go @@ -11,14 +11,17 @@ import ( // Frontend implements an empty Frontend that simply waits until the context is done. type Frontend struct { // Context - ctx context.Context + ctx context.Context + frontendOptions *options.App + done bool } // NewFrontend returns an initialized Frontend -func NewFrontend(ctx context.Context) *Frontend { +func NewFrontend(ctx context.Context, appoptions *options.App) *Frontend { return &Frontend{ - ctx: ctx, + frontendOptions: appoptions, + ctx: ctx, } } @@ -73,19 +76,25 @@ func (f *Frontend) WindowSetDarkTheme() { } // Run waits until the context is done and then exits -func (f *Frontend) Run(ctx context.Context) error { +func (f *Frontend) Run(ctx context.Context) (err error) { + err = nil + go func() { + if f.frontendOptions.OnStartup != nil { + f.frontendOptions.OnStartup(f.ctx) + } + }() for { select { case <-ctx.Done(): - break + return default: time.Sleep(1 * time.Millisecond) } if f.done { - break + return } } - return nil + } // WindowCenter does nothing diff --git a/v2/internal/frontend/hybrid/server.go b/v2/internal/frontend/hybrid/server.go index cd83fbf98aa..f4df3bd1cc3 100644 --- a/v2/internal/frontend/hybrid/server.go +++ b/v2/internal/frontend/hybrid/server.go @@ -17,5 +17,5 @@ import ( // New returns a new Server frontend // A server Frontend implementation contains a devserver.Frontend wrapping a null.Frontend func NewFrontend(ctx context.Context, appoptions *options.App, logger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) frontend.Frontend { - return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx)) + return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx, appoptions)) }