8.7 KiB
What's new in v3?
!!! note The features that will be included in the v3 release may change from this list.
Multiple Windows
It's now possible to create multiple windows and configure each one independently.
package main
import (
_ "embed"
"log"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed assets/*
var assets embed.FS
func main() {
app := application.New(application.Options{
Name: "Multi Window Demo",
Assets: application.AssetOptions{
FS: assets,
},
})
window1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Window 1",
})
window2 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Window 2",
})
// load the embedded html from the embed.FS
window1.SetURL("/")
window1.Center()
// Load an external URL
window2.SetURL("https://wails.app")
err := app.Run()
if err != nil {
log.Fatal(err.Error())
}
}
Systrays
Systrays allow you to add an icon in the system tray area of your desktop and have the following features:
- Attach window (the window will be centered to the systray icon)
- Full menu support
- Light/Dark mode icons
package main
import (
_ "embed"
"log"
"runtime"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/icons"
)
func main() {
app := application.New(application.Options{
Name: "Systray Demo",
Mac: application.MacOptions{
ActivationPolicy: application.ActivationPolicyAccessory,
},
})
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Width: 500,
Height: 800,
Frameless: true,
AlwaysOnTop: true,
Hidden: true,
Windows: application.WindowsWindow{
HiddenOnTaskbar: true,
},
})
systemTray := app.NewSystemTray()
// Support for template icons on macOS
if runtime.GOOS == "darwin" {
systemTray.SetTemplateIcon(icons.SystrayMacTemplate)
} else {
// Support for light/dark mode icons
systemTray.SetDarkModeIcon(icons.SystrayDark)
systemTray.SetIcon(icons.SystrayLight)
}
// Support for menu
myMenu := app.NewMenu()
myMenu.Add("Hello World!").OnClick(func(_ *application.Context) {
println("Hello World!")
})
systemTray.SetMenu(myMenu)
// This will center the window to the systray icon with a 5px offset
// It will automatically be shown when the systray icon is clicked
// and hidden when the window loses focus
systemTray.AttachWindow(window).WindowOffset(5)
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
Plugins
Plugins allow you to extend the functionality of the Wails system. Not only can plugin methods be used in Go, but also called from Javascript. Included plugins:
- kvstore - A key/value store
- browser - open links in a browser
- log - custom logger
- oauth - handles oauth authentication and supports 60 providers
- single_instance - only allow one copy of your app to be run
- sqlite - add a sqlite db to your app. Uses the modernc pure go library
- start_at_login - Register/Unregister your application to start at login
Improved bindings generation
v3 uses a new static analyser to generate bindings. This makes it extremely fast and maintains comments and parameter names in your bindings. By default, bindings are generated with calls using IDs instead of strings. This provides a performance boost and allows for using obfuscation tools such as garble.
Bindings are generated by simply running wails3 generate bindings
in the
project directory.
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import { main } from "./models";
window.go = window.go || {};
window.go.main = {
GreetService: {
/**
* GreetService.Greet
* Greet greets a person
* @param name {string}
* @returns {Promise<string>}
**/
Greet: function (name) {
wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0));
},
/**
* GreetService.GreetPerson
* GreetPerson greets a person
* @param person {main.Person}
* @returns {Promise<string>}
**/
GreetPerson: function (person) {
wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0));
},
},
};
Improved build system
In v2, the build system was completely opaque and hard to customise. In v3, it's possible to build everything using standard Go tooling.
All the heavy lifting that the v2 build system did, such as icon generation, have been added as tool commands in the CLI. We have incorporated Taskfile into the CLI to orchestrate these calls to bring the same developer experience as v2. However, this approach brings the ultimate balance of flexibility and ease of use as you can now customise the build process to your needs.
You can even use make if that's your thing!
build:darwin:
summary: Builds the application
platforms:
- darwin
cmds:
- task: pre-build
- task: build-frontend
- go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}}
- task: post-build
env:
CGO_CFLAGS: "-mmacosx-version-min=10.13"
CGO_LDFLAGS: "-mmacosx-version-min=10.13"
MACOSX_DEPLOYMENT_TARGET: "10.13"
Improved events
Events are now emitted for a lot of the runtime operations, allowing you to hook into application/system events. Cross-platform (common) events are also emitted where there are common platform events, allowing you to write the same event handling methods cross platform.
Event hooks can also be registered. These are like the On
method but are
synchronous and allow you to cancel the event. An example of this would be to
show a confirmation dialog before closing a window.
package main
import (
_ "embed"
"log"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
//go:embed assets
var assets embed.FS
func main() {
app := application.New(application.Options{
Name: "Events Demo",
Description: "A demo of the Events API",
Assets: application.AssetOptions{
FS: assets,
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
// Custom event handling
app.Events.On("myevent", func(e *application.WailsEvent) {
log.Printf("[Go] WailsEvent received: %+v\n", e)
})
// OS specific application events
app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
println("events.Mac.ApplicationDidFinishLaunching fired!")
})
// Platform agnostic events
app.On(events.Common.ApplicationStarted, func(event *application.Event) {
println("events.Common.ApplicationStarted fired!")
})
win1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Takes 3 attempts to close me!",
})
var countdown = 3
// Register a hook to cancel the window closing
win1.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
countdown--
if countdown == 0 {
println("Closing!")
return
}
println("Nope! Not closing!")
e.Cancel()
})
win1.On(events.Common.WindowFocus, func(e *application.WindowEvent) {
println("[Event] Window focus!")
})
err := app.Run()
if err != nil {
log.Fatal(err.Error())
}
}
Wails Markup Language (wml)
An experimental feature to call runtime methods using plain html, similar to htmx.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Wails ML Demo</title>
</head>
<body style="margin-top:50px; color: white; background-color: #191919">
<h2>Wails ML Demo</h2>
<p>This application contains no Javascript!</p>
<button data-wml-event="button-pressed">Press me!</button>
<button data-wml-event="delete-things" data-wml-confirm="Are you sure?">
Delete all the things!
</button>
<button data-wml-window="Close" data-wml-confirm="Are you sure?">
Close the Window?
</button>
<button data-wml-window="Center">Center</button>
<button data-wml-window="Minimise">Minimise</button>
<button data-wml-window="Maximise">Maximise</button>
<button data-wml-window="UnMaximise">UnMaximise</button>
<button data-wml-window="Fullscreen">Fullscreen</button>
<button data-wml-window="UnFullscreen">UnFullscreen</button>
<button data-wml-window="Restore">Restore</button>
<div
style="width: 200px; height: 200px; border: 2px solid white;"
data-wml-event="hover"
data-wml-trigger="mouseover"
>
Hover over me
</div>
</body>
</html>