[v3] update docs to reflect changes from Manager API Refactoring (#4476)

* (docs) installation.mdx: update required Go version to 1.24

* (docs) update for Manager API Refactoring https://github.com/wailsapp/wails/pull/4359

* add entry in UNRELEASED_CHANGELOG.md to satisfy github actions

* thx coderabbitai

* thx coderabbitai
This commit is contained in:
Yules 2025-08-05 15:59:45 +02:00 committed by GitHub
commit c02ba8f5d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 120 additions and 94 deletions

View file

@ -116,7 +116,7 @@ func main() {
Name: "MyApp",
Assets: application.NewAssetsFS(assetsFS),
})
window := app.NewWebviewWindow(&application.WebviewWindowOptions{
window := app.Window.New(&application.WebviewWindowOptions{
Title: "Hello",
Width: 1024,
Height: 768,

View file

@ -31,7 +31,7 @@ application object itself is initialised once.
### Public API
```go
win := app.NewWebviewWindow(&application.WebviewWindowOptions{
win := app.Window.New(&application.WebviewWindowOptions{
Title: "Dashboard",
Width: 1280,
Height: 720,

View file

@ -18,7 +18,7 @@ import { Tabs, TabItem } from "@astrojs/starlight/components";
Wails has a number of common dependencies that are required before installation:
<Tabs>
<TabItem label="Go (At least 1.23)" icon="seti:go">
<TabItem label="Go (At least 1.24)" icon="seti:go">
Download Go from the [Go Downloads Page](https://go.dev/dl/).

View file

@ -68,12 +68,12 @@ func main() {
// ... other runtime options ...
})
app.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) {
launchedURL := e.Context().URL() // Retrieve the URL from the event context
log.Printf("Application launched with URL: %s", launchedURL)
// TODO: Process the URL (e.g., navigate, perform action, etc.)
// Example: app.EmitEvent("frontend:ShowURL", launchedURL)
// Example: app.Event.Emit("frontend:ShowURL", launchedURL)
})
// ... rest of your main function ...

View file

@ -50,7 +50,7 @@ func main() {
Name: "My Application",
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
MinimiseButtonState: application.ButtonHidden,
MaximiseButtonState: application.ButtonDisabled,
CloseButtonState: application.ButtonEnabled,
@ -110,7 +110,7 @@ func main() {
Name: "My Application",
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Windows: application.WindowsWindow{
ExStyle: w32.WS_EX_TOOLWINDOW | w32.WS_EX_NOREDIRECTIONBITMAP | w32.WS_EX_TOPMOST,
},

View file

@ -68,18 +68,22 @@ From your Go code, you can emit events that your frontend can listen to:
package main
import (
"github.com/wailsapp/wails/v3/pkg/events"
"github.com/wailsapp/wails/v3/pkg/application"
"time"
)
func (a *App) UpdateData() {
func (s *Service) UpdateData() {
// Do some data processing...
// Notify the frontend
a.app.EmitEvent("my-app:data-updated", map[string]interface{}{
"timestamp": time.Now(),
"count": 42,
})
app := application.Get()
app.Event.EmitEvent(&application.CustomEvent{
Name: "my-app:data-updated",
Data: map[string]interface{}{
"timestamp": time.Now(),
"count": 42,
},
})
}
```
@ -212,26 +216,32 @@ You can create your own events for application-specific needs:
```go
// Emit a custom event when data changes
func (a *App) ProcessUserData(userData UserData) error {
func (s *Service) ProcessUserData(userData UserData) error {
// Process the data...
app := application.Get()
// Notify all listeners
a.app.EmitEvent("user:data-processed", map[string]interface{}{
"userId": userData.ID,
"status": "completed",
"timestamp": time.Now(),
app.Event.EmitEvent(&application.CustomEvent{
Name: "user:data-processed",
Data: map[string]interface{}{
"userId": userData.ID,
"status": "completed",
"timestamp": time.Now(),
},
})
return nil
}
// Emit periodic updates
func (a *App) StartMonitoring() {
func (s *Service) StartMonitoring() {
app := application.Get()
ticker := time.NewTicker(5 * time.Second)
go func() {
for range ticker.C {
stats := a.collectStats()
a.app.EmitEvent("monitor:stats-updated", stats)
stats := s.collectStats()
app.Event.Emit("monitor:stats-updated", stats)
}
}()
}

View file

@ -69,20 +69,27 @@ fileAssociations:
To handle file open events in your application, you can listen for the
`events.Common.ApplicationOpenedWithFile` event:
```go
```go title="main.go"
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func main() {
app := application.New(application.Options{
Name: "MyApp",
FileAssociations: []string{".txt", ".md"}, // Specify supported extensions
})
// Listen for files being used to open the application
app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
associatedFile := event.Context().Filename()
application.InfoDialog().SetMessage("Application opened with file: " + associatedFile).Show()
})
// Listen for files being used to open the application
app.Event.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
associatedFile := event.Context().Filename()
application.InfoDialog().SetMessage("Application opened with file: " + associatedFile).Show()
})
// Create your window and run the app...
// Create your window and run the app...
}
```

View file

@ -92,11 +92,10 @@ app := application.New(application.Options{
})
// Create window
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Wails + Gin Example",
Width: 900,
Height: 700,
Centered: true,
URL: "/", // This will load the route handled by Gin
})
```
@ -285,7 +284,7 @@ func (s *GinService) setupRoutes() {
}
// Process the event using the Wails event system
s.app.EmitEvent(eventData.Name, eventData.Data)
s.app.Event.Emit(eventData.Name, eventData.Data)
c.JSON(http.StatusOK, gin.H{
"success": true,
@ -364,7 +363,7 @@ must use the JavaScript API package `@wailsio/runtime`.
```go
// Register event handler
app.OnEvent("my-event", func(event *application.CustomEvent) {
app.Event.On("my-event", func(event *application.CustomEvent) {
log.Printf("Received event from frontend: %v", event.Data)
// Process the event...
})
@ -548,12 +547,12 @@ func main() {
})
// Register event handler
app.OnEvent("gin-button-clicked", func(event *application.CustomEvent) {
app.Event.On("gin-button-clicked", func(event *application.CustomEvent) {
log.Printf("Received event from frontend: %v", event.Data)
})
// Create window
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Wails + Gin Example",
Width: 900,
Height: 700,

View file

@ -122,14 +122,17 @@ func (s *GinService) ServiceStartup(ctx context.Context, options application.Ser
s.app = application.Get()
// Register an event handler that can be triggered from the frontend
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) {
s.app.Event.On("gin-api-event", func(event *application.CustomEvent) {
// Log the event data
s.app.Logger.Info("Received event from frontend", "data", event.Data)
// Emit an event back to the frontend
s.app.EmitEvent("gin-api-response", map[string]interface{}{
"message": "Response from Gin API Service",
"time": time.Now().Format(time.RFC3339),
s.app.Event.EmitEvent(&application.CustomEvent{
Name: "gin-api-response",
Data: map[string]interface{}{
"message": "Response from Gin API Service",
"time": time.Now().Format(time.RFC3339),
},
})
})
@ -224,7 +227,7 @@ func (s *GinService) setupRoutes() {
c.JSON(http.StatusCreated, newUser)
// Emit an event to notify about the new user
s.app.EmitEvent("user-created", newUser)
s.app.Event.Emit("user-created", newUser)
})
// Delete a user
@ -308,15 +311,18 @@ One of the powerful features of using Gin with Wails Services is the ability to
In your service's `ServiceStartup` method, you can register event handlers to process events from the frontend:
```go
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) {
// Log the event data
s.app.Logger.Info("Received event from frontend", "data", event.Data)
s.app.Event.On("gin-api-event", func(event *application.CustomEvent) {
// Log the event data
s.app.Logger.Info("Received event from frontend", "data", event.Data)
// Emit an event back to the frontend
s.app.EmitEvent("gin-api-response", map[string]interface{}{
"message": "Response from Gin API Service",
"time": time.Now().Format(time.RFC3339),
})
// Emit an event back to the frontend
s.app.Event.EmitEvent(&application.CustomEvent{
Name: "gin-api-response",
Data: map[string]interface{}{
"message": "Response from Gin API Service",
"time": time.Now().Format(time.RFC3339),
},
})
})
```
@ -324,7 +330,7 @@ You can also emit events to the frontend from your Gin routes or other parts of
```go
// After creating a new user
s.app.EmitEvent("user-created", newUser)
s.app.Event.Emit("user-created", newUser)
```
## Frontend Integration
@ -343,7 +349,10 @@ Then use it in your code:
import * as wails from '@wailsio/runtime';
// Event emission
wails.Events.Emit('gin-api-event', eventData);
wails.Events.Emit({
name: 'gin-api-event',
data: eventData,
});
```
Here's an example of how to set up frontend integration:

View file

@ -10,7 +10,7 @@ Wails v3 provides a powerful menu system that allows you to create both applicat
To create a new menu, use the `New()` method from the Menus manager:
```go
menu := app.Menus.New()
menu := app.Menu.New()
```
### Adding Menu Items
@ -59,10 +59,10 @@ submenu.Add("Save")
#### Combining menus
A menu can be added into another menu by appending or prepending it.
```go
menu := app.Menus.New()
menu := app.Menu.New()
menu.Add("First Menu")
secondaryMenu := app.Menus.New()
secondaryMenu := app.Menu.New()
secondaryMenu.Add("Second Menu")
// insert 'secondaryMenu' after 'menu'
@ -88,7 +88,7 @@ In some cases it'll be better to construct a whole new menu if you are working w
This will clear all items on an existing menu and allows you to add items again.
```go
menu := app.Menus.New()
menu := app.Menu.New()
menu.Add("Waiting for update...")
// after certain logic, the menu has to be updated
@ -107,7 +107,7 @@ so be sure to manage your menus carefully.
If you want to clear and release a menu, use the `Destroy()` method:
```go
menu := app.Menus.New()
menu := app.Menu.New()
menu.Add("Waiting for update...")
// after certain logic, the menu has to be destroyed
@ -265,7 +265,7 @@ These roles can be used to add individual menu items:
Here's an example showing how to use both complete menus and individual roles:
```go
menu := app.Menus.New()
menu := app.Menu.New()
// Add complete menu structures
menu.AddRole(application.AppMenu) // macOS only
@ -287,11 +287,11 @@ Application menus are the menus that appear at the top of your application windo
### Application Menu Behaviour
When you set an application menu using `app.Menus.Set()`, it becomes the main menu on macOS.
When you set an application menu using `app.Menu.Set()`, it becomes the main menu on macOS.
Menus are set on a per-window basis for Windows/Linux.
```go
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom Menu Window",
Windows: application.WindowsWindow{
Menu: customMenu, // Override application menu for this window
@ -306,7 +306,7 @@ func main() {
app := application.New(application.Options{})
// Create application menu
appMenu := app.Menus.New()
appMenu := app.Menu.New()
fileMenu := appMenu.AddSubmenu("File")
fileMenu.Add("New").OnClick(func(ctx *application.Context) {
// This will be available in all windows unless overridden
@ -315,12 +315,12 @@ func main() {
})
// Set as application menu - this is for macOS
app.Menus.Set(appMenu)
app.Menu.Set(appMenu)
// Window with custom menu on Windows
customMenu := app.Menus.New()
customMenu := app.Menu.New()
customMenu.Add("Custom Action")
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom Menu",
Windows: application.WindowsWindow{
Menu: customMenu,

View file

@ -248,7 +248,7 @@ func main() {
app.Menu.Set(menu)
// Create main window
app.NewWebviewWindow()
app.Window.New()
err := app.Run()
if err != nil {

View file

@ -240,7 +240,7 @@ Open development resources during development:
```go
func setupDevelopmentMenu(app *application.App) {
if !app.Environment.Info().Debug {
if !app.Env.Info().Debug {
return // Only show in debug mode
}

View file

@ -110,7 +110,7 @@ func main() {
})
app.Menu.Set(menu)
app.NewWebviewWindow()
app.Window.New()
err := app.Run()
if err != nil {

View file

@ -210,7 +210,7 @@ func main() {
// Register the context menu with the manager
app.ContextMenu.Add("test", contextMenu)
window := app.NewWebviewWindow()
window := app.Window.New()
window.SetTitle("Context Menu Demo")
err := app.Run()

View file

@ -90,7 +90,7 @@ Listen for theme changes to update your application dynamically:
import "github.com/wailsapp/wails/v3/pkg/events"
// Listen for theme changes
app.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
if app.Env.IsDarkMode() {
app.Logger.Info("Switched to dark mode")
updateApplicationTheme("dark")
@ -401,7 +401,7 @@ Platform Information:`,
2. **Handle Theme Changes**: Listen for system theme changes:
```go
app.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
updateTheme(app.Env.IsDarkMode())
})
```
@ -497,7 +497,7 @@ func setupForEnvironment(app *application.App) {
}
func monitorThemeChanges(app *application.App) {
app.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
if app.Env.IsDarkMode() {
app.Logger.Info("System switched to dark mode")
applyDarkTheme(app)

View file

@ -13,11 +13,11 @@ Wails provides a flexible event system that enables communication between differ
Application events are triggered by application-level state changes such as application startup, theme changes, and power events. You can listen for these events using the `OnApplicationEvent` method:
```go
app.OnApplicationEvent(events.Mac.ApplicationDidBecomeActive, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Mac.ApplicationDidBecomeActive, func(event *application.ApplicationEvent) {
app.Logger.Info("Application started!")
})
app.OnApplicationEvent(events.Windows.SystemThemeChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Windows.SystemThemeChanged, func(event *application.ApplicationEvent) {
app.Logger.Info("System theme changed!")
if event.Context().IsDarkMode() {
app.Logger.Info("System is now using dark mode!")
@ -35,11 +35,11 @@ changes such as application startup, theme changes, and power events.
Here is the same example as above, but using common application events to make it work across all platforms:
```go
app.OnApplicationEvent(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) {
app.Logger.Info("Application started!")
})
app.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
if event.Context().IsDarkMode() {
app.Logger.Info("System is now using dark mode!")
} else {
@ -457,11 +457,11 @@ Menu events are triggered by menu-specific actions such as opening, closing, and
```go
// Listen for menu events
app.OnApplicationEvent(events.Mac.MenuDidOpen, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Mac.MenuDidOpen, func(event *application.ApplicationEvent) {
app.Logger.Info("Menu opened!")
})
app.OnApplicationEvent(events.Mac.MenuWillSendAction, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Mac.MenuWillSendAction, func(event *application.ApplicationEvent) {
app.Logger.Info("Menu about to send action!")
})
```
@ -514,16 +514,16 @@ WebView events are triggered by navigation and loading state changes in the WebV
```go
// Listen for WebView navigation events
app.OnApplicationEvent(events.Mac.WebViewDidStartProvisionalNavigation, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Mac.WebViewDidStartProvisionalNavigation, func(event *application.ApplicationEvent) {
app.Logger.Info("WebView started loading a page!")
})
app.OnApplicationEvent(events.Mac.WebViewDidFinishNavigation, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Mac.WebViewDidFinishNavigation, func(event *application.ApplicationEvent) {
app.Logger.Info("WebView finished loading the page!")
})
// On Windows
app.OnApplicationEvent(events.Windows.WebViewNavigationCompleted, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Windows.WebViewNavigationCompleted, func(event *application.ApplicationEvent) {
app.Logger.Info("WebView navigation completed!")
})
```
@ -571,7 +571,7 @@ window.EmitEvent("windowevent", "window specific data")
</TabItem>
<TabItem label="Traditional API">
```go
// Traditional API (still supported)
// Traditional API (no longer works)
app.EmitEvent("myevent", "hello")
// Emit from a specific window

View file

@ -394,7 +394,7 @@ app.Logger.Info("Size conversion",
4. **Monitor Screen Changes**: Listen for screen configuration changes:
```go
app.OnApplicationEvent(events.Common.SystemDisplayChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.SystemDisplayChanged, func(event *application.ApplicationEvent) {
// Refresh screen information
screens := app.Screen.GetAll()
// Reposition windows if needed
@ -484,7 +484,7 @@ func createPositionedWindows(app *application.App) {
func monitorScreenChanges(app *application.App) {
// Monitor for screen configuration changes
app.OnApplicationEvent(events.Common.SystemDisplayChanged, func(event *application.ApplicationEvent) {
app.Event.OnApplicationEvent(events.Common.SystemDisplayChanged, func(event *application.ApplicationEvent) {
app.Logger.Info("Screen configuration changed")
// Re-analyze screens

View file

@ -112,7 +112,7 @@ systray := app.SystemTray.New()
systray.SetLabel("My App")
// Create a window
window := app.NewWebviewWindow()
window := app.Window.New()
// Attach the window to the system tray
systray.AttachWindow(window)
@ -124,7 +124,7 @@ systray.WindowOffset(10)
systray.WindowDebounce(200 * time.Millisecond)
// Add a menu (optional)
menu := application.NewMenu()
menu := app.Menu.New()
menu.Add("Open").OnClick(func() {
window.Show()
})

View file

@ -81,7 +81,7 @@ This will show you how to organize your code into reusable services and handle e
},
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "myproject",
Width: 600,
Height: 400,
@ -415,7 +415,7 @@ This will show you how to organize your code into reusable services and handle e
},
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "myproject",
Width: 600,
Height: 400,

View file

@ -51,11 +51,11 @@ func main() {
},
})
window1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
window1 := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Window 1",
})
window2 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
window2 := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Window 2",
})
@ -123,7 +123,7 @@ func main() {
},
})
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Width: 500,
Height: 800,
Frameless: true,
@ -134,7 +134,7 @@ func main() {
},
})
systemTray := app.NewSystemTray()
systemTray := app.SystemTray.New()
// Support for template icons on macOS
if runtime.GOOS == "darwin" {
@ -146,7 +146,7 @@ func main() {
}
// Support for menu
myMenu := app.NewMenu()
myMenu := app.Menu.New()
myMenu.Add("Hello World!").OnClick(func(_ *application.Context) {
println("Hello World!")
})
@ -310,16 +310,16 @@ func main() {
})
// OS specific application events
app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
app.Events.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) {
app.Events.On(events.Common.ApplicationStarted, func(event *application.Event) {
println("events.Common.ApplicationStarted fired!")
})
win1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
win1 := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Takes 3 attempts to close me!",
})

View file

@ -23,6 +23,7 @@ After processing, the content will be moved to the main changelog and this file
## Fixed
<!-- Bug fixes -->
- Update docs to reflect changes from Manager API Refactoring by @yulesxoxo in [PR #4476](https://github.com/wailsapp/wails/pull/4476)
## Deprecated
<!-- Soon-to-be removed features -->