Merge remote-tracking branch 'upstream/v3-alpha' into v3-alpha

This commit is contained in:
Lea Anthony 2025-07-12 14:39:22 +10:00
commit cbfbf4699a
19 changed files with 3383 additions and 1437 deletions

1240
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
"@types/react-dom": "19.0.2",
"astro": "4.16.17",
"framer-motion": "11.14.4",
"mermaid": "^10.9.3",
"motion": "11.14.4",
"react": "19.0.0",
"react-dom": "19.0.0",

View file

@ -0,0 +1,52 @@
---
title: Alpha 10 Released - A New Chapter for Wails
description: Announcing Wails v3 Alpha 10 and our new daily release strategy
date: 2024-12-03
author: The Wails Team
---
# Alpha 10 Released - A New Chapter for Wails
We're thrilled to announce the release of **Wails v3 Alpha 10** - and it's big! While our release cadence may have seemed slow recently, there's been an incredible amount of work happening behind the scenes. Today marks not just another release, but a shift in how we approach the development of Wails.
## Why the Wait?
Like many development teams, we fell into the trap of trying to achieve perfection before each release. We wanted to squash every bug, polish every feature, and ensure everything was just right. But here's the thing - software is never truly bug-free, and waiting for that mythical state only delays getting improvements into your hands.
## Our New Release Strategy
Starting today, we're adopting a **daily release strategy**. Any new changes merged during the day will be released at the end of that day. This approach will:
- Get bug fixes and features to you faster
- Provide more frequent feedback loops
- Speed up our journey to Beta
- Make the development process more transparent
This means you might see more frequent, smaller releases rather than occasional large ones. We believe this will benefit everyone in the Wails community.
## How You Can Help
We've been overwhelmed by the number of people wanting to contribute to Wails! To make it easier for contributors to get involved, we're implementing a new system:
- Firstly, we are opening up bug reporting for alpha releases. The frequent releases allow us to do this.
- Issues marked with **"Ready for Work"** are open for community contributions
- These issues have clear requirements and are ready to be tackled
- Most importantly, **we need people testing PRs** - this is one of the most valuable contributions you can make
Testing doesn't require deep knowledge of the codebase, but it provides immense value by ensuring changes work across different environments and use cases.
## What's Next?
With our new daily release strategy, expect to see rapid progress toward Beta. We're committed to maintaining momentum and getting Wails v3 to a stable release as quickly as possible without sacrificing quality.
And who knows? There might be a few surprises along the way... 😉
## Thank You
To everyone who has contributed code, tested releases, reported bugs, or simply used Wails - thank you. Your support and feedback drive this project forward.
Here's to more frequent releases, faster iteration, and an exciting journey ahead!
---
*Want to get involved? Check out our [GitHub repository](https://github.com/wailsapp/wails) for issues marked "ready for work", or join our community to help test the latest changes.*

View file

@ -25,6 +25,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## Added
- Add distribution-specific build dependencies for Linux by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/4345)
- Added bindings guide by @atterpac in [PR](https://github.com/wailsapp/wails/pull/4404)
## v3.0.0-alpha.10 - 2025-07-06
### Breaking Changes
- **Manager API Refactoring**: Reorganized application API from flat structure to organized managers for better code organization and discoverability by [@leaanthony](https://github.com/leaanthony) in [#4359](https://github.com/wailsapp/wails/pull/4359)

View file

@ -1,3 +1,8 @@
---
title: MSIX Packaging (Windows)
description: Guide for creating MSIX packages with Wails v3
---
# MSIX Packaging (Windows)
Wails v3 can generate modern **MSIX** installers for Windows applications, providing a cleaner, safer and Store-ready alternative to traditional **NSIS** or plain `.exe` bundles.

View file

@ -0,0 +1,342 @@
---
title: Advanced Binding Techniques
sidebar:
order: 22
---
import { FileTree } from "@astrojs/starlight/components";
This guide covers advanced techniques for customizing and optimizing the binding generation process in Wails v3.
## Customizing Generated Code with Directives
### Injecting Custom Code
The `//wails:inject` directive allows you to inject custom JavaScript/TypeScript code into the generated bindings:
```go
//wails:inject console.log("Hello from Wails!");
type MyService struct {}
func (s *MyService) Greet(name string) string {
return "Hello, " + name
}
```
This will inject the specified code into the generated JavaScript/TypeScript file for the `MyService` service.
You can also use conditional injection to target specific output formats:
```go
//wails:inject j*:console.log("Hello JS!"); // JavaScript only
//wails:inject t*:console.log("Hello TS!"); // TypeScript only
```
### Including Additional Files
The `//wails:include` directive allows you to include additional files with the generated bindings:
```go
//wails:include js/*.js
package mypackage
```
This directive is typically used in package documentation comments to include additional JavaScript/TypeScript files with the generated bindings.
### Marking Internal Types and Methods
The `//wails:internal` directive marks a type or method as internal, preventing it from being exported to the frontend:
```go
//wails:internal
type InternalModel struct {
Field string
}
//wails:internal
func (s *MyService) InternalMethod() {}
```
This is useful for types and methods that are only used internally by your Go code and should not be exposed to the frontend.
### Ignoring Methods
The `//wails:ignore` directive completely ignores a method during binding generation:
```go
//wails:ignore
func (s *MyService) IgnoredMethod() {}
```
This is similar to `//wails:internal`, but it completely ignores the method rather than marking it as internal.
### Custom Method IDs
The `//wails:id` directive specifies a custom ID for a method, overriding the default hash-based ID:
```go
//wails:id 42
func (s *MyService) CustomIDMethod() {}
```
This can be useful for maintaining compatibility when refactoring code.
## Working with Complex Types
### Nested Structs
The binding generator handles nested structs automatically:
```go
type Address struct {
Street string
City string
State string
Zip string
}
type Person struct {
Name string
Address Address
}
func (s *MyService) GetPerson() Person {
return Person{
Name: "John Doe",
Address: Address{
Street: "123 Main St",
City: "Anytown",
State: "CA",
Zip: "12345",
},
}
}
```
The generated JavaScript/TypeScript code will include classes for both `Person` and `Address`.
### Maps and Slices
Maps and slices are also handled automatically:
```go
type Person struct {
Name string
Attributes map[string]string
Friends []string
}
func (s *MyService) GetPerson() Person {
return Person{
Name: "John Doe",
Attributes: map[string]string{
"hair": "brown",
"eyes": "blue",
},
Friends: []string{"Jane", "Bob", "Alice"},
}
}
```
In JavaScript, maps are represented as objects and slices as arrays. In TypeScript, maps are represented as `Record<K, V>` and slices as `T[]`.
### Generic Types
The binding generator supports generic types:
```go
type Result[T any] struct {
Data T
Error string
}
func (s *MyService) GetResult() Result[string] {
return Result[string]{
Data: "Hello, World!",
Error: "",
}
}
```
The generated TypeScript code will include a generic class for `Result`:
```typescript
export class Result<T> {
"Data": T;
"Error": string;
constructor(source: Partial<Result<T>> = {}) {
if (!("Data" in source)) {
this["Data"] = null as any;
}
if (!("Error" in source)) {
this["Error"] = "";
}
Object.assign(this, source);
}
static createFrom<T>(source: string | object = {}): Result<T> {
let parsedSource = typeof source === "string" ? JSON.parse(source) : source;
return new Result<T>(parsedSource as Partial<Result<T>>);
}
}
```
### Interfaces
The binding generator can generate TypeScript interfaces instead of classes using the `-i` flag:
```bash
wails3 generate bindings -ts -i
```
This will generate TypeScript interfaces for all models:
```typescript
export interface Person {
Name: string;
Attributes: Record<string, string>;
Friends: string[];
}
```
## Optimizing Binding Generation
### Using Names Instead of IDs
By default, the binding generator uses hash-based IDs for method calls. You can use the `-names` flag to use names instead:
```bash
wails3 generate bindings -names
```
This will generate code that uses method names instead of IDs:
```javascript
export function Greet(name) {
let $resultPromise = $Call.ByName("Greet", name);
return $resultPromise;
}
```
This can make the generated code more readable and easier to debug, but it may be slightly less efficient.
### Bundling the Runtime
By default, the generated code imports the Wails runtime from the `@wailsio/runtime` npm package. You can use the `-b` flag to bundle the runtime with the generated code:
```bash
wails3 generate bindings -b
```
This will include the runtime code directly in the generated files, eliminating the need for the npm package.
### Disabling Index Files
If you don't need the index files, you can use the `-noindex` flag to disable their generation:
```bash
wails3 generate bindings -noindex
```
This can be useful if you prefer to import services and models directly from their respective files.
## Real-World Examples
### Authentication Service
Here's an example of an authentication service with custom directives:
```go
package auth
//wails:inject console.log("Auth service initialized");
type AuthService struct {
// Private fields
users map[string]User
}
type User struct {
Username string
Email string
Role string
}
type LoginRequest struct {
Username string
Password string
}
type LoginResponse struct {
Success bool
User User
Token string
Error string
}
// Login authenticates a user
func (s *AuthService) Login(req LoginRequest) LoginResponse {
// Implementation...
}
// GetCurrentUser returns the current user
func (s *AuthService) GetCurrentUser() User {
// Implementation...
}
// Internal helper method
//wails:internal
func (s *AuthService) validateCredentials(username, password string) bool {
// Implementation...
}
```
### Data Processing Service
Here's an example of a data processing service with generic types:
```go
package data
type ProcessingResult[T any] struct {
Data T
Error string
}
type DataService struct {}
// Process processes data and returns a result
func (s *DataService) Process(data string) ProcessingResult[map[string]int] {
// Implementation...
}
// ProcessBatch processes multiple data items
func (s *DataService) ProcessBatch(data []string) ProcessingResult[[]map[string]int] {
// Implementation...
}
// Internal helper method
//wails:internal
func (s *DataService) parseData(data string) (map[string]int, error) {
// Implementation...
}
```
### Conditional Code Injection
Here's an example of conditional code injection for different output formats:
```go
//wails:inject j*:/**
//wails:inject j*: * @param {string} arg
//wails:inject j*: * @returns {Promise<void>}
//wails:inject j*: */
//wails:inject j*:export async function CustomMethod(arg) {
//wails:inject t*:export async function CustomMethod(arg: string): Promise<void> {
//wails:inject await InternalMethod("Hello " + arg + "!");
//wails:inject }
type Service struct{}
```
This injects different code for JavaScript and TypeScript outputs, providing appropriate type annotations for each language.

View file

@ -0,0 +1,115 @@
---
title: Binding Best Practices
sidebar:
order: 23
---
import { FileTree } from "@astrojs/starlight/components";
This guide provides best practices and patterns for using the Wails binding system effectively in your applications.
## Service Design Patterns
### Service Organization
Organize your services based on functionality rather than technical concerns. For example, instead of having a single large service, split it into smaller, focused services:
```go
// Instead of this:
type AppService struct {}
func (s *AppService) GetUser() User { /* ... */ }
func (s *AppService) UpdateUser(user User) error { /* ... */ }
func (s *AppService) GetProducts() []Product { /* ... */ }
func (s *AppService) AddProduct(product Product) error { /* ... */ }
// Do this:
type UserService struct {}
func (s *UserService) GetUser() User { /* ... */ }
func (s *UserService) UpdateUser(user User) error { /* ... */ }
type ProductService struct {}
func (s *ProductService) GetProducts() []Product { /* ... */ }
func (s *ProductService) AddProduct(product Product) error { /* ... */ }
```
This makes your code more maintainable and easier to understand.
### Use JSON Tags
Use JSON tags to control how your models are serialized:
```go
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Password string `json:"-"` // Exclude from JSON
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
```
### Separate Frontend and Backend Models
Consider using different models for the frontend and backend:
```go
// Backend model
type User struct {
ID int
Name string
Email string
Password string // Sensitive data
CreatedAt time.Time
UpdatedAt time.Time
}
// Frontend model
type UserDTO struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
func (s *UserService) GetUser() UserDTO {
user := getUserFromDatabase()
return UserDTO{
ID: user.ID,
Name: user.Name,
Email: user.Email,
CreatedAt: user.CreatedAt,
}
}
```
This gives you more control over what data is exposed to the frontend.
### Use Context for Cancellation
Use context for cancellation to avoid wasting resources on abandoned requests:
```go
func (s *ProductService) GetProducts(ctx context.Context, req ProductsRequest) (ProductsResponse, error) {
// Check if the request has been cancelled
select {
case <-ctx.Done():
return ProductsResponse{}, ctx.Err()
default:
// Continue processing
}
products, total, err := getProductsFromDatabase(ctx, req.Page, req.PageSize, req.Filter)
if err != nil {
return ProductsResponse{}, err
}
return ProductsResponse{
Products: products,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
```

View file

@ -0,0 +1,155 @@
---
title: Binding System Internals
sidebar:
order: 21
---
import { FileTree } from "@astrojs/starlight/components";
This guide explains how the Wails binding system works internally, providing insights for developers who want to understand the mechanics behind the automatic code generation.
## Architecture Overview
The Wails binding system consists of three main components:
1. **Collection**: Analyzes Go code to extract information about services, models, and other declarations
2. **Configuration**: Manages settings and options for the binding generation process
3. **Rendering**: Generates JavaScript/TypeScript code based on the collected information
<FileTree>
- internal/generator/
- collect/ # Package analysis and information extraction
- config/ # Configuration structures and interfaces
- render/ # Code generation for JS/TS
</FileTree>
## Collection Process
The collection process is responsible for analyzing Go packages and extracting information about services, models, and other declarations. This is handled by the `collect` package.
### Key Components
- **Collector**: Manages package information and caches collected data
- **Package**: Represents a Go package being analyzed and stores collected services, models, and directives
- **Service**: Collects information about service types and their methods
- **Model**: Collects detailed information about model types, including fields, values, and type parameters
- **Directive**: Parses and interprets `//wails:` directives in Go source code
### Collection Flow
1. The collector scans the Go packages specified in the project
2. It identifies service types (structs with methods that will be exposed to the frontend)
3. For each service, it collects information about its methods
4. It identifies model types (structs used as parameters or return values in service methods)
5. For each model, it collects information about its fields and type parameters
6. It processes any `//wails:` directives found in the code
## Rendering Process
The rendering process is responsible for generating JavaScript/TypeScript code based on the collected information. This is handled by the `render` package.
### Key Components
- **Renderer**: Orchestrates the rendering of service, model, and index files
- **Module**: Represents a single generated JavaScript/TypeScript module
- **Templates**: Text templates used for code generation
### Rendering Flow
1. For each service, the renderer generates a JavaScript/TypeScript file with functions that mirror the service methods
2. For each model, the renderer generates a JavaScript/TypeScript class that mirrors the model struct
3. The renderer generates index files that re-export all services and models
4. The renderer applies any custom code injections specified by `//wails:inject` directives
## Type Mapping
One of the most important aspects of the binding system is how Go types are mapped to JavaScript/TypeScript types. Here's a summary of the mapping:
| Go Type | JavaScript Type | TypeScript Type |
|---------|----------------|----------------|
| `bool` | `boolean` | `boolean` |
| `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64` | `number` | `number` |
| `string` | `string` | `string` |
| `[]byte` | `Uint8Array` | `Uint8Array` |
| `[]T` | `Array<T>` | `T[]` |
| `map[K]V` | `Object` | `Record<K, V>` |
| `struct` | `Object` | Custom class |
| `interface{}` | `any` | `any` |
| `*T` | `T \| null` | `T \| null` |
| `func` | Not supported | Not supported |
| `chan` | Not supported | Not supported |
## Directives System
The binding system supports several directives that can be used to customize the generated code. These directives are added as comments in your Go code.
### Available Directives
- `//wails:inject`: Injects custom JavaScript/TypeScript code into the generated bindings
- `//wails:include`: Includes additional files with the generated bindings
- `//wails:internal`: Marks a type or method as internal, preventing it from being exported to the frontend
- `//wails:ignore`: Completely ignores a method during binding generation
- `//wails:id`: Specifies a custom ID for a method, overriding the default hash-based ID
### Directive Processing
1. During the collection phase, the collector identifies and parses directives in the Go code
2. The directives are stored with the corresponding declarations (services, methods, models, etc.)
3. During the rendering phase, the renderer applies the directives to customize the generated code
## Advanced Features
### Conditional Code Generation
The binding system supports conditional code generation using a two-character condition prefix for `include` and `inject` directives:
```
<language><style>:<content>
```
Where:
- `<language>` can be:
- `*` - Both JavaScript and TypeScript
- `j` - JavaScript only
- `t` - TypeScript only
- `<style>` can be:
- `*` - Both classes and interfaces
- `c` - Classes only
- `i` - Interfaces only
For example:
```go
//wails:inject j*:console.log("JavaScript only");
//wails:inject t*:console.log("TypeScript only");
```
### Custom Method IDs
By default, methods are identified by a hash-based ID. However, you can specify a custom ID using the `//wails:id` directive:
```go
//wails:id 42
func (s *Service) CustomIDMethod() {}
```
This can be useful for maintaining compatibility when refactoring code.
## Performance Considerations
The binding generator is designed to be efficient, but there are a few things to keep in mind:
1. The first run will be slower as it builds up a cache of packages to scan
2. Subsequent runs will be faster as they use the cached information
3. The generator processes all packages in the project, which can be time-consuming for large projects
4. You can use the `-clean` flag to clean the output directory before generation
## Debugging
If you encounter issues with the binding generation, you can use the `-v` flag to enable debug output:
```bash
wails3 generate bindings -v
```
This will provide detailed information about the collection and rendering process, which can help identify the source of the issue.

View file

@ -183,7 +183,6 @@ func main() {
},
})
// ....
app.NewWebviewWindow()
err := app.Run()
if err != nil {
log.Fatal(err)
@ -672,4 +671,4 @@ look for warnings from the binding generator to catch these.
If you see a `ReferenceError` complaining about unknown methods,
it could mean that your JS bindings have gotten out of sync with Go code
and must be regenerated.
:::
:::

View file

@ -2,7 +2,9 @@
title: Roadmap
---
## Current Status: Alpha 9
## Current Status: Alpha
Check out the [Changelog](./changelog) for the latest status.
Our goal is to reach Beta status. This roadmap outlines the key features and
improvements we need to implement before transitioning to Beta. Please note that
@ -28,7 +30,3 @@ direction. Your input is valuable in shaping the future of Wails! The roadmap is
a living document and is subject to change. If you have any suggestions, please
open an issue. Each milestone will have a set of goals that we are aiming to
achieve. These are subject to change.
## Alpha 10 Status
Check out the [Changelog](./changelog) for the latest status

View file

@ -7,7 +7,7 @@ import (
"runtime"
"strings"
"github.com/wailsapp/wails/v3/internal/commands/dmg"
// "github.com/wailsapp/wails/v3/internal/commands/dmg" // TODO: Missing package
"github.com/wailsapp/wails/v3/internal/flags"
"github.com/wailsapp/wails/v3/internal/packager"
)
@ -43,30 +43,34 @@ func ToolPackage(options *flags.ToolPackage) error {
// Create output path for DMG
dmgPath := filepath.Join(options.Out, fmt.Sprintf("%s.dmg", options.ExecutableName))
// Create DMG creator
dmgCreator, err := dmg.New(appPath, dmgPath, options.ExecutableName)
if err != nil {
return fmt.Errorf("error creating DMG: %w", err)
}
// DMG creation temporarily disabled - missing dmg package
_ = dmgPath // avoid unused variable warning
return fmt.Errorf("DMG creation is temporarily disabled due to missing dmg package")
// // Create DMG creator
// dmgCreator, err := dmg.New(appPath, dmgPath, options.ExecutableName)
// if err != nil {
// return fmt.Errorf("error creating DMG: %w", err)
// }
// Set background image if provided
if options.BackgroundImage != "" {
if err := dmgCreator.SetBackgroundImage(options.BackgroundImage); err != nil {
return fmt.Errorf("error setting background image: %w", err)
}
}
// // Set background image if provided
// if options.BackgroundImage != "" {
// if err := dmgCreator.SetBackgroundImage(options.BackgroundImage); err != nil {
// return fmt.Errorf("error setting background image: %w", err)
// }
// }
// Set default icon positions
dmgCreator.AddIconPosition(filepath.Base(appPath), 150, 175)
dmgCreator.AddIconPosition("Applications", 450, 175)
// // Set default icon positions
// dmgCreator.AddIconPosition(filepath.Base(appPath), 150, 175)
// dmgCreator.AddIconPosition("Applications", 450, 175)
// Create the DMG
if err := dmgCreator.Create(); err != nil {
return fmt.Errorf("error creating DMG: %w", err)
}
// // Create the DMG
// if err := dmgCreator.Create(); err != nil {
// return fmt.Errorf("error creating DMG: %w", err)
// }
fmt.Printf("DMG created successfully: %s\n", dmgPath)
return nil
// fmt.Printf("DMG created successfully: %s\n", dmgPath)
// return nil
}
// For Linux packages, continue with existing logic

View file

@ -24,9 +24,30 @@ contents:
- src: "./build/linux/{{.BinaryName}}.desktop"
dst: "/usr/share/applications/{{.BinaryName}}.desktop"
# Default dependencies for Debian 12/Ubuntu 22.04+ with WebKit 4.1
depends:
- gtk3
- libwebkit2gtk
- libgtk-3-dev
- libwebkit2gtk-4.1-dev
- build-essential
- pkg-config
# Distribution-specific overrides for different package formats and WebKit versions
overrides:
# RPM packages for RHEL/CentOS/AlmaLinux/Rocky Linux (WebKit 4.0)
rpm:
depends:
- gtk3-devel
- webkit2gtk3-devel
- gcc-c++
- pkg-config
# Arch Linux packages (WebKit 4.1)
archlinux:
depends:
- gtk3
- webkit2gtk-4.1
- base-devel
- pkgconf
# replaces:
# - foobar

View file

@ -30,6 +30,7 @@ func (a *Apt) Packages() Packagemap {
},
"webkit2gtk": []*Package{
{Name: "libwebkit2gtk-4.1-dev", SystemPackage: true, Library: true},
{Name: "libwebkit2gtk-4.0-dev", SystemPackage: true, Library: true},
},
"gcc": []*Package{
{Name: "build-essential", SystemPackage: true},

View file

@ -31,7 +31,7 @@ func (y *Dnf) Packages() Packagemap {
"webkit2gtk": []*Package{
{Name: "webkit2gtk4.1-devel", SystemPackage: true, Library: true},
{Name: "webkit2gtk3-devel", SystemPackage: true, Library: true},
// {Name: "webkitgtk3-devel", SystemPackage: true, Library: true},
{Name: "webkit2gtk4.0-devel", SystemPackage: true, Library: true},
},
"gcc": []*Package{
{Name: "gcc-c++", SystemPackage: true},

View file

@ -31,6 +31,7 @@ func (e *Emerge) Packages() Packagemap {
},
"webkit2gtk": []*Package{
{Name: "net-libs/webkit-gtk:6", SystemPackage: true, Library: true},
{Name: "net-libs/webkit-gtk:4", SystemPackage: true, Library: true},
},
"gcc": []*Package{
{Name: "sys-devel/gcc", SystemPackage: true},

View file

@ -31,6 +31,7 @@ func (p *Pacman) Packages() Packagemap {
},
"webkit2gtk": []*Package{
{Name: "webkit2gtk-4.1", SystemPackage: true, Library: true},
{Name: "webkit2gtk", SystemPackage: true, Library: true},
},
"gcc": []*Package{
{Name: "gcc", SystemPackage: true},

View file

@ -31,6 +31,7 @@ func (z *Zypper) Packages() Packagemap {
{Name: "gtk3-devel", SystemPackage: true, Library: true},
},
"webkit2gtk": []*Package{
{Name: "webkit2gtk4_1-devel", SystemPackage: true, Library: true},
{Name: "webkit2gtk3-soup2-devel", SystemPackage: true, Library: true},
{Name: "webkit2gtk3-devel", SystemPackage: true, Library: true},
},

View file

@ -1 +1 @@
v3.0.0-alpha.9
v3.0.0-alpha.10

View file

@ -271,6 +271,10 @@ func (w *windowsWebviewWindow) run() {
options := w.parent.options
// Initialize showRequested based on whether window should be hidden
// Non-hidden windows should be shown by default
w.showRequested = !options.Hidden
w.chromium = edge.NewChromium()
if globalApplication.options.ErrorHandler != nil {
w.chromium.SetErrorCallback(globalApplication.options.ErrorHandler)