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()` |  |
+|`mac.TitleBarHidden()` |  |
+|`mac.TitleBarHiddenInset()` |  |
+
+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