5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-21 19:39:29 +08:00

Use prettier on docs source

This commit is contained in:
Lea Anthony 2023-09-25 20:56:29 +10:00
parent 4663a45e59
commit d9a5130311
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
15 changed files with 651 additions and 409 deletions

View File

@ -2,7 +2,8 @@
This is the documentation for Wails v3. It is currently a work in progress. This is the documentation for Wails v3. It is currently a work in progress.
If you do not wish to build it locally, it is available online at [https://wailsapp.github.io/wails/](https://wailsapp.github.io/wails/). If you do not wish to build it locally, it is available online at
[https://wailsapp.github.io/wails/](https://wailsapp.github.io/wails/).
## Recommended Setup Steps ## Recommended Setup Steps
@ -12,16 +13,18 @@ Install the wails3 CLI if you haven't already:
go install github.com/wailsapp/wails/v3/cmd/wails3@latest go install github.com/wailsapp/wails/v3/cmd/wails3@latest
``` ```
The documentation uses mkdocs, so you will need to install [Python](https://www.python.org/). Once installed, The documentation uses mkdocs, so you will need to install
you can setup the documentation by running the following command: [Python](https://www.python.org/). Once installed, you can setup the
documentation by running the following command:
```bash ```bash
wails3 task docs:setup wails3 task docs:setup
``` ```
This will install the required dependencies for you. This will install the required dependencies for you.
If you have installed the wails3 CLI, you can run the following command to build the documentation and serve it locally: If you have installed the wails3 CLI, you can run the following command to build
the documentation and serve it locally:
```bash ```bash
wails3 task docs:serve wails3 task docs:serve
@ -31,13 +34,12 @@ wails3 task docs:serve
To install manually, you will need to do the following: To install manually, you will need to do the following:
- Install [Python](https://www.python.org/) - Install [Python](https://www.python.org/)
- Run `pip install -r requirements.txt` to install the required dependencies - Run `pip install -r requirements.txt` to install the required dependencies
- Run `mkdocs serve` to serve the documentation locally - Run `mkdocs serve` to serve the documentation locally
- Run `mkdocs build` to build the documentation - Run `mkdocs build` to build the documentation
## Contributing ## Contributing
If you would like to contribute to the documentation, please feel free to open a PR! If you would like to contribute to the documentation, please feel free to open a
PR!

View File

@ -1,17 +1,21 @@
# Application # Application
The application API assists in creating an application using the Wails framework. The application API assists in creating an application using the Wails
framework.
### New ### New
API: `New(appOptions Options) *App` API: `New(appOptions Options) *App`
`New(appOptions Options)` creates a new application using the given application options . It applies default values for unspecified options, merges them with the provided ones, initializes and returns an instance of the application. `New(appOptions Options)` creates a new application using the given application
options . It applies default values for unspecified options, merges them with
the provided ones, initializes and returns an instance of the application.
In case of an error during initialization, the application is stopped with the error message provided. In case of an error during initialization, the application is stopped with the
error message provided.
It should be noted that if a global application instance already exists, that instance will be returned instead of creating a new one.
It should be noted that if a global application instance already exists, that
instance will be returned instead of creating a new one.
```go title="main.go" hl_lines="6-9" ```go title="main.go" hl_lines="6-9"
package main package main
@ -23,14 +27,15 @@ func main() {
Name: "WebviewWindow Demo", Name: "WebviewWindow Demo",
// Other options // Other options
}) })
// Rest of application // Rest of application
} }
``` ```
### Get ### Get
`Get()` returns the global application instance. It's useful when you need to access the application from different parts of your code. `Get()` returns the global application instance. It's useful when you need to
access the application from different parts of your code.
```go ```go
// Get the application instance // Get the application instance
@ -41,14 +46,16 @@ func main() {
API: `Capabilities() capabilities.Capabilities` API: `Capabilities() capabilities.Capabilities`
`Capabilities()` retrieves a map of capabilities that the application currently has. Capabilities can be about different features the operating system provides, like webview features. `Capabilities()` retrieves a map of capabilities that the application currently
has. Capabilities can be about different features the operating system provides,
like webview features.
```go ```go
// Get the application capabilities // Get the application capabilities
capabilities := app.Capabilities() capabilities := app.Capabilities()
if capabilities.HasNativeDrag { if capabilities.HasNativeDrag {
// Do something // Do something
} }
``` ```
### GetPID ### GetPID
@ -68,21 +75,22 @@ API: `Run() error`
`Run()` starts the execution of the application and its components. `Run()` starts the execution of the application and its components.
```go ```go
app := application.New(application.Options{ app := application.New(application.Options{
//options //options
}) })
// Run the application // Run the application
err := application.Run() err := application.Run()
if err != nil { if err != nil {
// Handle error // Handle error
} }
``` ```
### Quit ### Quit
API: `Quit()` API: `Quit()`
`Quit()` quits the application by destroying windows and potentially other components. `Quit()` quits the application by destroying windows and potentially other
components.
```go ```go
// Quit the application // Quit the application
@ -93,7 +101,8 @@ API: `Quit()`
API: `IsDarkMode() bool` API: `IsDarkMode() bool`
`IsDarkMode()` checks if the application is running in dark mode. It returns a boolean indicating whether dark mode is enabled. `IsDarkMode()` checks if the application is running in dark mode. It returns a
boolean indicating whether dark mode is enabled.
```go ```go
// Check if dark mode is enabled // Check if dark mode is enabled
@ -128,7 +137,8 @@ API: `Show()`
API: `NewWebviewWindow() *WebviewWindow` API: `NewWebviewWindow() *WebviewWindow`
`NewWebviewWindow()` creates a new Webview window with default options, and returns it. `NewWebviewWindow()` creates a new Webview window with default options, and
returns it.
```go ```go
// Create a new webview window // Create a new webview window
@ -137,9 +147,12 @@ API: `NewWebviewWindow() *WebviewWindow`
### NewWebviewWindowWithOptions ### NewWebviewWindowWithOptions
API: `NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow` API:
`NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow`
`NewWebviewWindowWithOptions()` creates a new webview window with custom options. The newly created window is added to a map of windows managed by the application. `NewWebviewWindowWithOptions()` creates a new webview window with custom
options. The newly created window is added to a map of windows managed by the
application.
```go ```go
// Create a new webview window with custom options // Create a new webview window with custom options
@ -155,7 +168,8 @@ API: `NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWi
API: `OnWindowCreation(callback func(window *WebviewWindow))` API: `OnWindowCreation(callback func(window *WebviewWindow))`
`OnWindowCreation()` registers a callback function to be called when a window is created. `OnWindowCreation()` registers a callback function to be called when a window is
created.
```go ```go
// Register a callback to be called when a window is created // Register a callback to be called when a window is created
@ -179,7 +193,8 @@ API: `GetWindowByName(name string) *WebviewWindow`
API: `CurrentWindow() *WebviewWindow` API: `CurrentWindow() *WebviewWindow`
`CurrentWindow()` fetches and returns a pointer to the currently active window in the application. If there is no window, it returns nil. `CurrentWindow()` fetches and returns a pointer to the currently active window
in the application. If there is no window, it returns nil.
```go ```go
// Get the current window // Get the current window
@ -190,7 +205,8 @@ API: `CurrentWindow() *WebviewWindow`
API: `RegisterContextMenu(name string, menu *Menu)` API: `RegisterContextMenu(name string, menu *Menu)`
`RegisterContextMenu()` registers a context menu with a given name. This menu can be used later in the application. `RegisterContextMenu()` registers a context menu with a given name. This menu
can be used later in the application.
```go ```go
@ -205,7 +221,9 @@ API: `RegisterContextMenu(name string, menu *Menu)`
API: `SetMenu(menu *Menu)` API: `SetMenu(menu *Menu)`
`SetMenu()` sets the menu for the application. On Mac, this will be the global menu. For Windows and Linux, this will be the default menu for any new window created. `SetMenu()` sets the menu for the application. On Mac, this will be the global
menu. For Windows and Linux, this will be the default menu for any new window
created.
```go ```go
// Create a new menu // Create a new menu
@ -219,7 +237,8 @@ API: `SetMenu(menu *Menu)`
API: `ShowAboutDialog()` API: `ShowAboutDialog()`
`ShowAboutDialog()` shows an "About" dialog box. It can show the application's name, description and icon. `ShowAboutDialog()` shows an "About" dialog box. It can show the application's
name, description and icon.
```go ```go
// Show the about dialog // Show the about dialog
@ -228,59 +247,76 @@ API: `ShowAboutDialog()`
### Info ### Info
API: `InfoDialog()` API: `InfoDialog()`
`InfoDialog()` creates and returns a new instance of `MessageDialog` with an `InfoDialogType`. This dialog is typically used to display informational messages to the user. `InfoDialog()` creates and returns a new instance of `MessageDialog` with an
`InfoDialogType`. This dialog is typically used to display informational
messages to the user.
### Question ### Question
API: `QuestionDialog()` API: `QuestionDialog()`
`QuestionDialog()` creates and returns a new instance of `MessageDialog` with a `QuestionDialogType`. This dialog is often used to ask a question to the user and expect a response.
`QuestionDialog()` creates and returns a new instance of `MessageDialog` with a
`QuestionDialogType`. This dialog is often used to ask a question to the user
and expect a response.
### Warning ### Warning
API: `WarningDialog()` API: `WarningDialog()`
`WarningDialog()` creates and returns a new instance of `MessageDialog` with a `WarningDialogType`. As the name suggests, this dialog is primarily used to display warning messages to the user. `WarningDialog()` creates and returns a new instance of `MessageDialog` with a
`WarningDialogType`. As the name suggests, this dialog is primarily used to
display warning messages to the user.
### Error ### Error
API: `ErrorDialog()` API: `ErrorDialog()`
`ErrorDialog()` creates and returns a new instance of `MessageDialog` with an `ErrorDialogType`. This dialog is designed to be used when you need to display an error message to the user. `ErrorDialog()` creates and returns a new instance of `MessageDialog` with an
`ErrorDialogType`. This dialog is designed to be used when you need to display
an error message to the user.
### OpenFile ### OpenFile
API: `OpenFileDialog()` API: `OpenFileDialog()`
`OpenFileDialog()` creates and returns a new `OpenFileDialogStruct`. This dialog prompts the user to select one or more files from their file system. `OpenFileDialog()` creates and returns a new `OpenFileDialogStruct`. This dialog
prompts the user to select one or more files from their file system.
### SaveFile ### SaveFile
API: `SaveFileDialog()` API: `SaveFileDialog()`
`SaveFileDialog()` creates and returns a new `SaveFileDialogStruct`. This dialog prompts the user to choose a location on their file system where a file should be saved. `SaveFileDialog()` creates and returns a new `SaveFileDialogStruct`. This dialog
prompts the user to choose a location on their file system where a file should
be saved.
### OpenDirectory ### OpenDirectory
API: `OpenDirectoryDialog()` API: `OpenDirectoryDialog()`
`OpenDirectoryDialog()` creates and returns a new instance of `MessageDialog` with an `OpenDirectoryDialogType`. This dialog enables the user to choose a directory from their file system.
`OpenDirectoryDialog()` creates and returns a new instance of `MessageDialog`
with an `OpenDirectoryDialogType`. This dialog enables the user to choose a
directory from their file system.
### On ### On
API: `On(eventType events.ApplicationEventType, callback func(event *Event)) func()` API:
`On(eventType events.ApplicationEventType, callback func(event *Event)) func()`
`On()` registers an event listener for specific application events. The callback function provided will be triggered when the corresponding event occurs. The function returns a function that can be called to remove the listener. `On()` registers an event listener for specific application events. The callback
function provided will be triggered when the corresponding event occurs. The
function returns a function that can be called to remove the listener.
### RegisterHook ### RegisterHook
API: `RegisterHook(eventType events.ApplicationEventType, callback func(event *Event)) func()` API:
`RegisterHook(eventType events.ApplicationEventType, callback func(event *Event)) func()`
`RegisterHook()` registers a callback to be run as a hook during specific events. These hooks are run before listeners attached with `On()`. The function returns a function that can be called to remove the hook. `RegisterHook()` registers a callback to be run as a hook during specific
events. These hooks are run before listeners attached with `On()`. The function
returns a function that can be called to remove the hook.
### GetPrimaryScreen ### GetPrimaryScreen
@ -294,7 +330,9 @@ API: `GetScreens() ([]*Screen, error)`
`GetScreens()` returns information about all screens attached to the system. `GetScreens()` returns information about all screens attached to the system.
This is a brief summary of the exported methods in the provided `App` struct. Do note that for more detailed functionality or considerations, refer to the actual Go code or further internal documentation. This is a brief summary of the exported methods in the provided `App` struct. Do
note that for more detailed functionality or considerations, refer to the actual
Go code or further internal documentation.
## Options ## Options
@ -318,4 +356,4 @@ This is a brief summary of the exported methods in the provided `App` struct. Do
--8<-- --8<--
../v3/pkg/application/options_application_mac.go ../v3/pkg/application/options_application_mac.go
--8<-- --8<--
``` ```

View File

@ -1,38 +1,50 @@
# Main Thread Functions # Main Thread Functions
These methods are utility functions to run code on the main thread. This is required when you want to run These methods are utility functions to run code on the main thread. This is
custom code on the UI thread. required when you want to run custom code on the UI thread.
### InvokeSync ### InvokeSync
API: `InvokeSync(fn func())` API: `InvokeSync(fn func())`
This function runs the passed function (`fn`) synchronously. It uses a WaitGroup (`wg`) to ensure that the main thread waits for the `fn` function to finish before it continues. If a panic occurs inside `fn`, it will be passed to the handler function `PanicHandler`, defined in the application options. This function runs the passed function (`fn`) synchronously. It uses a WaitGroup
(`wg`) to ensure that the main thread waits for the `fn` function to finish
before it continues. If a panic occurs inside `fn`, it will be passed to the
handler function `PanicHandler`, defined in the application options.
### InvokeSyncWithResult ### InvokeSyncWithResult
API: `InvokeSyncWithResult[T any](fn func() T) (res T)` API: `InvokeSyncWithResult[T any](fn func() T) (res T)`
This function works similarly to `InvokeSync(fn func())`, however, it yields a result. Use this for calling any function with a single return. This function works similarly to `InvokeSync(fn func())`, however, it yields a
result. Use this for calling any function with a single return.
### InvokeSyncWithError ### InvokeSyncWithError
API: `InvokeSyncWithError(fn func() error) (err error)` API: `InvokeSyncWithError(fn func() error) (err error)`
This function runs `fn` synchronously and returns any error that `fn` produces. Note that this function will recover from a panic if one occurs during `fn`'s execution. This function runs `fn` synchronously and returns any error that `fn` produces.
Note that this function will recover from a panic if one occurs during `fn`'s
execution.
### InvokeSyncWithResultAndError ### InvokeSyncWithResultAndError
API: `InvokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error)` API:
`InvokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error)`
This function runs `fn` synchronously and returns both a result of type `T` and an error. This function runs `fn` synchronously and returns both a result of type `T` and
an error.
### InvokeAsync ### InvokeAsync
API: `InvokeAsync(fn func())` API: `InvokeAsync(fn func())`
This function runs `fn` asynchronously. It runs the given function on the main thread. If a panic occurs inside `fn`, it will be passed to the handler function `PanicHandler`, defined in the application options. This function runs `fn` asynchronously. It runs the given function on the main
thread. If a panic occurs inside `fn`, it will be passed to the handler function
`PanicHandler`, defined in the application options.
--- ---
_Note_: These functions will block execution until `fn` has finished. It's critical to ensure that `fn` doesn't block. If you need to run a function that blocks, use `InvokeAsync` instead. _Note_: These functions will block execution until `fn` has finished. It's
critical to ensure that `fn` doesn't block. If you need to run a function that
blocks, use `InvokeAsync` instead.

View File

@ -1,6 +1,7 @@
# Menu # Menu
Menus can be created and added to the application. They can be used to create context menus, system tray menus and application menus. Menus can be created and added to the application. They can be used to create
context menus, system tray menus and application menus.
To create a new menu, call: To create a new menu, call:
@ -15,7 +16,8 @@ The following operations are then available on the `Menu` type:
API: `Add(label string) *MenuItem` API: `Add(label string) *MenuItem`
This method takes a `label` of type `string` as an input and adds a new `MenuItem` with the given label to the menu. It returns the `MenuItem` added. This method takes a `label` of type `string` as an input and adds a new
`MenuItem` with the given label to the menu. It returns the `MenuItem` added.
### AddSeparator ### AddSeparator
@ -27,31 +29,38 @@ This method adds a new separator `MenuItem` to the menu.
API: `AddCheckbox(label string, enabled bool) *MenuItem` API: `AddCheckbox(label string, enabled bool) *MenuItem`
This method takes a `label` of type `string` and `enabled` of type `bool` as inputs and adds a new checkbox `MenuItem` with the given label and enabled state to the menu. It returns the `MenuItem` added. This method takes a `label` of type `string` and `enabled` of type `bool` as
inputs and adds a new checkbox `MenuItem` with the given label and enabled state
to the menu. It returns the `MenuItem` added.
### AddRadio ### AddRadio
API: `AddRadio(label string, enabled bool) *MenuItem` API: `AddRadio(label string, enabled bool) *MenuItem`
This method takes a `label` of type `string` and `enabled` of type `bool` as inputs and adds a new radio `MenuItem` with the given label and enabled state to the menu. It returns the `MenuItem` added. This method takes a `label` of type `string` and `enabled` of type `bool` as
inputs and adds a new radio `MenuItem` with the given label and enabled state to
the menu. It returns the `MenuItem` added.
### Update ### Update
API: `Update()` API: `Update()`
This method processes any radio groups and updates the menu if a menu implementation is not initialized. This method processes any radio groups and updates the menu if a menu
implementation is not initialized.
### AddSubmenu ### AddSubmenu
API: `AddSubmenu(s string) *Menu` API: `AddSubmenu(s string) *Menu`
This method takes a `s` of type `string` as input and adds a new submenu `MenuItem` with the given label to the menu. It returns the submenu added. This method takes a `s` of type `string` as input and adds a new submenu
`MenuItem` with the given label to the menu. It returns the submenu added.
### AddRole ### AddRole
API: `AddRole(role Role) *Menu` API: `AddRole(role Role) *Menu`
This method takes `role` of type `Role` as input, adds it to the menu if it is not `nil` and returns the `Menu`. This method takes `role` of type `Role` as input, adds it to the menu if it is
not `nil` and returns the `Menu`.
### SetLabel ### SetLabel

View File

@ -1,6 +1,8 @@
# System Tray # System Tray
The system tray houses notification area on a desktop environment, which can contain both icons of currently-running applications and specific system notifications. The system tray houses notification area on a desktop environment, which can
contain both icons of currently-running applications and specific system
notifications.
You create a system tray by calling `app.NewSystemTray()`: You create a system tray by calling `app.NewSystemTray()`:
@ -15,19 +17,20 @@ The following methods are available on the `SystemTray` type:
API: `SetLabel(label string)` API: `SetLabel(label string)`
The `SetLabel` method sets the tray's label. The `SetLabel` method sets the tray's label.
### Label ### Label
API: `Label() string` API: `Label() string`
The `Label` method retrieves the tray's label. The `Label` method retrieves the tray's label.
### PositionWindow ### PositionWindow
API: `PositionWindow(*WebviewWindow, offset int) error` API: `PositionWindow(*WebviewWindow, offset int) error`
The `PositionWindow` method calls both `AttachWindow` and `WindowOffset` methods. The `PositionWindow` method calls both `AttachWindow` and `WindowOffset`
methods.
### SetIcon ### SetIcon
@ -39,13 +42,13 @@ The `SetIcon` method sets the system tray's icon.
API: `SetDarkModeIcon(icon []byte) *SystemTray` API: `SetDarkModeIcon(icon []byte) *SystemTray`
The `SetDarkModeIcon` method sets the system tray's icon when in dark mode. The `SetDarkModeIcon` method sets the system tray's icon when in dark mode.
### SetMenu ### SetMenu
API: `SetMenu(menu *Menu) *SystemTray` API: `SetMenu(menu *Menu) *SystemTray`
The `SetMenu` method sets the system tray's menu. The `SetMenu` method sets the system tray's menu.
### Destroy ### Destroy
@ -63,37 +66,44 @@ The `OnClick` method sets the function to execute when the tray icon is clicked.
API: `OnRightClick(handler func()) *SystemTray` API: `OnRightClick(handler func()) *SystemTray`
The `OnRightClick` method sets the function to execute when right-clicking the tray icon. The `OnRightClick` method sets the function to execute when right-clicking the
tray icon.
### OnDoubleClick ### OnDoubleClick
API: `OnDoubleClick(handler func()) *SystemTray` API: `OnDoubleClick(handler func()) *SystemTray`
The `OnDoubleClick` method sets the function to execute when double-clicking the tray icon. The `OnDoubleClick` method sets the function to execute when double-clicking the
tray icon.
### OnRightDoubleClick ### OnRightDoubleClick
API: `OnRightDoubleClick(handler func()) *SystemTray` API: `OnRightDoubleClick(handler func()) *SystemTray`
The `OnRightDoubleClick` method sets the function to execute when right double-clicking the tray icon. The `OnRightDoubleClick` method sets the function to execute when right
double-clicking the tray icon.
### AttachWindow ### AttachWindow
API: `AttachWindow(window *WebviewWindow) *SystemTray` API: `AttachWindow(window *WebviewWindow) *SystemTray`
The `AttachWindow` method attaches a window to the system tray. The window will be shown when the system tray icon is clicked. The `AttachWindow` method attaches a window to the system tray. The window will
be shown when the system tray icon is clicked.
### WindowOffset ### WindowOffset
API: `WindowOffset(offset int) *SystemTray` API: `WindowOffset(offset int) *SystemTray`
The `WindowOffset` method sets the gap in pixels between the system tray and the window. The `WindowOffset` method sets the gap in pixels between the system tray and the
window.
### WindowDebounce ### WindowDebounce
API: `WindowDebounce(debounce time.Duration) *SystemTray` API: `WindowDebounce(debounce time.Duration) *SystemTray`
The `WindowDebounce` method sets a debounce time. In the context of Windows, this is used to specify how long to wait before responding to a mouse up event on the notification icon. The `WindowDebounce` method sets a debounce time. In the context of Windows,
this is used to specify how long to wait before responding to a mouse up event
on the notification icon.
### OpenMenu ### OpenMenu

View File

@ -1,6 +1,10 @@
# Window # Window
To create a window, use [Application.NewWebviewWindow](application.md#newwebviewwindow) or [Application.NewWebviewWindowWithOptions](application.md#newwebviewwindowwithoptions). The former creates a window with default options, while the latter allows you to specify custom options. To create a window, use
[Application.NewWebviewWindow](application.md#newwebviewwindow) or
[Application.NewWebviewWindowWithOptions](application.md#newwebviewwindowwithoptions).
The former creates a window with default options, while the latter allows you to
specify custom options.
These methods are callable on the returned WebviewWindow object: These methods are callable on the returned WebviewWindow object:
@ -8,8 +12,8 @@ These methods are callable on the returned WebviewWindow object:
API: `SetTitle(title string) *WebviewWindow` API: `SetTitle(title string) *WebviewWindow`
This method updates the window title to the provided string. It returns the WebviewWindow object, allowing for method chaining. This method updates the window title to the provided string. It returns the
WebviewWindow object, allowing for method chaining.
### Name ### Name
@ -17,13 +21,13 @@ API: `Name() string`
This function returns the name of the WebviewWindow. This function returns the name of the WebviewWindow.
### SetSize ### SetSize
API: `SetSize(width, height int) *WebviewWindow` API: `SetSize(width, height int) *WebviewWindow`
This method sets the size of the WebviewWindow to the provided width and height parameters. If the dimensions provided exceed the constraints, they are adjusted appropriately. This method sets the size of the WebviewWindow to the provided width and height
parameters. If the dimensions provided exceed the constraints, they are adjusted
appropriately.
### SetAlwaysOnTop ### SetAlwaysOnTop
@ -31,20 +35,19 @@ API: `SetAlwaysOnTop(b bool) *WebviewWindow`
This function sets the window to stay on top based on the boolean flag provided. This function sets the window to stay on top based on the boolean flag provided.
### Show ### Show
API: `Show() *WebviewWindow` API: `Show() *WebviewWindow`
`Show` method is used to make the window visible. If the window is not running, it first invokes the `run` method to start the window and then makes it visible. `Show` method is used to make the window visible. If the window is not running,
it first invokes the `run` method to start the window and then makes it visible.
### Hide ### Hide
API: `Hide() *WebviewWindow` API: `Hide() *WebviewWindow`
`Hide` method is used to hide the window. It sets the hidden status of the window to true and emits the window hide event. `Hide` method is used to hide the window. It sets the hidden status of the
window to true and emits the window hide event.
### SetURL ### SetURL
@ -52,13 +55,12 @@ API: `SetURL(s string) *WebviewWindow`
`SetURL` method is used to set the URL of the window to the given URL string. `SetURL` method is used to set the URL of the window to the given URL string.
### SetZoom ### SetZoom
API: `SetZoom(magnification float64) *WebviewWindow` API: `SetZoom(magnification float64) *WebviewWindow`
`SetZoom` method sets the zoom level of the window content to the provided magnification level. `SetZoom` method sets the zoom level of the window content to the provided
magnification level.
### GetZoom ### GetZoom
@ -66,7 +68,6 @@ API: `GetZoom() float64`
`GetZoom` function returns the current zoom level of the window content. `GetZoom` function returns the current zoom level of the window content.
### GetScreen ### GetScreen
API: `GetScreen() (*Screen, error)` API: `GetScreen() (*Screen, error)`
@ -77,8 +78,9 @@ API: `GetScreen() (*Screen, error)`
API: `SetFrameless(frameless bool) *WebviewWindow` API: `SetFrameless(frameless bool) *WebviewWindow`
This function is used to remove the window frame and title bar. It toggles the framelessness of the window according to the boolean value provided (true for frameless, false for framed). This function is used to remove the window frame and title bar. It toggles the
framelessness of the window according to the boolean value provided (true for
frameless, false for framed).
#### RegisterContextMenu #### RegisterContextMenu
@ -86,27 +88,24 @@ API: `RegisterContextMenu(name string, menu *Menu)`
This function is used to register a context menu and assigns it the given name. This function is used to register a context menu and assigns it the given name.
#### NativeWindowHandle #### NativeWindowHandle
API: `NativeWindowHandle() (uintptr, error)` API: `NativeWindowHandle() (uintptr, error)`
This function is used to fetch the platform native window handle for the window. This function is used to fetch the platform native window handle for the window.
#### Focus #### Focus
API: `Focus()` API: `Focus()`
This function is used to focus the window. This function is used to focus the window.
#### SetEnabled #### SetEnabled
API: `SetEnabled(enabled bool)` API: `SetEnabled(enabled bool)`
This function is used to enable/disable the window based on the provided boolean value. This function is used to enable/disable the window based on the provided boolean
value.
#### SetAbsolutePosition #### SetAbsolutePosition

View File

@ -17,14 +17,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added ### Added
* [darwin] add getPrimaryScreen/getScreens to impl by @tmclane in https://github.com/wailsapp/wails/pull/2618
- [darwin] add getPrimaryScreen/getScreens to impl by @tmclane in
https://github.com/wailsapp/wails/pull/2618
### Fixed ### Fixed
- Fixed background colours of examples on Windows by [mmgvh](https://github.com/mmghv) in [#2750](https://github.com/wailsapp/wails/pull/2750). - Fixed background colours of examples on Windows by
- Fixed default context menus by [mmgvh](https://github.com/mmghv) in [#2753](https://github.com/wailsapp/wails/pull/2753). [mmgvh](https://github.com/mmghv) in
[#2750](https://github.com/wailsapp/wails/pull/2750).
- Fixed default context menus by [mmgvh](https://github.com/mmghv) in
[#2753](https://github.com/wailsapp/wails/pull/2753).
### Changed ### Changed
@ -33,4 +37,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Deprecated ### Deprecated
### Security ### Security

View File

@ -1,11 +1,11 @@
# Changes for v3 # Changes for v3
!!! note !!! note This is currently an unsorted brain dump of changes. It will be
This is currently an unsorted brain dump of changes. It will be organised into a more readable format soon. organised into a more readable format soon.
## Options ## Options
The application options have been revised since v2. The application options have been revised since v2.
## Events ## Events
@ -17,97 +17,139 @@ In v3, there are 3 types of events:
### Application Events ### Application Events
Application events are events that are emitted by the application. These events include native events such as `ApplicationDidFinishLaunching` on macOS. Application events are events that are emitted by the application. These events
include native events such as `ApplicationDidFinishLaunching` on macOS.
### Window Events ### Window Events
Window events are events that are emitted by a window. These events include native events such as `WindowDidBecomeMain` on macOS. Common events are also defined, so they work cross-platform, e.g. `WindowClosing`. Window events are events that are emitted by a window. These events include
native events such as `WindowDidBecomeMain` on macOS. Common events are also
defined, so they work cross-platform, e.g. `WindowClosing`.
### Custom Events ### Custom Events
Events that the user defines are called `WailsEvents`. This is to differentiate them from the `Event` object that is used to communicate with the browser. WailsEvents are now objects that encapsulate all the details of an event. This includes the event name, the data, and the source of the event. Events that the user defines are called `WailsEvents`. This is to differentiate
them from the `Event` object that is used to communicate with the browser.
WailsEvents are now objects that encapsulate all the details of an event. This
includes the event name, the data, and the source of the event.
The data associated with a WailsEvent is now a single value. If multiple values are required, then a struct can be used. The data associated with a WailsEvent is now a single value. If multiple values
are required, then a struct can be used.
### Event callbacks and `Emit` function signature ### Event callbacks and `Emit` function signature
The signatures events callbacks (as used by `On`, `Once` & `OnMultiple`) have changed. In v2, the callback function received optional data. In v3, the callback function receives a `WailsEvent` object that contains all data related to the event. The signatures events callbacks (as used by `On`, `Once` & `OnMultiple`) have
changed. In v2, the callback function received optional data. In v3, the
callback function receives a `WailsEvent` object that contains all data related
to the event.
Similarly, the `Emit` function has changed. Instead of taking a name and optional data, it now takes a single `WailsEvent` object that it will emit. Similarly, the `Emit` function has changed. Instead of taking a name and
optional data, it now takes a single `WailsEvent` object that it will emit.
### `Off` and `OffAll` ### `Off` and `OffAll`
In v2, `Off` and `OffAll` calls would remove events in both JS and Go. Due to the multi-window nature of v3, this has been changed so that these methods only apply to the context they are called in. For example, if you call `Off` in a window, it will only remove events for that window. If you use `Off` in Go, it will only remove events for Go. In v2, `Off` and `OffAll` calls would remove events in both JS and Go. Due to
the multi-window nature of v3, this has been changed so that these methods only
apply to the context they are called in. For example, if you call `Off` in a
window, it will only remove events for that window. If you use `Off` in Go, it
will only remove events for Go.
### Hooks ### Hooks
Event Hooks are a new feature in v3. They allow you to hook into the event system and perform actions when certain events are emitted. For example, you can hook into the `WindowClosing` event and perform some cleanup before the window closes. Event Hooks are a new feature in v3. They allow you to hook into the event
Hooks can be registered at the application level or at the window level using `RegisterHook`. Application level are for application events. Window level hooks will only be called for the window they are registered with. system and perform actions when certain events are emitted. For example, you can
hook into the `WindowClosing` event and perform some cleanup before the window
closes. Hooks can be registered at the application level or at the window level
using `RegisterHook`. Application level are for application events. Window level
hooks will only be called for the window they are registered with.
### Logging ### Logging
Logging in v2 was confusing as both application logs and system (internal) logs were using the same logger. We have simplified this as follows: Logging in v2 was confusing as both application logs and system (internal) logs
were using the same logger. We have simplified this as follows:
- Internal logs are now handled using the standard Go `slog` logger. This is configured using the `logger` option in the application options. By default, this uses the [tint](https://github.com/lmittmann/tint) logger.
- Application logs can now be achieved through the new `log` plugin which utilises `slog` under the hood. This plugin provides a simple API for logging to the console. It is available in both Go and JS.
- Internal logs are now handled using the standard Go `slog` logger. This is
configured using the `logger` option in the application options. By default,
this uses the [tint](https://github.com/lmittmann/tint) logger.
- Application logs can now be achieved through the new `log` plugin which
utilises `slog` under the hood. This plugin provides a simple API for logging
to the console. It is available in both Go and JS.
### Developer notes ### Developer notes
When emitting an event in Go, it will dispatch the event to local Go listeners and also each window in the application. When emitting an event in Go, it will dispatch the event to local Go listeners
When emitting an event in JS, it now sends the event to the application. This will be processed as if it was emitted in Go, however the sender ID will be that of the window. and also each window in the application. When emitting an event in JS, it now
sends the event to the application. This will be processed as if it was emitted
in Go, however the sender ID will be that of the window.
## Window ## Window
The Window API has largely remained the same, however the methods are now on an instance of a window rather than the runtime. The Window API has largely remained the same, however the methods are now on an
Some notable differences are: instance of a window rather than the runtime. Some notable differences are:
- Windows now have a Name that identifies them. This is used to identify the window when emitting events.
- Windows have even more methods on the that were previously unavailable, such as `AbsolutePosition` and `ToggleDevTools`. - Windows now have a Name that identifies them. This is used to identify the
- Windows can now accept files via native drag and drop. See the Drag and Drop section for more details. window when emitting events.
- Windows have even more methods on the that were previously unavailable, such
as `AbsolutePosition` and `ToggleDevTools`.
- Windows can now accept files via native drag and drop. See the Drag and Drop
section for more details.
## ClipBoard ## ClipBoard
The clipboard API has been simplified. There is now a single `Clipboard` object that can be used to read and write to the clipboard. The `Clipboard` object is available in both Go and JS. `SetText()` to set the text and `Text()` to get the text. The clipboard API has been simplified. There is now a single `Clipboard` object
that can be used to read and write to the clipboard. The `Clipboard` object is
available in both Go and JS. `SetText()` to set the text and `Text()` to get the
text.
## Bindings ## Bindings
Bindings work in a similar way to v2, by providing a means to bind struct methods to the frontend. Bindings work in a similar way to v2, by providing a means to bind struct
These can be called in the frontend using the binding wrappers generated by the `wails3 generate bindings` command: methods to the frontend. These can be called in the frontend using the binding
wrappers generated by the `wails3 generate bindings` command:
```javascript ```javascript
// @ts-check // @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
import {main} from './models'; import { main } from "./models";
window.go = window.go || {}; window.go = window.go || {};
window.go.main = { window.go.main = {
GreetService: { GreetService: {
/**
/** * GreetService.Greet
* GreetService.Greet * Greet greets a person
* Greet greets a person * @param name {string}
* @param name {string} * @returns {Promise<string>}
* @returns {Promise<string>} **/
**/ Greet: function (name) {
Greet: function(name) { wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); }, 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)); },
}, },
/**
* 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));
},
},
}; };
``` ```
Bound methods are obfuscated by default, and are identified using uint32 IDs, calculated using the [FNV hashing algorithm](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function). This is to prevent the method name from being exposed in production builds. Bound methods are obfuscated by default, and are identified using uint32 IDs,
In debug mode, the method IDs are logged along with the calculated ID of the method to aid in debugging. If you wish to add an extra layer of obfuscation, you can use the `BindAliases` option. This allows you to specify a map of alias IDs to method IDs. When the frontend calls a method using an ID, the method ID will be looked up in the alias map first for a match. If it does not find it, it assumes it's a standard method ID and tries to find the method in the usual way. calculated using the
[FNV hashing algorithm](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).
This is to prevent the method name from being exposed in production builds. In
debug mode, the method IDs are logged along with the calculated ID of the method
to aid in debugging. If you wish to add an extra layer of obfuscation, you can
use the `BindAliases` option. This allows you to specify a map of alias IDs to
method IDs. When the frontend calls a method using an ID, the method ID will be
looked up in the alias map first for a match. If it does not find it, it assumes
it's a standard method ID and tries to find the method in the usual way.
Example: Example:
@ -133,10 +175,12 @@ We can now call using this alias in the frontend: `wails.Call(1, "world!")`.
### Insecure calls ### Insecure calls
If you don't mind your calls being available in plain text in your binary and have no intention of using [garble](https://github.com/burrowers/garble), If you don't mind your calls being available in plain text in your binary and
then you can use the insecure `wails.CallByName()` method. This method takes the fully qualified name of the method to call and the arguments to pass to it. have no intention of using [garble](https://github.com/burrowers/garble), then
you can use the insecure `wails.CallByName()` method. This method takes the
fully qualified name of the method to call and the arguments to pass to it.
Example: Example:
```go ```go
wails.CallByName("main.GreetService.Greet", "world!") wails.CallByName("main.GreetService.Greet", "world!")
``` ```
@ -144,16 +188,19 @@ Example:
!!! danger !!! danger
This is only provided as a convenience method for development. It is not recommended to use this in production. This is only provided as a convenience method for development. It is not recommended to use this in production.
## Dialogs ## Dialogs
Dialogs are now available in JavaScript! Dialogs are now available in JavaScript!
### Windows ### Windows
Dialog buttons in Windows are not configurable and are constant depending on the type of dialog. To trigger a callback when a button is pressed, create a button with the same name as the button you wish to have the callback attached to. Dialog buttons in Windows are not configurable and are constant depending on the
Example: Create a button with the label `Ok` and use `OnClick()` to set the callback method: type of dialog. To trigger a callback when a button is pressed, create a button
with the same name as the button you wish to have the callback attached to.
Example: Create a button with the label `Ok` and use `OnClick()` to set the
callback method:
```go ```go
dialog := app.QuestionDialog(). dialog := app.QuestionDialog().
SetTitle("Update"). SetTitle("Update").
@ -170,40 +217,66 @@ Example: Create a button with the label `Ok` and use `OnClick()` to set the call
## Drag and Drop ## Drag and Drop
Native drag and drop can be enabled per-window. Simply set the `EnableDragAndDrop` window config option to `true` and the window will allow files to be dragged onto it. When this happens, the `events.FilesDropped` event will be emitted. The filenames can then be retrieved from the `WindowEvent.Context()` using the `DroppedFiles()` method. This returns a slice of strings containing the filenames. Native drag and drop can be enabled per-window. Simply set the
`EnableDragAndDrop` window config option to `true` and the window will allow
files to be dragged onto it. When this happens, the `events.FilesDropped` event
will be emitted. The filenames can then be retrieved from the
`WindowEvent.Context()` using the `DroppedFiles()` method. This returns a slice
of strings containing the filenames.
## Context Menus ## Context Menus
Context menus are contextual menus that are shown when the user right-clicks on an element. Creating a context menu is the same as creating a standard menu , by using `app.NewMenu()`. To make the context menu available to a window, call `window.RegisterContextMenu(name, menu)`. The name will be the id of the context menu and used by the frontend. Context menus are contextual menus that are shown when the user right-clicks on
an element. Creating a context menu is the same as creating a standard menu , by
using `app.NewMenu()`. To make the context menu available to a window, call
`window.RegisterContextMenu(name, menu)`. The name will be the id of the context
menu and used by the frontend.
To indicate that an element has a context menu, add the `data-contextmenu` attribute to the element. The value of this attribute should be the name of a context menu previously registered with the window. To indicate that an element has a context menu, add the `data-contextmenu`
attribute to the element. The value of this attribute should be the name of a
context menu previously registered with the window.
It is possible to register a context menu at the application level, making it available to all windows. This can be done using `app.RegisterContextMenu(name, menu)`. If a context menu cannot be found at the window level, the application context menus will be checked. A demo of this can be found in `v3/examples/contextmenus`. It is possible to register a context menu at the application level, making it
available to all windows. This can be done using
`app.RegisterContextMenu(name, menu)`. If a context menu cannot be found at the
window level, the application context menus will be checked. A demo of this can
be found in `v3/examples/contextmenus`.
## Wails Markup Language (WML) ## Wails Markup Language (WML)
The Wails Markup Language is a simple markup language that allows you to add functionality to standard HTML elements without the use of Javascript. The Wails Markup Language is a simple markup language that allows you to add
functionality to standard HTML elements without the use of Javascript.
The following tags are currently supported: The following tags are currently supported:
### `data-wml-event` ### `data-wml-event`
This specifies that a Wails event will be emitted when the element is clicked. The value of the attribute should be the name of the event to emit. This specifies that a Wails event will be emitted when the element is clicked.
The value of the attribute should be the name of the event to emit.
Example: Example:
```html ```html
<button data-wml-event="myevent">Click Me</button> <button data-wml-event="myevent">Click Me</button>
``` ```
Sometimes you need the user to confirm an action. This can be done by adding the `data-wml-confirm` attribute to the element. The value of this attribute will be the message to display to the user.
Sometimes you need the user to confirm an action. This can be done by adding the
`data-wml-confirm` attribute to the element. The value of this attribute will be
the message to display to the user.
Example: Example:
```html ```html
<button data-wml-event="delete-all-items" data-wml-confirm="Are you sure?">Delete All Items</button> <button data-wml-event="delete-all-items" data-wml-confirm="Are you sure?">
Delete All Items
</button>
``` ```
### `data-wml-window` ### `data-wml-window`
Any `wails.window` method can be called by adding the `data-wml-window` attribute to an element. The value of the attribute should be the name of the method to call. The method name should be in the same case as the method. Any `wails.window` method can be called by adding the `data-wml-window`
attribute to an element. The value of the attribute should be the name of the
method to call. The method name should be in the same case as the method.
```html ```html
<button data-wml-window="Close">Close Window</button> <button data-wml-window="Close">Close Window</button>
@ -211,23 +284,28 @@ Any `wails.window` method can be called by adding the `data-wml-window` attribut
### `data-wml-trigger` ### `data-wml-trigger`
This attribute specifies which javascript event should trigger the action. The default is `click`. This attribute specifies which javascript event should trigger the action. The
default is `click`.
```html ```html
<button data-wml-event="hover-box" data-wml-trigger="mouseover">Hover over me!</button> <button data-wml-event="hover-box" data-wml-trigger="mouseover">
Hover over me!
</button>
``` ```
## Systray ## Systray
Wails 3 comes with a built-in systray. This is a fully featured systray that has been designed to be as simple as possible to use. Wails 3 comes with a built-in systray. This is a fully featured systray that has
It is possible to set the icon, tooltip and menu of the systray. It is possible to also "attach" a window to the systray. Doing this will provide the following functionality: been designed to be as simple as possible to use. It is possible to set the
icon, tooltip and menu of the systray. It is possible to also "attach" a window
to the systray. Doing this will provide the following functionality:
- Clicking the systray icon with toggle the window visibility - Clicking the systray icon with toggle the window visibility
- Right-clicking the systray will open the menu, if there is one - Right-clicking the systray will open the menu, if there is one
On macOS, if there is no attached window, the systray will use the default method of displaying the menu (any button). On macOS, if there is no attached window, the systray will use the default
If there is an attached window but no menu, the systray will toggle the window regardless of the button pressed. method of displaying the menu (any button). If there is an attached window but
no menu, the systray will toggle the window regardless of the button pressed.
## Plugins ## Plugins
@ -241,25 +319,28 @@ Plugins are standard Go structure that adhere to the following interface:
type Plugin interface { type Plugin interface {
Name() string Name() string
Init(*application.App) error Init(*application.App) error
Shutdown() Shutdown()
CallableByJS() []string CallableByJS() []string
InjectJS() string InjectJS() string
} }
``` ```
The `Name()` method returns the name of the plugin. This is used for logging purposes. The `Name()` method returns the name of the plugin. This is used for logging
purposes.
The `Init(*application.App) error` method is called when the plugin is loaded. The `*application.App` The `Init(*application.App) error` method is called when the plugin is loaded.
parameter is the application that the plugin is being loaded into. Any errors will prevent The `*application.App` parameter is the application that the plugin is being
the application from starting. loaded into. Any errors will prevent the application from starting.
The `Shutdown()` method is called when the application is shutting down. The `Shutdown()` method is called when the application is shutting down.
The `CallableByJS()` method returns a list of exported functions that can be called from The `CallableByJS()` method returns a list of exported functions that can be
the frontend. These method names must exactly match the names of the methods exported called from the frontend. These method names must exactly match the names of the
by the plugin. methods exported by the plugin.
The `InjectJS()` method returns JavaScript that should be injected into all windows as they are created. This is useful for adding custom JavaScript functions that complement the plugin. The `InjectJS()` method returns JavaScript that should be injected into all
windows as they are created. This is useful for adding custom JavaScript
functions that complement the plugin.
### Tips ### Tips
@ -277,7 +358,8 @@ const (
) )
``` ```
Due to incompatibility between Go and JavaScript, custom types cannot be used in this way. The best strategy is to use a type alias for float64: Due to incompatibility between Go and JavaScript, custom types cannot be used in
this way. The best strategy is to use a type alias for float64:
```go ```go
type MyEnum = float64 type MyEnum = float64
@ -293,67 +375,80 @@ In Javascript, you can then use the following:
```js ```js
const MyEnum = { const MyEnum = {
MyEnumOne: 0, MyEnumOne: 0,
MyEnumTwo: 1, MyEnumTwo: 1,
MyEnumThree: 2 MyEnumThree: 2,
} };
``` ```
- Why use `float64`? Can't we use `int`? - Why use `float64`? Can't we use `int`?
- Because JavaScript doesn't have a concept of `int`. Everything is a `number`, which translates to `float64` in Go. There are also restrictions on casting types in Go's reflection package, which means using `int` doesn't work. - Because JavaScript doesn't have a concept of `int`. Everything is a
`number`, which translates to `float64` in Go. There are also restrictions
on casting types in Go's reflection package, which means using `int` doesn't
work.
### BackgroundColour ### BackgroundColour
In v2, this was a pointer to an `RGBA` struct. In v3, this is an `RGBA` struct value. In v2, this was a pointer to an `RGBA` struct. In v3, this is an `RGBA` struct
value.
### WindowIsTranslucent ### WindowIsTranslucent
This flag has been removed. Now there is a `BackgroundType` flag that can be used to set the type of background the window should have. This flag has been removed. Now there is a `BackgroundType` flag that can be
This flag can be set to any of the following values: used to set the type of background the window should have. This flag can be set
to any of the following values:
- `BackgroundTypeSolid` - The window will have a solid background - `BackgroundTypeSolid` - The window will have a solid background
- `BackgroundTypeTransparent` - The window will have a transparent background - `BackgroundTypeTransparent` - The window will have a transparent background
- `BackgroundTypeTranslucent` - The window will have a translucent background - `BackgroundTypeTranslucent` - The window will have a translucent background
On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the type of translucency can be set using the On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the
`BackdropType` flag in the `WindowsWindow` options. This can be set to any of the following values: type of translucency can be set using the `BackdropType` flag in the
`WindowsWindow` options. This can be set to any of the following values:
- `Auto` - The window will use an effect determined by the system - `Auto` - The window will use an effect determined by the system
- `None` - The window will have no background - `None` - The window will have no background
- `Mica` - The window will use the Mica effect - `Mica` - The window will use the Mica effect
- `Acrylic` - The window will use the acrylic effect - `Acrylic` - The window will use the acrylic effect
- `Tabbed` - The window will use the tabbed effect - `Tabbed` - The window will use the tabbed effect
## Windows Application Options ## Windows Application Options
### WndProcInterceptor ### WndProcInterceptor
If this is set, the WndProc will be intercepted and the function will be called. This allows you to handle Windows If this is set, the WndProc will be intercepted and the function will be called.
messages directly. The function should have the following signature: This allows you to handle Windows messages directly. The function should have
the following signature:
```go ```go
func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnValue uintptr, shouldReturn) func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnValue uintptr, shouldReturn)
``` ```
The `shouldReturn` value should be set to `true` if the returnValue should be returned by the main wndProc method. The `shouldReturn` value should be set to `true` if the returnValue should be
If it is set to `false`, the return value will be ignored and the message will continue to be processed by the main returned by the main wndProc method. If it is set to `false`, the return value
will be ignored and the message will continue to be processed by the main
wndProc method. wndProc method.
## Hide Window on Close + OnBeforeClose ## Hide Window on Close + OnBeforeClose
In v2, there was the `HideWindowOnClose` flag to hide the window when it closed. There was a logical overlap between In v2, there was the `HideWindowOnClose` flag to hide the window when it closed.
this flag and the `OnBeforeClose` callback. In v3, the `HideWindowOnClose` flag has been removed and the `OnBeforeClose` There was a logical overlap between this flag and the `OnBeforeClose` callback.
callback has been renamed to `ShouldClose`. The `ShouldClose` callback is called when the user attempts to close a In v3, the `HideWindowOnClose` flag has been removed and the `OnBeforeClose`
window. If the callback returns `true`, the window will close. If it returns `false`, the window will not close. callback has been renamed to `ShouldClose`. The `ShouldClose` callback is called
This can be used to hide the window instead of closing it. when the user attempts to close a window. If the callback returns `true`, the
window will close. If it returns `false`, the window will not close. This can be
used to hide the window instead of closing it.
## Window Drag ## Window Drag
In v2, the `--wails-drag` attribute was used to indicate that an element could be used to drag the window. In v2, the `--wails-drag` attribute was used to indicate that an element could
In v3, this has been replaced with `--webkit-app-region` to be more in line with the way other frameworks be used to drag the window. In v3, this has been replaced with
handle this. The `--webkit-app-region` attribute can be set to any of the following values: `--webkit-app-region` to be more in line with the way other frameworks handle
this. The `--webkit-app-region` attribute can be set to any of the following
values:
- `drag` - The element can be used to drag the window - `drag` - The element can be used to drag the window
- `no-drag` - The element cannot be used to drag the window - `no-drag` - The element cannot be used to drag the window
We would have ideally liked to use `app-region`, however this is not supported by the `getComputedStyle` call on We would have ideally liked to use `app-region`, however this is not supported
webkit on macOS. by the `getComputedStyle` call on webkit on macOS.

View File

@ -1,32 +1,35 @@
# Introduction # Introduction
!!! note !!! note This guide is a work in progress.
This guide is a work in progress.
Thanks for wanting to help out with development of Wails! This guide will help you get started. Thanks for wanting to help out with development of Wails! This guide will help
you get started.
## Getting Started ## Getting Started
- Git clone this repository. Checkout the `v3-alpha` branch. - Git clone this repository. Checkout the `v3-alpha` branch.
- Install the CLI: `cd v3/cmd/wails3 && go install` - Install the CLI: `cd v3/cmd/wails3 && go install`
- Optional: If you are wanting to use the build system to build frontend code, you will need to install [npm](https://nodejs.org/en/download). - Optional: If you are wanting to use the build system to build frontend code,
you will need to install [npm](https://nodejs.org/en/download).
## Building ## Building
For simple programs, you can use the standard `go build` command. It's also possible to use `go run`. For simple programs, you can use the standard `go build` command. It's also
possible to use `go run`.
Wails also comes with a build system that can be used to build more complex projects. It utilises the awesome [Task](https://taskfile.dev) build system. Wails also comes with a build system that can be used to build more complex
For more information, check out the task homepage or run `wails task --help`. projects. It utilises the awesome [Task](https://taskfile.dev) build system. For
more information, check out the task homepage or run `wails task --help`.
## Project layout ## Project layout
The project has the following structure: The project has the following structure:
``` ```
v3 v3
├── cmd/wails3 // CLI ├── cmd/wails3 // CLI
├── examples // Examples of Wails apps ├── examples // Examples of Wails apps
├── internal // Internal packages ├── internal // Internal packages
| ├── runtime // The Wails JS runtime | ├── runtime // The Wails JS runtime
| └── templates // The supported project templates | └── templates // The supported project templates
@ -44,18 +47,27 @@ The project has the following structure:
### Adding window functionality ### Adding window functionality
The preferred way to add window functionality is to add a new function to the `pkg/application/webview_window.go` file. This should implement all the functionality required for all platforms. Any platform specific code should be called via a `webviewWindowImpl` interface method. This interface is implemented by each of the target platforms to provide the platform specific functionality. In some cases, this may do nothing. The preferred way to add window functionality is to add a new function to the
Once you've added the interface method, ensure each platform implements it. A good example of this is the `SetMinSize` method. `pkg/application/webview_window.go` file. This should implement all the
functionality required for all platforms. Any platform specific code should be
called via a `webviewWindowImpl` interface method. This interface is implemented
by each of the target platforms to provide the platform specific functionality.
In some cases, this may do nothing. Once you've added the interface method,
ensure each platform implements it. A good example of this is the `SetMinSize`
method.
- Mac: `webview_window_darwin.go` - Mac: `webview_window_darwin.go`
- Windows: `webview_window_windows.go` - Windows: `webview_window_windows.go`
- Linux: `webview_window_linux.go` - Linux: `webview_window_linux.go`
Most, if not all, of the platform specific code should be run on the main thread. To simplify this, there are a number of `invokeSync` methods defined in `application.go`. Most, if not all, of the platform specific code should be run on the main
thread. To simplify this, there are a number of `invokeSync` methods defined in
`application.go`.
### Updating the runtime ### Updating the runtime
The runtime is located in `v3/internal/runtime`. When the runtime is updated, the following steps need to be taken: The runtime is located in `v3/internal/runtime`. When the runtime is updated,
the following steps need to be taken:
```shell ```shell
wails3 task runtime:build wails3 task runtime:build
@ -63,14 +75,19 @@ wails3 task runtime:build
### Events ### Events
Events are defined in `v3/pkg/events`. When adding a new event, the following steps need to be taken: Events are defined in `v3/pkg/events`. When adding a new event, the following
steps need to be taken:
- Add the event to the `events.txt` file - Add the event to the `events.txt` file
- Run `wails3 task events:generate` - Run `wails3 task events:generate`
There are a number of types of events: platform specific application and window events + common events. The common events are useful for cross-platform event handling, but you aren't limited to the "lowest common denominator". You can use the platform specific events if you need to. There are a number of types of events: platform specific application and window
events + common events. The common events are useful for cross-platform event
handling, but you aren't limited to the "lowest common denominator". You can use
the platform specific events if you need to.
When adding a common event, ensure that the platform specific events are mapped. An example of this is in `window_webview_darwin.go`: When adding a common event, ensure that the platform specific events are mapped.
An example of this is in `window_webview_darwin.go`:
```go ```go
// Translate ShouldClose to common WindowClosing event // Translate ShouldClose to common WindowClosing event
@ -79,7 +96,8 @@ When adding a common event, ensure that the platform specific events are mapped.
}) })
``` ```
NOTE: We may try to automate this in the future by adding the mapping to the event definition. NOTE: We may try to automate this in the future by adding the mapping to the
event definition.
### Plugins ### Plugins
@ -93,35 +111,39 @@ Plugins are standard Go structure that adhere to the following interface:
type Plugin interface { type Plugin interface {
Name() string Name() string
Init(*application.App) error Init(*application.App) error
Shutdown() Shutdown()
CallableByJS() []string CallableByJS() []string
InjectJS() string InjectJS() string
} }
``` ```
The `Name()` method returns the name of the plugin. This is used for logging purposes. The `Name()` method returns the name of the plugin. This is used for logging
purposes.
The `Init(*application.App) error` method is called when the plugin is loaded. The `*application.App` The `Init(*application.App) error` method is called when the plugin is loaded.
parameter is the application that the plugin is being loaded into. Any errors will prevent The `*application.App` parameter is the application that the plugin is being
the application from starting. loaded into. Any errors will prevent the application from starting.
The `Shutdown()` method is called when the application is shutting down. The `Shutdown()` method is called when the application is shutting down.
The `CallableByJS()` method returns a list of exported functions that can be called from The `CallableByJS()` method returns a list of exported functions that can be
the frontend. These method names must exactly match the names of the methods exported called from the frontend. These method names must exactly match the names of the
by the plugin. methods exported by the plugin.
The `InjectJS()` method returns JavaScript that should be injected into all windows as they are created. This is useful for adding custom JavaScript functions that complement the plugin.
The `InjectJS()` method returns JavaScript that should be injected into all
windows as they are created. This is useful for adding custom JavaScript
functions that complement the plugin.
## Misc Tasks ## Misc Tasks
### Upgrading Taskfile ### Upgrading Taskfile
The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported as a library and used to run the tasks defined in `Taskfile.yaml`. The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported
The main interfacing with Task happens in `v3/internal/commands/task.go`. as a library and used to run the tasks defined in `Taskfile.yaml`. The main
interfacing with Task happens in `v3/internal/commands/task.go`.
To check if there's an upgrade for Taskfile, run `wails3 task -version` and check against the Task website. To check if there's an upgrade for Taskfile, run `wails3 task -version` and
check against the Task website.
To upgrade the version of Taskfile used, run: To upgrade the version of Taskfile used, run:
@ -129,11 +151,15 @@ To upgrade the version of Taskfile used, run:
wails3 task taskfile:upgrade wails3 task taskfile:upgrade
``` ```
If there are incompatibilities then they should appear in the `v3/internal/commands/task.go` file. If there are incompatibilities then they should appear in the
`v3/internal/commands/task.go` file.
Usually the best way to fix incompatibilities is to clone the task repo at `https://github.com/go-task/task` and look at the git history to determine what has changed and why. Usually the best way to fix incompatibilities is to clone the task repo at
`https://github.com/go-task/task` and look at the git history to determine what
has changed and why.
To check all changes have worked correctly, re-install the CLI and check the version again: To check all changes have worked correctly, re-install the CLI and check the
version again:
```shell ```shell
wails3 task cli:install wails3 task cli:install
@ -142,18 +168,21 @@ wails3 task -version
## Opening a PR ## Opening a PR
Make sure that all PRs have a ticket associated with them providing context to the change. If there is no ticket, please create one first. Make sure that all PRs have a ticket associated with them providing context to
Ensure that all PRs have updated the CHANGELOG.md file with the changes made. The CHANGELOG.md file is located in the `v3` directory. the change. If there is no ticket, please create one first. Ensure that all PRs
have updated the CHANGELOG.md file with the changes made. The CHANGELOG.md file
is located in the `v3` directory.
## Misc Tasks ## Misc Tasks
### Upgrading Taskfile ### Upgrading Taskfile
The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported as a library and used to run the tasks defined in `Taskfile.yaml`. The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported
The main interfacing with Task happens in `v3/internal/commands/task.go`. as a library and used to run the tasks defined in `Taskfile.yaml`. The main
interfacing with Task happens in `v3/internal/commands/task.go`.
To check if there's an upgrade for Taskfile, run `wails3 task -version` and check against the Task website. To check if there's an upgrade for Taskfile, run `wails3 task -version` and
check against the Task website.
To upgrade the version of Taskfile used, run: To upgrade the version of Taskfile used, run:
@ -161,14 +190,17 @@ To upgrade the version of Taskfile used, run:
wails3 task taskfile:upgrade wails3 task taskfile:upgrade
``` ```
If there are incompatibilities then they should appear in the `v3/internal/commands/task.go` file. If there are incompatibilities then they should appear in the
`v3/internal/commands/task.go` file.
Usually the best way to fix incompatibilities is to clone the task repo at `https://github.com/go-task/task` and look at the git history to determine what has changed and why. Usually the best way to fix incompatibilities is to clone the task repo at
`https://github.com/go-task/task` and look at the git history to determine what
has changed and why.
To check all changes have worked correctly, re-install the CLI and check the version again: To check all changes have worked correctly, re-install the CLI and check the
version again:
```shell ```shell
wails3 task cli:install wails3 task cli:install
wails3 task -version wails3 task -version
``` ```

