diff --git a/README.md b/README.md index c8641ea3..11b3ac1f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ - [1. Internationalization](#nav-1) - [2. Table of Contents](#nav-2) -- [3. Introductions](#nav-3) +- [3. Introduction](#nav-3) - [3.1 Official Website](#nav-3-1) - [4. Features](#nav-4) - [5. Sponsors](#nav-5) diff --git a/v2/cmd/wails/internal/commands/build/build.go b/v2/cmd/wails/internal/commands/build/build.go index b8d3798f..e537c4ec 100644 --- a/v2/cmd/wails/internal/commands/build/build.go +++ b/v2/cmd/wails/internal/commands/build/build.go @@ -5,11 +5,15 @@ import ( "io" "os" "os/exec" + "path/filepath" "runtime" "strings" "text/tabwriter" "time" + "github.com/wailsapp/wails/v2/cmd/wails/internal" + "github.com/wailsapp/wails/v2/internal/gomod" + "github.com/wailsapp/wails/v2/internal/system" "github.com/leaanthony/clir" @@ -129,8 +133,8 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) { } } - if runtime.GOOS == "darwin" && !experimental { - return fmt.Errorf("MacOS version coming soon!") + if runtime.GOOS == "linux" && !experimental { + return fmt.Errorf("Linux version coming soon!") } // Webview2 installer strategy (download by default) @@ -205,6 +209,11 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) { fmt.Fprintf(w, "\n") w.Flush() + err = checkGoModVersion(logger) + if err != nil { + return err + } + return doBuild(buildOptions) }) } @@ -228,3 +237,29 @@ func doBuild(buildOptions *build.Options) error { return nil } + +func checkGoModVersion(logger *clilogger.CLILogger) error { + cwd, err := os.Getwd() + if err != nil { + return err + } + gomodFilename := filepath.Join(cwd, "go.mod") + gomodData, err := os.ReadFile(gomodFilename) + if err != nil { + return err + } + outOfSync, err := gomod.GoModOutOfSync(gomodData, internal.Version) + if err != nil { + return err + } + if !outOfSync { + return nil + } + gomodversion, err := gomod.GetWailsVersionFromModFile(gomodData) + if err != nil { + return err + } + + logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating it.\n", gomodversion.String(), internal.Version) + return nil +} diff --git a/v2/cmd/wails/internal/commands/dev/dev.go b/v2/cmd/wails/internal/commands/dev/dev.go index 0b760cca..3fdeb5da 100644 --- a/v2/cmd/wails/internal/commands/dev/dev.go +++ b/v2/cmd/wails/internal/commands/dev/dev.go @@ -113,8 +113,8 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error { } } - if runtime.GOOS == "darwin" && !experimental { - return fmt.Errorf("MacOS version coming soon!") + if runtime.GOOS == "linux" && !experimental { + return fmt.Errorf("Linux version coming soon!") } cwd, err := os.Getwd() diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/frontend/src/global.css b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/frontend/src/global.css index 3827664c..3bd7b1f1 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/frontend/src/global.css +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/frontend/src/global.css @@ -2,7 +2,7 @@ html { text-align: center; color: white; - background-color: rgba(0, 0, 0, 255); + background-color: rgba(0, 0, 0, 0); width: 100%; height: 100%; } diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/main.tmpl.go b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/main.tmpl.go index 89a4cecb..71e2fd21 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/main.tmpl.go +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/main.tmpl.go @@ -4,6 +4,8 @@ import ( "embed" "log" + "github.com/wailsapp/wails/v2/pkg/options/mac" + "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/logger" "github.com/wailsapp/wails/v2/pkg/options" @@ -13,6 +15,9 @@ import ( //go:embed frontend/dist var assets embed.FS +//go:embed build/appicon.png +var icon []byte + func main() { // Create an instance of the app structure app := NewApp() @@ -31,7 +36,7 @@ func main() { Frameless: false, StartHidden: false, HideWindowOnClose: false, - RGBA: &options.RGBA{R: 255, G: 255, B: 255, A: 255}, + RGBA: &options.RGBA{R: 0, G: 0, B: 0, A: 0}, Assets: assets, LogLevel: logger.DEBUG, OnStartup: app.startup, @@ -46,6 +51,17 @@ func main() { WindowIsTranslucent: false, DisableWindowIcon: false, }, + Mac: &mac.Options{ + TitleBar: mac.TitleBarHiddenInset(), + Appearance: mac.NSAppearanceNameDarkAqua, + WebviewIsTransparent: true, + WindowIsTranslucent: true, + About: &mac.AboutInfo{ + Title: "My Application", + Message: "© 2021 Me", + Icon: icon, + }, + }, }) if err != nil { diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/frontend/src/main.css b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/frontend/src/main.css index 1a73a0da..e4c79486 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/frontend/src/main.css +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/frontend/src/main.css @@ -1,5 +1,5 @@ html { - background-color: rgba(33, 37, 43, 1); + background-color: rgba(33, 37, 43, 0); text-align: center; color: white; } diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/main.tmpl.go b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/main.tmpl.go index 28d7826d..b5742a46 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/main.tmpl.go +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/main.tmpl.go @@ -4,6 +4,8 @@ import ( "embed" "log" + "github.com/wailsapp/wails/v2/pkg/options/mac" + "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/logger" "github.com/wailsapp/wails/v2/pkg/options" @@ -13,6 +15,9 @@ import ( //go:embed frontend/src var assets embed.FS +//go:embed build/appicon.png +var icon []byte + func main() { // Create an instance of the app structure app := NewApp() @@ -31,7 +36,7 @@ func main() { Frameless: false, StartHidden: false, HideWindowOnClose: false, - RGBA: &options.RGBA{R: 255, G: 255, B: 255, A: 255}, + RGBA: &options.RGBA{R: 0, G: 0, B: 0, A: 0}, Assets: assets, LogLevel: logger.DEBUG, OnStartup: app.startup, @@ -46,6 +51,16 @@ func main() { WindowIsTranslucent: false, DisableWindowIcon: false, }, + Mac: &mac.Options{ + TitleBar: mac.TitleBarHiddenInset(), + WebviewIsTransparent: true, + WindowIsTranslucent: true, + About: &mac.AboutInfo{ + Title: "Vanilla Template", + Message: "Part of the Wails projects", + Icon: icon, + }, + }, }) if err != nil { diff --git a/v2/go.mod b/v2/go.mod index 8c122d6a..164632f8 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -13,6 +13,7 @@ require ( github.com/gofiber/fiber/v2 v2.17.0 github.com/gofiber/websocket/v2 v2.0.8 github.com/golang/protobuf v1.5.2 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.1.2 // indirect github.com/gorilla/websocket v1.4.1 github.com/imdario/mergo v0.3.12 @@ -56,11 +57,11 @@ require ( github.com/go-git/gcfg v1.5.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/google/go-cmp v0.5.5 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/klauspost/compress v1.12.2 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect github.com/mattn/go-runewidth v0.0.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect diff --git a/v2/go.sum b/v2/go.sum index 0a548f1c..8dd91f46 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -103,8 +103,9 @@ github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8 github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 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 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -161,6 +162,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIEYnpFFONrrCcAIWNUNoFhUfMqAGY= github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= @@ -282,10 +285,12 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/v2/internal/appng/app_dev.go b/v2/internal/appng/app_dev.go index da715a3d..98856e19 100644 --- a/v2/internal/appng/app_dev.go +++ b/v2/internal/appng/app_dev.go @@ -18,7 +18,6 @@ import ( "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/internal/signal" pkglogger "github.com/wailsapp/wails/v2/pkg/logger" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -27,7 +26,6 @@ import ( type App struct { frontend frontend.Frontend logger *logger.Logger - signal *signal.Manager options *options.App menuManager *menumanager.Manager diff --git a/v2/internal/appng/app_production.go b/v2/internal/appng/app_production.go index 7e404d35..cdc14518 100644 --- a/v2/internal/appng/app_production.go +++ b/v2/internal/appng/app_production.go @@ -5,6 +5,7 @@ package appng import ( "context" + "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" @@ -12,7 +13,6 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend/runtime" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" - "github.com/wailsapp/wails/v2/internal/signal" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -20,7 +20,6 @@ import ( type App struct { frontend frontend.Frontend logger *logger.Logger - signal *signal.Manager options *options.App menuManager *menumanager.Manager @@ -36,9 +35,6 @@ type App struct { func (a *App) Run() error { err := a.frontend.Run(a.ctx) - if a.shutdownCallback != nil { - a.shutdownCallback(a.ctx) - } return err } diff --git a/v2/internal/frontend/desktop/darwin/AppDelegate.h b/v2/internal/frontend/desktop/darwin/AppDelegate.h index 3799aae0..7760b09a 100644 --- a/v2/internal/frontend/desktop/darwin/AppDelegate.h +++ b/v2/internal/frontend/desktop/darwin/AppDelegate.h @@ -9,11 +9,12 @@ #define AppDelegate_h #import +#import "WailsContext.h" @interface AppDelegate : NSResponder @property bool alwaysOnTop; -@property (retain) NSWindow* mainWindow; +@property (retain) WailsWindow* mainWindow; @end diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 8bee9b95..3cfbb853 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -49,6 +49,7 @@ void* NewMenu(const char* name); void AppendSubmenu(void* parent, void* child); void AppendRole(void *inctx, void *inMenu, int role); void SetAsApplicationMenu(void *inctx, void *inMenu); +void UpdateApplicationMenu(void *inctx); void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen); void* AppendMenuItem(void* inctx, void* nsmenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index c9af9c31..816fe225 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -14,6 +14,8 @@ WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug) { + [NSApplication sharedApplication]; + WailsContext *result = [WailsContext new]; result.debug = debug; @@ -256,6 +258,14 @@ void SetAsApplicationMenu(void *inctx, void *inMenu) { ctx.applicationMenu = menu; } +void UpdateApplicationMenu(void *inctx) { + WailsContext *ctx = (__bridge WailsContext*) inctx; + ON_MAIN_THREAD( + NSApplication *app = [NSApplication sharedApplication]; + [app setMainMenu:ctx.applicationMenu]; + ) +} + void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen) { WailsContext *ctx = (__bridge WailsContext*) inctx; NSString *_title = safeInit(title); diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.h b/v2/internal/frontend/desktop/darwin/WailsContext.h index 0c5232f7..c39687e9 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.h +++ b/v2/internal/frontend/desktop/darwin/WailsContext.h @@ -13,14 +13,12 @@ #define ON_MAIN_THREAD(str) dispatch_async(dispatch_get_main_queue(), ^{ str; }); #define unicode(input) [NSString stringWithFormat:@"%C", input] -#define STREQ(a,b) strcmp(a, b) == 0 - @interface WailsWindow : NSWindow - (BOOL)canBecomeKeyWindow; @end -@interface WailsContext : NSObject +@interface WailsContext : NSObject @property (retain) WailsWindow* mainWindow; @property (retain) WKWebView* webview; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.m b/v2/internal/frontend/desktop/darwin/WailsContext.m index ae755f9f..85da9009 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.m +++ b/v2/internal/frontend/desktop/darwin/WailsContext.m @@ -93,7 +93,7 @@ if ( currentFrame.size.height > self.maxSize.height ) currentFrame.size.height = self.maxSize.height; if ( currentFrame.size.height < self.minSize.height ) currentFrame.size.height = self.minSize.height; - [self.mainWindow setFrame:currentFrame display:TRUE animate:FALSE]; + [self.mainWindow setFrame:currentFrame display:YES animate:FALSE]; } @@ -135,41 +135,46 @@ self.urlRequests = [NSMutableDictionary new]; - NSWindowStyleMask styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + NSWindowStyleMask styleMask = NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; if (frameless) { styleMask = NSWindowStyleMaskBorderless; + titlebarAppearsTransparent = true; + hideTitle = true; } else { - if (resizable) { - styleMask |= NSWindowStyleMaskResizable; + if (!hideTitleBar) { + styleMask |= NSWindowStyleMaskTitled; + } + + if (fullscreen) { + styleMask |= NSWindowStyleMaskFullScreen; + } + + if( fullSizeContent || frameless || titlebarAppearsTransparent ) { + styleMask |= NSWindowStyleMaskFullSizeContentView; } } - if (fullscreen) { - styleMask |= NSWindowStyleMaskFullScreen; - } - if( fullSizeContent || frameless || titlebarAppearsTransparent ) { - styleMask |= NSWindowStyleMaskFullSizeContentView; + if (resizable) { + styleMask |= NSWindowStyleMaskResizable; } self.mainWindow = [[[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO] autorelease]; - - if (frameless) { - return; - } - - if (useToolbar) { + + if (!frameless && useToolbar) { id toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"]; [toolbar autorelease]; [toolbar setShowsBaselineSeparator:!hideToolbarSeparator]; [self.mainWindow setToolbar:toolbar]; + } [self.mainWindow setTitleVisibility:hideTitle]; [self.mainWindow setTitlebarAppearsTransparent:titlebarAppearsTransparent]; - [self.mainWindow canBecomeKeyWindow]; + +// [self.mainWindow canBecomeKeyWindow]; id contentView = [self.mainWindow contentView]; if (windowIsTranslucent) { @@ -203,7 +208,7 @@ config.suppressesIncrementalRendering = true; [config setURLSchemeHandler:self forURLScheme:@"wails"]; - [config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"]; +// [config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"]; WKUserContentController* userContentController = [WKUserContentController new]; [userContentController addScriptMessageHandler:self name:@"external"]; @@ -233,6 +238,8 @@ [self.webview setValue:[NSNumber numberWithBool:!webviewIsTransparent] forKey:@"drawsBackground"]; } + [self.webview setNavigationDelegate:self]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setBool:FALSE forKey:@"NSAutomaticQuoteSubstitutionEnabled"]; @@ -390,6 +397,10 @@ } +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { + processMessage("DomReady"); +} + - (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message { NSString *m = message.body; diff --git a/v2/internal/frontend/desktop/darwin/WailsMenu.m b/v2/internal/frontend/desktop/darwin/WailsMenu.m index 0e2162dd..cebb31c4 100644 --- a/v2/internal/frontend/desktop/darwin/WailsMenu.m +++ b/v2/internal/frontend/desktop/darwin/WailsMenu.m @@ -60,7 +60,10 @@ switch(role) { case AppMenu: { - NSString *appName = [[NSProcessInfo processInfo] processName]; + NSString *appName = [NSRunningApplication currentApplication].localizedName; + if( appName == nil ) { + appName = [[NSProcessInfo processInfo] processName]; + } WailsMenu *appMenu = [[WailsMenu new] initWithNSTitle:appName]; id quitTitle = [@"Quit " stringByAppendingString:appName]; NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand]; diff --git a/v2/internal/frontend/desktop/darwin/WindowDelegate.m b/v2/internal/frontend/desktop/darwin/WindowDelegate.m index 549413e4..60cff434 100644 --- a/v2/internal/frontend/desktop/darwin/WindowDelegate.m +++ b/v2/internal/frontend/desktop/darwin/WindowDelegate.m @@ -9,10 +9,11 @@ #import #import "WindowDelegate.h" #import "message.h" +#import "WailsContext.h" @implementation WindowDelegate -- (BOOL)windowShouldClose:(NSWindow *)sender { +- (BOOL)windowShouldClose:(WailsWindow *)sender { [sender orderOut:nil]; if( self.hideOnClose == false ) { processMessage("Q"); diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index 2e989066..265a7aef 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -214,6 +214,9 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) { func (f *Frontend) Quit() { f.mainWindow.Quit() + if f.frontendOptions.OnShutdown != nil { + f.frontendOptions.OnShutdown(f.ctx) + } } type EventNotify struct { @@ -235,6 +238,14 @@ func (f *Frontend) Notify(name string, data ...interface{}) { } func (f *Frontend) processMessage(message string) { + + if message == "DomReady" { + if f.frontendOptions.OnDomReady != nil { + f.frontendOptions.OnDomReady(f.ctx) + } + return + } + result, err := f.dispatcher.ProcessMessage(message, f) if err != nil { f.logger.Error(err.Error()) diff --git a/v2/internal/frontend/desktop/darwin/main.m b/v2/internal/frontend/desktop/darwin/main.m index 3b78740e..a7200f6f 100644 --- a/v2/internal/frontend/desktop/darwin/main.m +++ b/v2/internal/frontend/desktop/darwin/main.m @@ -32,7 +32,7 @@ void processCallback(int callbackID) { void processURLRequest(void *ctx, const char* url) { NSLog(@"processURLRequest called"); const char myByteArray[] = { 0x3c,0x68,0x31,0x3e,0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64,0x21,0x3c,0x2f,0x68,0x31,0x3e }; - ProcessURLResponse(ctx, url, "text/html", myByteArray, 21); + ProcessURLResponse(ctx, url, "text/html", (void*)myByteArray, 21); } unsigned char _Users_username_Pictures_SaltBae_png[] = { @@ -200,17 +200,17 @@ unsigned int _Users_username_Pictures_SaltBae_png_len = 1863; int main(int argc, const char * argv[]) { // insert code here... - int frameless = 0; - int resizable = 1; + int frameless = 1; + int resizable = 0; int fullscreen = 0; int fullSizeContent = 1; int hideTitleBar = 0; - int titlebarAppearsTransparent = 1; + int titlebarAppearsTransparent = 0; int hideTitle = 0; - int useToolbar = 1; - int hideToolbarSeparator = 1; - int webviewIsTransparent = 0; - int alwaysOnTop = 1; + int useToolbar = 0; + int hideToolbarSeparator = 0; + int webviewIsTransparent = 1; + int alwaysOnTop = 0; int hideWindowOnClose = 0; const char* appearance = "NSAppearanceNameDarkAqua"; int windowIsTranslucent = 1; diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index 722df0ea..8afb63fb 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -130,5 +130,6 @@ func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) { } func (f *Frontend) MenuUpdateApplicationMenu() { - //processMenu(f.mainWindow, f.mainWindow.applicationMenu) + f.MenuSetApplicationMenu(f.frontendOptions.Menu) + f.mainWindow.UpdateApplicationMenu() } diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index 4bd65665..5cf9e465 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -215,19 +215,12 @@ func (w *Window) Size() (int, int) { return parseIntDuo(temp) } -//func (w *Window) parseMenu(inMenu *menu.Menu) { -// for index, item := range inMenu.Items { -// switch item.Type { -// case menu.TextType: -// // Create NSMenuItem -// // Append to NSMenu -// // Keep track of index -// } -// } -//} - func (w *Window) SetApplicationMenu(inMenu *menu.Menu) { mainMenu := NewNSMenu(w.context, "") processMenu(mainMenu, inMenu) C.SetAsApplicationMenu(w.context, mainMenu.nsmenu) } + +func (w *Window) UpdateApplicationMenu() { + C.UpdateApplicationMenu(w.context) +} diff --git a/v2/internal/signal/signal.go b/v2/internal/signal/signal.go index 6d38d89c..f6db19cd 100644 --- a/v2/internal/signal/signal.go +++ b/v2/internal/signal/signal.go @@ -35,7 +35,7 @@ func NewManager(ctx context.Context, cancel context.CancelFunc, bus *servicebus. result := &Manager{ bus: bus, - logger: logger.CustomLogger("Event Manager"), + logger: logger.CustomLogger("Signal Manager"), signalchannel: make(chan os.Signal, 2), ctx: ctx, cancel: cancel, @@ -49,7 +49,7 @@ func NewManager(ctx context.Context, cancel context.CancelFunc, bus *servicebus. func (m *Manager) Start() { // Hook into interrupts - gosignal.Notify(m.signalchannel, os.Interrupt, syscall.SIGTERM) + gosignal.Notify(m.signalchannel, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) m.wg.Add(1) diff --git a/v2/pkg/buildassets/buildassets.go b/v2/pkg/buildassets/buildassets.go index 138b387f..008ca0ab 100644 --- a/v2/pkg/buildassets/buildassets.go +++ b/v2/pkg/buildassets/buildassets.go @@ -2,10 +2,11 @@ package buildassets import ( "embed" - "github.com/leaanthony/debme" - "github.com/leaanthony/gosod" "os" "path/filepath" + + "github.com/leaanthony/debme" + "github.com/leaanthony/gosod" ) //go:embed build @@ -50,3 +51,17 @@ func RegenerateAppIcon(target string) error { } return a.CopyFile("appicon.png", target, 0644) } + +func RegeneratePlist(targetDir string, projectName string) error { + darwinAssets, err := debme.FS(assets, "build/darwin") + if err != nil { + return err + } + templateDir := gosod.New(darwinAssets) + err = templateDir.Extract(targetDir, &assetData{Name: projectName}) + if err != nil { + return err + } + + return nil +} diff --git a/v2/pkg/commands/build/base.go b/v2/pkg/commands/build/base.go index 1f443315..ec8c7f1e 100644 --- a/v2/pkg/commands/build/base.go +++ b/v2/pkg/commands/build/base.go @@ -298,7 +298,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error { if v != "" { v += " " } - v += "-I" + buildBaseDir + v += "-mmacosx-version-min=10.13" return v }) // Use upsertEnv so we don't overwrite user's CGO_CXXFLAGS @@ -313,6 +313,17 @@ func (b *BaseBuilder) CompileProject(options *Options) error { cmd.Env = upsertEnv(cmd.Env, "CGO_ENABLED", func(v string) string { return "1" }) + if runtime.GOOS == "darwin" { + // Set the minimum Mac SDK to 10.13 + cmd.Env = upsertEnv(cmd.Env, "CGO_LDFLAGS", func(v string) string { + if v != "" { + v += " " + } + v += "-mmacosx-version-min=10.13" + + return v + }) + } } cmd.Env = upsertEnv(cmd.Env, "GOOS", func(v string) string { diff --git a/v2/pkg/commands/build/build.go b/v2/pkg/commands/build/build.go index a64858ae..9af037bc 100644 --- a/v2/pkg/commands/build/build.go +++ b/v2/pkg/commands/build/build.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "runtime" + "strings" "github.com/wailsapp/wails/v2/internal/fs" @@ -209,6 +210,18 @@ func Build(options *Options) (string, error) { return "", err } - return options.CompiledBinary, nil + result := options.CompiledBinary + + if options.Pack && options.Platform == "darwin" { + sr := strings.Split(result, "/") + for i := len(sr) - 1; i >= 0; i-- { + if strings.Contains(sr[i], ".app") { + result = strings.Join(sr[:i+1], "/") + break + } + } + } + + return result, nil } diff --git a/v2/pkg/commands/build/packager.go b/v2/pkg/commands/build/packager.go index 59816650..8587a28e 100644 --- a/v2/pkg/commands/build/packager.go +++ b/v2/pkg/commands/build/packager.go @@ -1,16 +1,12 @@ package build import ( - "bytes" "fmt" "image" - "io/ioutil" "os" "path" "path/filepath" "runtime" - "strings" - "text/template" "github.com/leaanthony/winicon" "github.com/tc-hib/winres" @@ -113,7 +109,7 @@ func packageApplicationForDarwin(options *Options) error { } // Generate Icons - err = processApplicationIcon(resourceDir, options.ProjectData.BuildDir) + err = processApplicationIcon(resourceDir, options.ProjectData.Path) if err != nil { return err } @@ -126,11 +122,11 @@ func packageApplicationForDarwin(options *Options) error { func processPList(options *Options, contentsDirectory string) error { // Check if plist already exists in project dir - plistFile := filepath.Join(options.ProjectData.BuildDir, "darwin", "Info.plist") - + plistFileDir := filepath.Join(options.ProjectData.Path, "build", "darwin") + plistFile := filepath.Join(plistFileDir, "Info.plist") // If the file doesn't exist, generate it if !fs.FileExists(plistFile) { - err := generateDefaultPlist(options, plistFile) + err := buildassets.RegeneratePlist(plistFileDir, options.ProjectData.Name) if err != nil { return err } @@ -141,65 +137,6 @@ func processPList(options *Options, contentsDirectory string) error { return fs.CopyFile(plistFile, targetFile) } -func generateDefaultPlist(options *Options, targetPlistFile string) error { - name := defaultString(options.ProjectData.Name, "WailsTest") - exe := defaultString(options.OutputFile, name) - version := "1.0.0" - author := defaultString(options.ProjectData.Author.Name, "Anonymous") - packageID := strings.Join([]string{"wails", name}, ".") - plistData := newPlistData(name, exe, packageID, version, author) - - tmpl := template.New("infoPlist") - plistTemplate := fs.RelativePath("./internal/packager/darwin/Info.plist") - infoPlist, err := ioutil.ReadFile(plistTemplate) - if err != nil { - return errors.Wrap(err, "Cannot open plist template") - } - _, err = tmpl.Parse(string(infoPlist)) - if err != nil { - return err - } - // Write the template to a buffer - var tpl bytes.Buffer - err = tmpl.Execute(&tpl, plistData) - if err != nil { - return err - } - - // Create the directory if it doesn't exist - err = fs.MkDirs(filepath.Dir(targetPlistFile)) - if err != nil { - return err - } - // Save the file - return ioutil.WriteFile(targetPlistFile, tpl.Bytes(), 0644) -} - -func defaultString(val string, defaultVal string) string { - if val != "" { - return val - } - return defaultVal -} - -type plistData struct { - Title string - Exe string - PackageID string - Version string - Author string -} - -func newPlistData(title, exe, packageID, version, author string) *plistData { - return &plistData{ - Title: title, - Exe: exe, - Version: version, - PackageID: packageID, - Author: author, - } -} - func processApplicationIcon(resourceDir string, iconsDir string) (err error) { appIcon := filepath.Join(iconsDir, "appicon.png") diff --git a/v2/pkg/options/default.go b/v2/pkg/options/default.go index df3f3d52..42e17c4a 100644 --- a/v2/pkg/options/default.go +++ b/v2/pkg/options/default.go @@ -2,6 +2,7 @@ package options import ( "github.com/wailsapp/wails/v2/pkg/logger" + "github.com/wailsapp/wails/v2/pkg/menu" ) // Default options for creating the App @@ -11,3 +12,8 @@ var Default = &App{ Logger: logger.NewDefaultLogger(), LogLevel: logger.INFO, } + +var defaultMacMenu = menu.NewMenuFromItems( + menu.AppMenu(), + menu.EditMenu(), +) diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 61c800d5..ce9a03a0 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -4,6 +4,7 @@ import ( "context" "embed" "log" + "runtime" "github.com/wailsapp/wails/v2/pkg/options/mac" "github.com/wailsapp/wails/v2/pkg/options/windows" @@ -94,4 +95,11 @@ func MergeDefaults(appoptions *App) { appoptions.Height = appoptions.MaxHeight } + switch runtime.GOOS { + case "darwin": + if appoptions.Menu == nil { + appoptions.Menu = defaultMacMenu + } + } + } diff --git a/website/blog/2021-11-06-v2-beta2-release-notes.mdx b/website/blog/2021-11-06-v2-beta2-release-notes.mdx new file mode 100644 index 00000000..eccce86f --- /dev/null +++ b/website/blog/2021-11-06-v2-beta2-release-notes.mdx @@ -0,0 +1,161 @@ +--- +slug: wails-v2-beta-for-mac +title: Wails v2 Beta for MacOS +authors: [leaanthony] +tags: [wails, v2] +--- + + +
+ +
+
+ +Today marks the first beta release of Wails v2 for Mac! It's taken quite a while to get to this point and I'm hoping +that today's release will give you something that's reasonably useful. There have been a number of twists and turns +to get to this point and I'm hoping, with your help, to iron out the crinkles and get the Mac port polished for the +final v2 release. + +You mean this isn't ready for production? For your use case, it may well be ready, but there are still a number of +known issues so keep your eye on [this project board](https://github.com/wailsapp/wails/projects/7) and if you would +like to contribute, you'd be very welcome! + +So what's new for Wails v2 for Mac vs v1? Hint: They're pretty similar to the Windows Beta :wink: + +### New Features + +
+ +
+
+ +There were a lot of requests for native menu support. Wails has finally got you covered. Application menus are now available +and include support for most native menu features. This includes standard menu items, checkboxes, radio groups, submenus +and separators. + +There were a huge number of requests in v1 for the ability to have greater control of the window itself. +I'm happy to announce that there's new runtime APIs specifically for this. +It's feature-rich and supports multi-monitor configurations. There is also an improved dialogs API: Now, you can have modern, native +dialogs with rich configuration to cater for all your dialog needs. + +### Mac Specific Options + +In addition to the normal application options, Wails v2 for Mac also brings some Mac extras: + + - Make your window all funky and translucent, like all the pretty swift apps! + - Highly customisable titlebar + - We support the NSAppearance options for the application + - Simple config to auto-create an "About" menu + +### No requirement to bundle assets + +A huge pain-point of v1 was the need to condense your entire application down to single JS & CSS files. I'm happy to +announce that for v2, there is no requirement to bundle assets, in any way, shape or form. Want to load a local image? Use an +`` tag with a local src path. Want to use a cool font? Copy it in and add the path to it in your CSS. + +> Wow, that sounds like a webserver... + +Yes, it works just like a webserver, except it isn't. + +> So how do I include my assets? + +You just pass a single `embed.FS` that contains all your assets into your application configuration. +They don't even need to be in the top directory - Wails will just work it out for you. + +### New Development Experience + +Now that assets don't need to be bundled, it's enabled a whole new development experience. The new `wails dev` +command will build and run your application, but instead of using the assets in the `embed.FS`, it loads them directly +from disk. + +It also provides the additional features: + + - Hot reload - Any changes to frontend assets will trigger and auto reload of the application frontend + - Auto rebuild - Any changes to your Go code will rebuild and relaunch your application + +In addition to this, a webserver will start on port 34115. This will serve your application to any browser that +connects to it. All connected web browsers will respond to system events like hot reload on asset change. + +In Go, we are used to dealing with structs in our applications. It's often useful to send structs to our frontend +and use them as state in our application. In v1, this was a very manual process and a bit of a burden on the +developer. I'm happy to announce that in v2, any application run in dev mode will automatically generate Typescript +models for all structs that are input or output parameters to bound methods. This enables seamless interchange of data +models between the two worlds. + +In addition to this, another JS module is dynamically generated wrapping all your bound methods. This provides +JSDoc for your methods, providing code completion and hinting in your IDE. It's really cool when you get data models +auto-imported when hitting tab in an auto-generated module wrapping your Go code! + +### Remote Templates + +
+ +
+
+ +Getting an application up and running quickly was always a key goal for the Wails project. When we launched, we tried +to cover a lot of the modern frameworks at the time: react, vue and angular. The world of frontend development is very +opinionated, fast moving and hard to keep on top of! As a result, we found our base templates getting out of date pretty +quickly and this caused a maintenance headache. It also meant that we didn't have cool modern templates for the latest +and greatest tech stacks. + +With v2, I wanted to empower the community by giving you the ability to create and host templates yourselves, rather +than rely on the Wails project. So now you can create projects using community supported templates! I hope this will +inspire developers to create a vibrant ecosystem of project templates. I'm really quite excited about what our developer +community can create! + +### Native M1 Support + +Thanks to the amazing support of [Mat Ryer](https://github.com/matryer/), the Wails project now supports M1 native +builds: + +
+ +
+
+ +You can also specify `darwin/amd64` as a target too: + +
+ +
+
+ +Oh, I almost forgot.... you can also do `darwin/universal`.... :wink: + +
+ +
+
+ +### Cross Compilation to Windows + +Because Wails v2 for Windows is pure Go, you can target Windows builds without docker. + +
+ +
+
+ + +### WKWebView Renderer + +V1 relied on a (now deprecated) WebView component. V2 uses the most recent WKWebKit component so expect the latest and greatest from Apple. + +### In Conclusion + +As I'd said in the Windows release notes, Wails v2 represents a new foundation for the project. +The aim of this release is to get feedback on the new approach, and to iron out any bugs before a full release. +Your input would be most welcome! Please direct any feedback to the [v2 Beta](https://github.com/wailsapp/wails/discussions/828) +discussion board. + +And finally, I'd like to give a special thank you to all the [project sponsors](/docs/credits#sponsors), including [JetBrains](https://www.jetbrains.com?from=Wails), +whose support drive the project in many ways behind the scenes. + +I look forward to seeing what people build with Wails in this next exciting phase of the project! + +Lea. + +PS: Linux users, you're next! + +PPS: If you or your company find Wails useful, please consider [sponsoring the project](https://github.com/sponsors/leaanthony). Thanks! diff --git a/website/docs/gettingstarted/installation.mdx b/website/docs/gettingstarted/installation.mdx index 5cd767d9..23750f3d 100644 --- a/website/docs/gettingstarted/installation.mdx +++ b/website/docs/gettingstarted/installation.mdx @@ -7,8 +7,9 @@ sidebar_position: 1 ## Supported Platforms - Windows 10 -- MacOS x64 & arm64 (due October '21) -- Linux (due December '21) +- MacOS 10.13+ (amd64) +- MacOS 11.0+ (arm64) +- Linux (due Jan '22) ## Dependencies @@ -47,7 +48,11 @@ import TabItem from "@theme/TabItem"; { label: "Linux", value: "Linux" }, ]} > - Coming Soon... + + Wails requires that the xcode command line tools are installed. This can be done by running:
+ + xcode-select --install +
Wails requires that the WebView2{" "} runtime is installed. Some Windows installations will already have this installed. You can check using the{" "} diff --git a/website/docs/guides/migrating.mdx b/website/docs/guides/migrating.mdx index e9800c92..bafc26ac 100644 --- a/website/docs/guides/migrating.mdx +++ b/website/docs/guides/migrating.mdx @@ -199,7 +199,7 @@ The format of the file is slightly different. Here is a comparison: | frontend / serve | | Removed | | tags | | Removed | | | wailsjsdir | The directory to generate wailsjs modules | -| | assetdir | The directory of the frontend assets for `dev` mode | +| | assetdir | The directory of the compiled frontend assets for `dev` mode |

diff --git a/website/docs/reference/cli.mdx b/website/docs/reference/cli.mdx index 8b299628..dfc75bed 100644 --- a/website/docs/reference/cli.mdx +++ b/website/docs/reference/cli.mdx @@ -74,6 +74,12 @@ Example: `wails build -clean -o myproject.exe` +:::info UPX on Apple Silicon + + There are [issues](https://github.com/upx/upx/issues/446) with using UPX with Apple Silicon. + +::: + ## doctor `wails doctor` will run diagnostics to ensure that your system is ready for development. @@ -135,6 +141,7 @@ Your system is ready for Wails development! | -debounce | The time to wait for reload after an asset change is detected | 100 (milliseconds) | | -devserverurl "url" | Use 3rd party dev server url, EG Vite | "http://localhost:34115" | | -appargs "args" | Arguments passed to the application in shell style | | +| -platform "platform" | Platform/Arch to target | `runtime.GOOS` | If the `assetdir`, `wailsjsdir`, `debounce` or `devserverurl` flags are provided on the command line, they are saved in `wails.json`, and become the defaults for subsequent invocations. diff --git a/website/docs/reference/menus.mdx b/website/docs/reference/menus.mdx index 96949456..7c637d89 100644 --- a/website/docs/reference/menus.mdx +++ b/website/docs/reference/menus.mdx @@ -5,7 +5,7 @@ sidebar_position: 4 # Menus It is possible to add an application menu to Wails projects. This is achieved by defining a [Menu](#menu) struct and -calling the runtime method [MenuSetApplicationMenu](/docs/reference/runtime/menu#menusetapplicationmenu). +setting the [`Menu`](/docs/reference/options#menu) option, or by calling the runtime method [MenuSetApplicationMenu](/docs/reference/runtime/menu#menusetapplicationmenu). It is also possible to dynamically update the menu, by updating the menu struct and calling [MenuUpdateApplicationMenu](/docs/reference/runtime/menu#menuupdateapplicationmenu). @@ -79,6 +79,7 @@ type MenuItem struct { | Checked | bool | Adds check to item (Checkbox & Radio types) | | SubMenu | [\*Menu](#menu) | Sets the submenu | | Click | [Callback](#callback) | Callback function when menu clicked | +| Role | string | Defines a [role](#roles) for this menu item. Mac only for now. | ### Accelerator @@ -231,3 +232,19 @@ type CallbackData struct { The function is given a `CallbackData` struct which indicates which menu item triggered the callback. This is useful when using radio groups that may share a callback. + +### Role + +:::info Roles + + Roles are currently supported on Mac only. + +::: + +A menu item may have a role, which is essentially a pre-defined menu item. We currently support the following roles: + +| Role | Description | +| ---- | ----------- | +| AppMenuRole | The standard Mac application menu. Can be created using `menu.AppMenu()` | +| EditMenuRole | The standard Mac edit menu. Can be created using `menu.EditMenu()` | + diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx index bc1e8df6..ebbd2665 100644 --- a/website/docs/reference/options.mdx +++ b/website/docs/reference/options.mdx @@ -28,6 +28,7 @@ func main() { StartHidden: false, HideWindowOnClose: false, RGBA: &options.RGBA{R: 0, G: 0, B: 0, A: 255}, + AlwaysOnTop: false, Assets: assets, Menu: app.applicationMenu(), Logger: nil, @@ -43,6 +44,24 @@ func main() { WindowIsTranslucent: false, DisableWindowIcon: false, }, + Mac: &mac.Options{ + TitleBar: &mac.TitleBar{ + TitlebarAppearsTransparent: true, + HideTitle: false, + HideTitleBar: false, + FullSizeContent: false, + UseToolbar: false, + HideToolbarSeparator: true, + }, + Appearance: mac.NSAppearanceNameDarkAqua, + WebviewIsTransparent: true, + WindowIsTranslucent: false, + About: &mac.AboutInfo{ + Title: "My Application", + Message: "© 2021 Me", + Icon: icon, + }, + }, }) if err != nil { log.Fatal(err) @@ -192,6 +211,8 @@ Type: \*menu.Menu The menu to be used by the application. More details about Menus in the [Menu Reference](/docs/reference/runtime/menu). +NOTE: On Mac, if no menu is specified, a default menu will be created. + ### Logger Name: Logger @@ -281,3 +302,153 @@ Name: DisableWindowIcon Type: bool Setting this to true will remove the icon in the top left corner of the title bar. + + +## Mac Specific Options + +### TitleBar + +Name: TitleBar + +Type: [*mac.TitleBar](#titlebar-struct) + +The TitleBar struct provides the ability to configure the look and feel of the title bar. + +### Appearance + +Name: Appearance + +Type: [AppearanceType](#appearance-type) + +Appearance is used to set the style of your app in accordance with Apple's [NSAppearance](https://developer.apple.com/documentation/appkit/nsappearancename?language=objc) names. + +### WebviewIsTransparent + +Name: WebviewIsTransparent + +Type: bool + +Setting this to `true` will make the webview background transparent when an alpha value of `0` is used. +This means that if you use `rgba(0,0,0,0)`, the host window will show through. +Often combined with [WindowIsTranslucent](#WindowIsTranslucent) to make frosty-looking applications. + +### WindowIsTranslucent + +Name: WindowIsTranslucent + +Type: bool + +Setting this to `true` will make the window background translucent. Often combined +with [WebviewIsTransparent](#WebviewIsTransparent) to make frosty-looking applications. + +### About + +Name: About + +Type: [About](#about-struct) + +This configuration lets you set the title, message and icon for the "About" menu item in the app menu created by the "AppMenu" role. + +#### Titlebar struct + +The titlebar of the application can be customised by using the TitleBar options: + +```go +type TitleBar struct { + TitlebarAppearsTransparent bool + HideTitle bool + HideTitleBar bool + FullSizeContent bool + UseToolbar bool + HideToolbarSeparator bool +} +``` + +| Name | Description | +| ---- | ----------- | +| TitlebarAppearsTransparent | Makes the titlebar transparent. [Apple Docs](https://developer.apple.com/documentation/appkit/nswindow/1419167-titlebarappearstransparent?language=objc) | +| HideTitle | Hides the title of the window. [Apple Docs](https://developer.apple.com/documentation/appkit/nswindowtitlevisibility?language=objc) | +| HideTitleBar | Removes [NSWindowStyleMaskTitled](https://developer.apple.com/documentation/appkit/nswindowstylemask/nswindowstylemasktitled/) from the style mask | +| FullSizeContent | Makes the webview fill the entire window. [Apple Docs](https://developer.apple.com/documentation/appkit/nswindowstylemask/nswindowstylemaskfullsizecontentview)| +| UseToolbar | Adds a default toolbar to the window. [Apple Docs](https://developer.apple.com/documentation/appkit/nstoolbar?language=objc) | +| HideToolbarSeparator | Removes the line beneath the toolbar. [Apple Docs](https://developer.apple.com/documentation/appkit/nstoolbar/1516954-showsbaselineseparator?language=objc) | + +Preconfigured titlebar settings are available: + +| Setting | Example | +| ------- | ------- | +|`mac.TitleBarDefault()` | ![](/img/reference/titlebar-default.png) | +|`mac.TitleBarHidden()` | ![](/img/reference/titlebar-hidden.png) | +|`mac.TitleBarHiddenInset()` | ![](/img/reference/titlebar-hidden-inset.png) | + +Example: +```go +Mac: &mac.Options{ + TitleBar: mac.TitleBarHiddenInset(), +} +``` + +Click [here](https://github.com/lukakerr/NSWindowStyles) for some inspiration on customising the titlebar. + +#### Appearance type + +You can specify the application's [appearance](https://developer.apple.com/documentation/appkit/nsappearance?language=objc). + +| Value | Description | +| --------------- | ------------------ | +| DefaultAppearance | DefaultAppearance uses the default system value | +| NSAppearanceNameAqua | The standard light system appearance | +| NSAppearanceNameDarkAqua | The standard dark system appearance | +| NSAppearanceNameVibrantLight | The light vibrant appearance | +| NSAppearanceNameAccessibilityHighContrastAqua | A high-contrast version of the standard light system appearance | +| NSAppearanceNameAccessibilityHighContrastDarkAqua | A high-contrast version of the standard dark system appearance | +| NSAppearanceNameAccessibilityHighContrastVibrantLight | A high-contrast version of the light vibrant appearance | +| NSAppearanceNameAccessibilityHighContrastVibrantDark | A high-contrast version of the dark vibrant appearance | + +Example: +```go +Mac: &mac.Options{ + Appearance: mac.NSAppearanceNameDarkAqua, +} +``` + +#### About struct + +```go +type AboutInfo struct { + Title string + Message string + Icon []byte +} +``` +If these settings are provided, an "About" menu item will appear in the app menu (when using the `AppMenu` role). +Given this configuration: +```go +//go:embed build/appicon.png +var icon []byte + +func main() { + err := wails.Run(&options.App{ + ... + Mac: &mac.Options{ + About: &mac.AboutInfo{ + Title: "My Application", + Message: "© 2021 Me", + Icon: icon, + }, + }, + }) +``` +The "About" menu item will appear in the app menu: + +
+ +
+
+ +When clicked, that will open an about message box: + +
+ +
+
diff --git a/website/docs/reference/project-config.mdx b/website/docs/reference/project-config.mdx index dad072cb..f27da3fe 100644 --- a/website/docs/reference/project-config.mdx +++ b/website/docs/reference/project-config.mdx @@ -9,7 +9,7 @@ The project config resides in the `wails.json` file in the project directory. Th ```json { "name": "[The project name]", - "assetdir": "[Relative path to your assets directory]", + "assetdir": "[Relative path to the directory containing the compiled assets]", "frontend:install": "[The command to install node dependencies, run in the frontend directory - often `npm install`]", "frontend:build": "[The command to build the assets, run in the frontend directory - often `npm run build`]", "frontend:dev": "[This command is run in a separate process on `wails dev`. Useful for 3rd party watchers]", diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index a50db626..fb98c762 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -63,7 +63,7 @@ const darkCodeTheme = require('prism-react-renderer/themes/palenight'); ({ announcementBar: { id: 'beta-message', - content: 'Wails v2 is currently Beta for Windows. Mac & Linux in progress.', + content: 'Wails v2 is currently Beta for Windows & Mac. Linux in progress.', backgroundColor: '#b00', textColor: '#FFF', isCloseable: false, diff --git a/website/static/img/build-cross-windows.png b/website/static/img/build-cross-windows.png new file mode 100644 index 00000000..ab488227 Binary files /dev/null and b/website/static/img/build-cross-windows.png differ diff --git a/website/static/img/build-darwin-amd.png b/website/static/img/build-darwin-amd.png new file mode 100644 index 00000000..6300d264 Binary files /dev/null and b/website/static/img/build-darwin-amd.png differ diff --git a/website/static/img/build-darwin-arm.png b/website/static/img/build-darwin-arm.png new file mode 100644 index 00000000..0bb72ae3 Binary files /dev/null and b/website/static/img/build-darwin-arm.png differ diff --git a/website/static/img/build-darwin-universal.png b/website/static/img/build-darwin-universal.png new file mode 100644 index 00000000..249be83c Binary files /dev/null and b/website/static/img/build-darwin-universal.png differ diff --git a/website/static/img/desktop-application-app-dark.svg b/website/static/img/desktop-application-app-dark.svg index 04917d4f..352e2386 100644 --- a/website/static/img/desktop-application-app-dark.svg +++ b/website/static/img/desktop-application-app-dark.svg @@ -1,6 +1,6 @@ - diff --git a/website/static/img/desktop-application-app.svg b/website/static/img/desktop-application-app.svg index 986ed183..e1b12275 100644 --- a/website/static/img/desktop-application-app.svg +++ b/website/static/img/desktop-application-app.svg @@ -1,6 +1,6 @@ - diff --git a/website/static/img/reference/about-dialog.png b/website/static/img/reference/about-dialog.png new file mode 100644 index 00000000..8af3ef91 Binary files /dev/null and b/website/static/img/reference/about-dialog.png differ diff --git a/website/static/img/reference/about-menu.png b/website/static/img/reference/about-menu.png new file mode 100644 index 00000000..6ac7166e Binary files /dev/null and b/website/static/img/reference/about-menu.png differ diff --git a/website/static/img/reference/titlebar-default.png b/website/static/img/reference/titlebar-default.png new file mode 100644 index 00000000..8204d3f9 Binary files /dev/null and b/website/static/img/reference/titlebar-default.png differ diff --git a/website/static/img/reference/titlebar-hidden-inset.png b/website/static/img/reference/titlebar-hidden-inset.png new file mode 100644 index 00000000..b3161367 Binary files /dev/null and b/website/static/img/reference/titlebar-hidden-inset.png differ diff --git a/website/static/img/reference/titlebar-hidden.png b/website/static/img/reference/titlebar-hidden.png new file mode 100644 index 00000000..c68db059 Binary files /dev/null and b/website/static/img/reference/titlebar-hidden.png differ diff --git a/website/static/img/remote-mac.png b/website/static/img/remote-mac.png new file mode 100644 index 00000000..c15aaf9c Binary files /dev/null and b/website/static/img/remote-mac.png differ diff --git a/website/static/img/wails-mac.png b/website/static/img/wails-mac.png new file mode 100644 index 00000000..4abe2558 Binary files /dev/null and b/website/static/img/wails-mac.png differ diff --git a/website/static/img/wails-menus-mac.png b/website/static/img/wails-menus-mac.png new file mode 100644 index 00000000..b9d9611f Binary files /dev/null and b/website/static/img/wails-menus-mac.png differ