View File

@ -16,10 +16,10 @@ Status of features in v3.
Application interface methods Application interface methods
| Method | Windows | Linux | Mac | Notes | | Method | Windows | Linux | Mac | Notes |
|---------------------------------------------------------------|---------|-------|-----|-------| | ------------------------------------------------------------- | ------- | ----- | --- | ----- |
| run() error | Y | Y | Y | | | run() error | Y | Y | Y | |
| destroy() | | Y | Y | | | destroy() | | Y | Y | |
| setApplicationMenu(menu *Menu) | Y | Y | Y | | | setApplicationMenu(menu \*Menu) | Y | Y | Y | |
| name() string | | Y | Y | | | name() string | | Y | Y | |
| getCurrentWindowID() uint | Y | Y | Y | | | getCurrentWindowID() uint | Y | Y | Y | |
| showAboutDialog(name string, description string, icon []byte) | | Y | Y | | | showAboutDialog(name string, description string, icon []byte) | | Y | Y | |
@ -28,15 +28,15 @@ Application interface methods
| dispatchOnMainThread(fn func()) | Y | Y | Y | | | dispatchOnMainThread(fn func()) | Y | Y | Y | |
| hide() | Y | Y | Y | | | hide() | Y | Y | Y | |
| show() | Y | Y | Y | | | show() | Y | Y | Y | |
| getPrimaryScreen() (*Screen, error) | | Y | Y | | | getPrimaryScreen() (\*Screen, error) | | Y | Y | |
| getScreens() ([]*Screen, error) | | Y | Y | | | getScreens() ([]\*Screen, error) | | Y | Y | |
## Webview Window ## Webview Window
Webview Window Interface Methods Webview Window Interface Methods
| Method | Windows | Linux | Mac | Notes | | Method | Windows | Linux | Mac | Notes |
|----------------------------------------------------|---------|-------|-----|------------------------------------------| | -------------------------------------------------- | ------- | ----- | --- | ---------------------------------------- |
| center() | Y | Y | Y | | | center() | Y | Y | Y | |
| close() | y | Y | Y | | | close() | y | Y | Y | |
| destroy() | | Y | Y | | | destroy() | | Y | Y | |
@ -44,7 +44,7 @@ Webview Window Interface Methods
| focus() | Y | Y | | | | focus() | Y | Y | | |
| forceReload() | | Y | Y | | | forceReload() | | Y | Y | |
| fullscreen() | Y | Y | Y | | | fullscreen() | Y | Y | Y | |
| getScreen() (*Screen, error) | y | Y | Y | | | getScreen() (\*Screen, error) | y | Y | Y | |
| getZoom() float64 | | Y | Y | | | getZoom() float64 | | Y | Y | |
| height() int | Y | Y | Y | | | height() int | Y | Y | Y | |
| hide() | Y | Y | Y | | | hide() | Y | Y | Y | |
@ -90,7 +90,7 @@ Webview Window Interface Methods
### Application ### Application
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|---------|---------|-------|-----|-------| | ------- | ------- | ----- | --- | ----- |
| Quit | Y | Y | Y | | | Quit | Y | Y | Y | |
| Hide | Y | | Y | | | Hide | Y | | Y | |
| Show | Y | | Y | | | Show | Y | | Y | |
@ -98,7 +98,7 @@ Webview Window Interface Methods
### Dialogs ### Dialogs
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|----------|---------|-------|-----|-------| | -------- | ------- | ----- | --- | ----- |
| Info | Y | Y | Y | | | Info | Y | Y | Y | |
| Warning | Y | Y | Y | | | Warning | Y | Y | Y | |
| Error | Y | Y | Y | | | Error | Y | Y | Y | |
@ -109,30 +109,32 @@ Webview Window Interface Methods
### Clipboard ### Clipboard
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|---------|---------|-------|-----|-------| | ------- | ------- | ----- | --- | ----- |
| SetText | Y | | Y | | | SetText | Y | | Y | |
| Text | Y | | Y | | | Text | Y | | Y | |
### ContextMenu ### ContextMenu
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|------------------|---------|-------|-----|-------| | ---------------- | ------- | ----- | --- | ----- |
| OpenContextMenu | Y | | Y | | | OpenContextMenu | Y | | Y | |
| On By Default | | | | | | On By Default | | | | |
| Control via HTML | Y | | | | | Control via HTML | Y | | | |
The default context menu is enabled by default for all elements that are `contentEditable: true`, `<input>` The default context menu is enabled by default for all elements that are
or `<textarea>` tags or have the `--default-contextmenu: true` style set. `contentEditable: true`, `<input>` or `<textarea>` tags or have the
The `--default-contextmenu: show` style will always show the context menu `--default-contextmenu: true` style set. The `--default-contextmenu: show` style
The `--default-contextmenu: hide` style will always hide the context menu will always show the context menu The `--default-contextmenu: hide` style will
always hide the context menu
Anything nested under a tag with `--default-contextmenu: hide` style will not show the context menu unless it is Anything nested under a tag with `--default-contextmenu: hide` style will not
explicitly set with `--default-contextmenu: show`. show the context menu unless it is explicitly set with
`--default-contextmenu: show`.
### Screens ### Screens
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|------------|---------|-------|-----|-------| | ---------- | ------- | ----- | --- | ----- |
| GetAll | Y | Y | Y | | | GetAll | Y | Y | Y | |
| GetPrimary | Y | Y | Y | | | GetPrimary | Y | Y | Y | |
| GetCurrent | Y | Y | Y | | | GetCurrent | Y | Y | Y | |
@ -140,18 +142,17 @@ explicitly set with `--default-contextmenu: show`.
### System ### System
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|------------|---------|-------|-----|-------| | ---------- | ------- | ----- | --- | ----- |
| IsDarkMode | | | Y | | | IsDarkMode | | | Y | |
### Window ### Window
Y = Supported Y = Supported U = Untested
U = Untested
- = Not available - = Not available
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|---------------------|---------|-------|-----|--------------------------------------------------------------------------------------| | ------------------- | ------- | ----- | --- | ------------------------------------------------------------------------------------ |
| Center | Y | Y | Y | | | Center | Y | Y | Y | |
| Focus | Y | Y | | | | Focus | Y | Y | | |
| FullScreen | Y | Y | Y | | | FullScreen | Y | Y | Y | |
@ -184,11 +185,12 @@ U = Untested
### Window Options ### Window Options
A 'Y' in the table below indicates that the option has been tested and is applied when the window is created. A 'Y' in the table below indicates that the option has been tested and is
An 'X' indicates that the option is not supported by the platform. applied when the window is created. An 'X' indicates that the option is not
supported by the platform.
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|---------------------------------|---------|-------|-----|--------------------------------------------| | ------------------------------- | ------- | ----- | --- | ------------------------------------------ |
| AlwaysOnTop | Y | | | | | AlwaysOnTop | Y | | | |
| BackgroundColour | Y | Y | | | | BackgroundColour | Y | Y | | |
| BackgroundType | | | | Acrylic seems to work but the others don't | | BackgroundType | | | | Acrylic seems to work but the others don't |
@ -228,13 +230,13 @@ To log or not to log? System logger vs custom logger.
## Menu ## Menu
| Event | Windows | Linux | Mac | Notes | | Event | Windows | Linux | Mac | Notes |
|--------------------------|---------|-------|-----|-------| | ------------------------ | ------- | ----- | --- | ----- |
| Default Application Menu | Y | Y | Y | | | Default Application Menu | Y | Y | Y | |
## Tray Menus ## Tray Menus
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|--------------------|---------|-------|-----|----------------------------------------------------------------------| | ------------------ | ------- | ----- | --- | -------------------------------------------------------------------- |
| Icon | Y | | Y | Windows has default icons for light/dark mode & supports PNG or ICO. | | Icon | Y | | Y | Windows has default icons for light/dark mode & supports PNG or ICO. |
| Label | - | | Y | | | Label | - | | Y | |
| Label (ANSI Codes) | - | | | | | Label (ANSI Codes) | - | | | |
@ -243,11 +245,11 @@ To log or not to log? System logger vs custom logger.
### Methods ### Methods
| Method | Windows | Linux | Mac | Notes | | Method | Windows | Linux | Mac | Notes |
|-------------------------------|---------|-------|-----|-------| | ----------------------------- | ------- | ----- | --- | ----- |
| setLabel(label string) | - | | Y | | | setLabel(label string) | - | | Y | |
| run() | Y | | Y | | | run() | Y | | Y | |
| setIcon(icon []byte) | Y | | Y | | | setIcon(icon []byte) | Y | | Y | |
| setMenu(menu *Menu) | Y | | Y | | | setMenu(menu \*Menu) | Y | | Y | |
| setIconPosition(position int) | - | | Y | | | setIconPosition(position int) | - | | Y | |
| setTemplateIcon(icon []byte) | - | | Y | | | setTemplateIcon(icon []byte) | - | | Y | |
| destroy() | Y | | Y | | | destroy() | Y | | Y | |
@ -258,7 +260,7 @@ To log or not to log? System logger vs custom logger.
Mapping native events to cross-platform events. Mapping native events to cross-platform events.
| Event | Windows | Linux | Mac | Notes | | Event | Windows | Linux | Mac | Notes |
|--------------------------|---------|-------|-----------------|-------| | ------------------------ | ------- | ----- | --------------- | ----- |
| WindowWillClose | | | WindowWillClose | | | WindowWillClose | | | WindowWillClose | |
| WindowDidClose | | | | | | WindowDidClose | | | | |
| WindowDidResize | | | | | | WindowDidResize | | | | |
@ -282,7 +284,7 @@ Contains a lot needed for development.
## Theme ## Theme
| Mode | Windows | Linux | Mac | Notes | | Mode | Windows | Linux | Mac | Notes |
|--------|---------|-------|-----|-------| | ------ | ------- | ----- | --- | ----- |
| Dark | Y | | | | | Dark | Y | | | |
| Light | Y | | | | | Light | Y | | | |
| System | Y | | | | | System | Y | | | |
@ -300,7 +302,7 @@ All templates are working.
Built-in plugin support: Built-in plugin support:
| Plugin | Windows | Linux | Mac | Notes | | Plugin | Windows | Linux | Mac | Notes |
|-----------------|---------|-------|-----|-------| | --------------- | ------- | ----- | --- | ----- |
| Browser | Y | | Y | | | Browser | Y | | Y | |
| KV Store | Y | Y | Y | | | KV Store | Y | Y | Y | |
| Log | Y | Y | Y | | | Log | Y | Y | Y | |
@ -316,7 +318,7 @@ TODO:
## Packaging ## Packaging
| | Windows | Linux | Mac | Notes | | | Windows | Linux | Mac | Notes |
|-----------------|---------|-------|-----|-------| | --------------- | ------- | ----- | --- | ----- |
| Icon Generation | Y | | Y | | | Icon Generation | Y | | Y | |
| Icon Embedding | Y | | Y | | | Icon Embedding | Y | | Y | |
| Info.plist | - | | Y | | | Info.plist | - | | Y | |
@ -327,7 +329,7 @@ TODO:
## Frameless Windows ## Frameless Windows
| Feature | Windows | Linux | Mac | Notes | | Feature | Windows | Linux | Mac | Notes |
|---------|---------|-------|-----|------------------------------------------------| | ------- | ------- | ----- | --- | ---------------------------------------------- |
| Resize | Y | | Y | | | Resize | Y | | Y | |
| Drag | Y | Y | Y | Linux - can always drag with `Meta`+left mouse | | Drag | Y | Y | Y | Linux - can always drag with `Meta`+left mouse |
@ -338,7 +340,7 @@ TODO:
### Mac Options ### Mac Options
| Feature | Default | Notes | | Feature | Default | Notes |
|-------------------------|-------------------|------------------------------------------------------| | ----------------------- | ----------------- | ---------------------------------------------------- |
| Backdrop | MacBackdropNormal | Standard solid window | | Backdrop | MacBackdropNormal | Standard solid window |
| DisableShadow | false | | | DisableShadow | false | |
| TitleBar | | Standard window decorations by default | | TitleBar | | Standard window decorations by default |
@ -354,7 +356,7 @@ TODO:
### Windows Options ### Windows Options
| Feature | Default | Notes | | Feature | Default | Notes |
|-----------------------------------|---------------|---------------------------------------------| | --------------------------------- | ------------- | ------------------------------------------- |
| BackdropType | Solid | | | BackdropType | Solid | |
| DisableIcon | false | | | DisableIcon | false | |
| Theme | SystemDefault | | | Theme | SystemDefault | |
@ -364,15 +366,17 @@ TODO:
## Linux Specific ## Linux Specific
Implementation details for the functions utilized by the `*_linux.go` files are located in the following files: Implementation details for the functions utilized by the `*_linux.go` files are
located in the following files:
- linux_cgo.go: CGo implementation - linux_cgo.go: CGo implementation
- linux_purego.go: PureGo implementation - linux_purego.go: PureGo implementation
### CGO ### CGO
By default CGO is utilized to compile the Linux port. This prevents easy cross-compilation and so the PureGo By default CGO is utilized to compile the Linux port. This prevents easy
implementation is also being simultaneously developed. cross-compilation and so the PureGo implementation is also being simultaneously
developed.
### Purego ### Purego
@ -385,7 +389,7 @@ Note: things are currently not working after the refactor
## Examples ## Examples
| Example | Windows | Linux | Mac | | Example | Windows | Linux | Mac |
|--------------|----------------------|-------|-----| | ------------ | -------------------- | ----- | --- |
| binding | NO | | | | binding | NO | | |
| build | Yes (Debug + Prod) | | | | build | Yes (Debug + Prod) | | |
| clipboard | Yes | | | | clipboard | Yes | | |

View File

@ -1,11 +1,12 @@
# Feedback # Feedback
We welcome (and encourage) your feedback! Here are the different ways to provide feedback: We welcome (and encourage) your feedback! Here are the different ways to provide
feedback:
=== "Bugs" === "Bugs"
If you find a bug, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel on Discord: If you find a bug, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel on Discord:
- The post should clearly state what the bug is and have a simple reproducible example. If the docs are unclear what *should* happen, please include that in the post. - The post should clearly state what the bug is and have a simple reproducible example. If the docs are unclear what *should* happen, please include that in the post.
- The post should be given the `Bug` tag. - The post should be given the `Bug` tag.
- Please include the output of `wails doctor` in your post. - Please include the output of `wails doctor` in your post.
@ -14,12 +15,12 @@ We welcome (and encourage) your feedback! Here are the different ways to provide
=== "Fixes" === "Fixes"
If you have a fix for a bug or an update for documentation, please do the following: If you have a fix for a bug or an update for documentation, please do the following:
- Open a pull request on the [Wails repository](https://github.com/wailsapp/wails). The title of the PR should start with `[v3]`. - Open a pull request on the [Wails repository](https://github.com/wailsapp/wails). The title of the PR should start with `[v3]`.
- Create a post in the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel. - Create a post in the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel.
- The post should be given the `PR` tag. - The post should be given the `PR` tag.
- Please include a link to the PR in your post. - Please include a link to the PR in your post.
=== "Suggestions" === "Suggestions"
If you have a suggestion, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel on Discord: If you have a suggestion, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/3mgVyGua) channel on Discord:
@ -30,27 +31,26 @@ We welcome (and encourage) your feedback! Here are the different ways to provide
=== "Upvoting" === "Upvoting"
- Posts can be "upvoted" by using the :thumbsup: emoji. Please apply to any posts that are a priority for you. - Posts can be "upvoted" by using the :thumbsup: emoji. Please apply to any posts that are a priority for you.
- Please *don't* just add comments like "+1" or "me too". - Please *don't* just add comments like "+1" or "me too".
- Please feel free to comment if there is more to add to the post, such as "this bug also affect ARM builds" or "Another option would be to ....." - Please feel free to comment if there is more to add to the post, such as "this bug also affect ARM builds" or "Another option would be to ....."
Things we are looking for feedback on: Things we are looking for feedback on:
- The API - The API
- Is it easy to use? - Is it easy to use?
- Does it do what you expect? - Does it do what you expect?
- Is it missing anything? - Is it missing anything?
- Is there anything that should be removed? - Is there anything that should be removed?
- Is it consistent between Go and JS? - Is it consistent between Go and JS?
- The build system - The build system
- Is it easy to use? - Is it easy to use?
- Can we improve it? - Can we improve it?
- The examples - The examples
- Are they clear? - Are they clear?
- Do they cover the basics? - Do they cover the basics?
- Features - Features
- What features are missing? - What features are missing?
- What features are not needed? - What features are not needed?
- Documentation - Documentation
- What could be clearer? - What could be clearer?

View File

@ -1,7 +1,7 @@
# Installation # Installation
To install the Wails CLI, ensure you have [Go 1.21+](https://go.dev/dl/)
To install the Wails CLI, ensure you have [Go 1.21+](https://go.dev/dl/) installed and run: installed and run:
```shell ```shell
go install github.com/wailsapp/wails/v3/cmd/wails3@latest go install github.com/wailsapp/wails/v3/cmd/wails3@latest
@ -21,9 +21,9 @@ Wails has a number of common dependencies that are required before installation:
=== "Go 1.21+" === "Go 1.21+"
Download Go from the [Go Downloads Page](https://go.dev/dl/). Download Go from the [Go Downloads Page](https://go.dev/dl/).
Ensure that you follow the official [Go installation instructions](https://go.dev/doc/install). You will also need to ensure that your `PATH` environment variable also includes the path to your `~/go/bin` directory. Restart your terminal and do the following checks: Ensure that you follow the official [Go installation instructions](https://go.dev/doc/install). You will also need to ensure that your `PATH` environment variable also includes the path to your `~/go/bin` directory. Restart your terminal and do the following checks:
- Check Go is installed correctly: `go version` - Check Go is installed correctly: `go version`
- Check `~/go/bin` is in your PATH variable: `echo $PATH | grep go/bin` - Check `~/go/bin` is in your PATH variable: `echo $PATH | grep go/bin`
@ -32,7 +32,7 @@ Wails has a number of common dependencies that are required before installation:
Although Wails doesn't require npm to be installed, it is needed if you want to use the bundled templates. Although Wails doesn't require npm to be installed, it is needed if you want to use the bundled templates.
Download the latest node installer from the [Node Downloads Page](https://nodejs.org/en/download/). It is best to use the latest release as that is what we generally test against. Download the latest node installer from the [Node Downloads Page](https://nodejs.org/en/download/). It is best to use the latest release as that is what we generally test against.
Run `npm --version` to verify. Run `npm --version` to verify.
=== "Task (Optional)" === "Task (Optional)"
@ -63,12 +63,15 @@ You will also need to install platform specific dependencies:
## System Check ## System Check
Running `wails3 doctor` will check if you have the correct dependencies installed. If not, it will advise on what is missing and help on how to rectify any problems. Running `wails3 doctor` will check if you have the correct dependencies
installed. If not, it will advise on what is missing and help on how to rectify
any problems.
## The `wails3` command appears to be missing? ## The `wails3` command appears to be missing?
If your system is reporting that the `wails3` command is missing, check the following: If your system is reporting that the `wails3` command is missing, check the
following:
- Make sure you have followed the Go installation guide correctly.
- Check that the `go/bin` directory is in the `PATH` environment variable. - Make sure you have followed the Go installation guide correctly.
- Close/Reopen current terminals to pick up the new `PATH` variable. - Check that the `go/bin` directory is in the `PATH` environment variable.
- Close/Reopen current terminals to pick up the new `PATH` variable.

View File

@ -2,7 +2,8 @@
Now that you have Wails installed, you can start exploring the alpha version. Now that you have Wails installed, you can start exploring the alpha version.
The best place to start is the `examples` directory in the Wails repository. This contains a number of examples that you can run and play with. The best place to start is the `examples` directory in the Wails repository.
This contains a number of examples that you can run and play with.
## Running an example ## Running an example
@ -11,23 +12,26 @@ To run an example, you can simply use:
```shell ```shell
go run . go run .
``` ```
in the example directory. in the example directory.
## Creating a new project ## Creating a new project
To create a new project, you can use the `wails3 init` command. This will create a new project in the current directory. To create a new project, you can use the `wails3 init` command. This will create
a new project in the current directory.
Wails3 uses [Task](https://taskfile.dev) as its build system by default, although there is no reason why you can't Wails3 uses [Task](https://taskfile.dev) as its build system by default,
use your own build system, or use `go build` directly. Wails has the task build system built in and can be run using `wails3 task`. although there is no reason why you can't use your own build system, or use
`go build` directly. Wails has the task build system built in and can be run
using `wails3 task`.
If you look through the `Taskfile.yaml` file, you will see that there are a number of tasks defined. The most important If you look through the `Taskfile.yaml` file, you will see that there are a
one is the `build` task. This is the task that is run when you use `wails3 build`. number of tasks defined. The most important one is the `build` task. This is the
task that is run when you use `wails3 build`.
The task file is unlikely to be complete and is subject to change over time. The task file is unlikely to be complete and is subject to change over time.
## Building a project ## Building a project
To build a project, you can use the `wails3 build` command. This is a shortcut for `wails3 task build`. To build a project, you can use the `wails3 build` command. This is a shortcut
for `wails3 task build`.

View File

@ -1,11 +1,12 @@
# What's new in v3? # What's new in v3?
!!! note !!! note The features that will be included in the v3 release may change from
The features that will be included in the v3 release may change from this list. this list.
## Multiple Windows ## Multiple Windows
It's now possible to create multiple windows and configure each one independently. It's now possible to create multiple windows and configure each one
independently.
```go ```go
package main package main
@ -40,7 +41,7 @@ func main() {
// load the embedded html from the embed.FS // load the embedded html from the embed.FS
window1.SetURL("/") window1.SetURL("/")
window1.Center() window1.Center()
// Load an external URL // Load an external URL
window2.SetURL("https://wails.app") window2.SetURL("https://wails.app")
@ -55,10 +56,11 @@ func main() {
## Systrays ## Systrays
Systrays allow you to add an icon in the system tray area of your desktop and have the following features: 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) - Attach window (the window will be centered to the systray icon)
- Full menu support - Full menu support
- Light/Dark mode icons - Light/Dark mode icons
```go ```go
@ -93,23 +95,23 @@ func main() {
}) })
systemTray := app.NewSystemTray() systemTray := app.NewSystemTray()
// Support for template icons on macOS // Support for template icons on macOS
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
systemTray.SetTemplateIcon(icons.SystrayMacTemplate) systemTray.SetTemplateIcon(icons.SystrayMacTemplate)
} else { } else {
// Support for light/dark mode icons // Support for light/dark mode icons
systemTray.SetDarkModeIcon(icons.SystrayDark) systemTray.SetDarkModeIcon(icons.SystrayDark)
systemTray.SetIcon(icons.SystrayLight) systemTray.SetIcon(icons.SystrayLight)
} }
// Support for menu // Support for menu
myMenu := app.NewMenu() myMenu := app.NewMenu()
myMenu.Add("Hello World!").OnClick(func(_ *application.Context) { myMenu.Add("Hello World!").OnClick(func(_ *application.Context) {
println("Hello World!") println("Hello World!")
}) })
systemTray.SetMenu(myMenu) systemTray.SetMenu(myMenu)
// This will center the window to the systray icon with a 5px offset // This will center the window to the systray icon with a 5px offset
// It will automatically be shown when the systray icon is clicked // It will automatically be shown when the systray icon is clicked
// and hidden when the window loses focus // and hidden when the window loses focus
@ -125,7 +127,8 @@ func main() {
## Plugins ## 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: 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 - kvstore - A key/value store
- browser - open links in a browser - browser - open links in a browser
@ -137,74 +140,88 @@ Plugins allow you to extend the functionality of the Wails system. Not only can
## Improved bindings generation ## 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. v3 uses a new static analyser to generate bindings. This makes it extremely fast
By default, bindings are generated with calls using IDs instead of strings. This provides a performance boost and allows and maintains comments and parameter names in your bindings. By default,
for using obfuscation tools such as [garble](https://github.com/burrowers/garble). bindings are generated with calls using IDs instead of strings. This provides a
performance boost and allows for using obfuscation tools such as
[garble](https://github.com/burrowers/garble).
Bindings are generated by simply running `wails3 generate bindings` in the project directory. Bindings are generated by simply running `wails3 generate bindings` in the
project directory.
```js ```js
// @ts-check // @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
import {main} from './models'; import { main } from "./models";
window.go = window.go || {}; window.go = window.go || {};
window.go.main = { window.go.main = {
GreetService: { GreetService: {
/**
/** * GreetService.Greet
* GreetService.Greet * Greet greets a person
* Greet greets a person * @param name {string}
* @param name {string} * @returns {Promise<string>}
* @returns {Promise<string>} **/
**/ Greet: function (name) {
Greet: function(name) { wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); }, 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)); },
}, },
};
/**
* 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 ## Improved build system
In v2, the build system was completely opaque and hard to customise. In v2, the build system was completely opaque and hard to customise. In v3, it's
In v3, it's possible to build everything using standard Go tooling. 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. All the heavy lifting that the v2 build system did, such as icon generation,
We have incorporated [Taskfile](https://taskfile.dev) into the CLI to orchestrate these calls to bring the same developer experience as v2. have been added as tool commands in the CLI. We have incorporated
However, this approach brings the ultimate balance of flexibility and ease of use as you can now customise the build process to your needs. [Taskfile](https://taskfile.dev) 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! You can even use make if that's your thing!
```yaml title="Snippet from Taskfile.yml" ```yaml title="Snippet from Taskfile.yml"
build:darwin: build:darwin:
summary: Builds the application summary: Builds the application
platforms: platforms:
- darwin - darwin
cmds: cmds:
- task: pre-build - task: pre-build
- task: build-frontend - task: build-frontend
- go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}} - go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}}
- task: post-build - task: post-build
env: env:
CGO_CFLAGS: "-mmacosx-version-min=10.13" CGO_CFLAGS: "-mmacosx-version-min=10.13"
CGO_LDFLAGS: "-mmacosx-version-min=10.13" CGO_LDFLAGS: "-mmacosx-version-min=10.13"
MACOSX_DEPLOYMENT_TARGET: "10.13" MACOSX_DEPLOYMENT_TARGET: "10.13"
``` ```
## Improved events ## 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. 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. 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.
```go ```go
package main package main
@ -281,21 +298,26 @@ func main() {
## Wails Markup Language (wml) ## Wails Markup Language (wml)
An experimental feature to call runtime methods using plain html, similar to [htmx](https://htmx.org). An experimental feature to call runtime methods using plain html, similar to
[htmx](https://htmx.org).
```html ```html
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>Wails ML Demo</title> <title>Wails ML Demo</title>
</head> </head>
<body style="margin-top:50px; color: white; background-color: #191919"> <body style="margin-top:50px; color: white; background-color: #191919">
<h2>Wails ML Demo</h2> <h2>Wails ML Demo</h2>
<p>This application contains no Javascript!</p> <p>This application contains no Javascript!</p>
<button data-wml-event="button-pressed">Press me!</button> <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-event="delete-things" data-wml-confirm="Are you sure?">
<button data-wml-window="Close" data-wml-confirm="Are you sure?">Close the Window?</button> 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="Center">Center</button>
<button data-wml-window="Minimise">Minimise</button> <button data-wml-window="Minimise">Minimise</button>
<button data-wml-window="Maximise">Maximise</button> <button data-wml-window="Maximise">Maximise</button>
@ -303,7 +325,13 @@ An experimental feature to call runtime methods using plain html, similar to [ht
<button data-wml-window="Fullscreen">Fullscreen</button> <button data-wml-window="Fullscreen">Fullscreen</button>
<button data-wml-window="UnFullscreen">UnFullscreen</button> <button data-wml-window="UnFullscreen">UnFullscreen</button>
<button data-wml-window="Restore">Restore</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> <div
</body> style="width: 200px; height: 200px; border: 2px solid white;"
data-wml-event="hover"
data-wml-trigger="mouseover"
>
Hover over me
</div>
</body>
</html> </html>
``` ```

View File

@ -118,6 +118,7 @@ tasks:
- echo "Generated templates" - echo "Generated templates"
format:md: format:md:
dir: ../mkdocs-website
cmds: cmds:
- npx prettier --write "**/*.md" - npx prettier --write "**/*.md"
@ -128,5 +129,7 @@ tasks:
precommit: precommit:
cmds: cmds:
- go test ./... - go test ./...
- task: format
- task: docs:update:api