Window Basics

Window Management

Wails provides a unified window management API that works across all platforms. Create windows, control their behaviour, and manage multiple windows with full control over creation, appearance, behaviour, and lifecycle.

Quick Start

package main

import "github.com/wailsapp/wails/v3/pkg/application"

func main() {
    app := application.New(application.Options{
        Name: "My App",
    })

    // Create a window
    window := app.Window.New()
    
    // Configure it
    window.SetTitle("Hello Wails")
    window.SetSize(800, 600)
    window.Center()
    
    // Show it
    window.Show()

    app.Run()
}

That’s it! You have a cross-platform window.

Creating Windows

Basic Window

The simplest way to create a window:

window := app.Window.New()

What you get:

  • Default size (800x600)
  • Default title (application name)
  • WebView ready for your frontend
  • Platform-native appearance

Window with Options

Create a window with custom configuration:

window := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Title:  "My Application",
    Width:  1200,
    Height: 800,
    X:      100,   // Position from left
    Y:      100,   // Position from top
    AlwaysOnTop: false,
    Frameless: false,
    Hidden: false,
    MinWidth: 400,
    MinHeight: 300,
    MaxWidth: 1920,
    MaxHeight: 1080,
})

Common options:

Option Type Description
Title string Window title
Width int Window width in pixels
Height int Window height in pixels
X int X position (from left)
Y int Y position (from top)
AlwaysOnTop bool Keep window above others
Frameless bool Remove title bar and borders
Hidden bool Start hidden
MinWidth int Minimum width
MinHeight int Minimum height
MaxWidth int Maximum width
MaxHeight int Maximum height

See Window Options for complete list.

Named Windows

Give windows names for easy retrieval:

window := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Name:  "main-window",
    Title: "Main Application",
})

// Later, find it by name
if mainWindow, ok := app.Window.GetByName("main-window"); ok {
    mainWindow.Show()
}

Use cases:

  • Multiple windows (main, settings, about)
  • Finding windows from different parts of your code
  • Window communication

Controlling Windows

Show and Hide

// Show window
window.Show()

// Hide window
window.Hide()

// Check if visible
if window.IsVisible() {
    fmt.Println("Window is visible")
}

Use cases:

  • Splash screens (show, then hide)
  • Settings windows (hide when not needed)
  • Popup windows (show on demand)

Position and Size

// Set size
window.SetSize(1024, 768)

// Set position
window.SetPosition(100, 100)

// Centre on screen
window.Center()

// Get current size
width, height := window.Size()

// Get current position
x, y := window.Position()

Coordinate system:

  • (0, 0) is top-left of primary screen
  • Positive X goes right
  • Positive Y goes down

Window State

// Minimise
window.Minimise()

// Maximise
window.Maximise()

// Fullscreen
window.Fullscreen()

// Restore to normal
window.Restore()

// Check state
if window.IsMinimised() {
    fmt.Println("Window is minimised")
}

if window.IsMaximised() {
    fmt.Println("Window is maximised")
}

if window.IsFullscreen() {
    fmt.Println("Window is fullscreen")
}

State transitions:

Normal ←→ Minimised
Normal ←→ Maximised
Normal ←→ Fullscreen

Title and Appearance

// Set title
window.SetTitle("My Application - Document.txt")

// Set background colour — RGBA value (helper for RGB)
window.SetBackgroundColour(application.NewRGBA(0, 0, 0, 255))

// Set always on top
window.SetAlwaysOnTop(true)

// Set resizable
window.SetResizable(false)

Closing Windows

// Close window — dispatches WindowClosing; a RegisterHook can call e.Cancel().
window.Close()

There is no window.Destroy() method in v3 — use Close() and either listen with OnWindowEvent (cannot cancel) or hook with RegisterHook (can call e.Cancel() to keep the window open).

Finding Windows

By Name

if window, ok := app.Window.GetByName("settings"); ok {
    window.Show()
}

By ID

Every window has a unique ID:

id := window.ID()
fmt.Printf("Window ID: %d\n", id)

// Find by ID
if found, ok := app.Window.GetByID(id); ok {
    found.Focus()
}

Current Window

Get the currently focused window:

current := app.Window.Current()
if current != nil {
    current.SetTitle("Active Window")
}

All Windows

Get all windows:

windows := app.Window.GetAll()
fmt.Printf("Total windows: %d\n", len(windows))

for _, w := range windows {
    fmt.Printf("Window: %s (ID: %d)\n", w.Name(), w.ID())
}

Window Lifecycle

Creation

app.Window.OnCreate(func(window application.Window) {
    fmt.Printf("Window created: %s\n", window.Name())

    // Configure new windows
    window.SetMinSize(400, 300)
})

Closing

To prevent a window from closing, use RegisterHook with the WindowClosing event:

window.RegisterHook(events.Common.WindowClosing, func(event *application.WindowEvent) {
    if hasUnsavedChanges() {
        // Ask user for confirmation
        result := showConfirmDialog("Unsaved changes. Close anyway?")
        if result != "yes" {
            // Cancel the close event
            event.Cancel()
        }
    }
})

Important: RegisterHook intercepts the close event before it happens. Call event.Cancel() to prevent the window from closing. This works for user-initiated closes (clicking X button).

Destruction

To perform cleanup when a window closes, use OnWindowEvent with the WindowClosing event:

window.OnWindowEvent(events.Common.WindowClosing, func(event *application.WindowEvent) {
    fmt.Println("Window is closing")
    // Cleanup resources
})

Multiple Windows

Creating Multiple Windows

// Main window
mainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Name:   "main",
    Title:  "Main Application",
    Width:  1200,
    Height: 800,
})

// Settings window
settingsWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Name:   "settings",
    Title:  "Settings",
    Width:  600,
    Height: 400,
    Hidden: true,  // Start hidden
})

// Show settings when needed
settingsWindow.Show()

Window Communication

Windows can communicate via events:

// In main window
app.Event.Emit("data-updated", map[string]interface{}{
    "value": 42,
})

// In settings window
app.Event.On("data-updated", func(event *application.CustomEvent) {
    data := event.Data.(map[string]interface{})
    value := data["value"].(int)
    fmt.Printf("Received: %d\n", value)
})

See Events for more.

Parent-Child Windows

WebviewWindowOptions has no Parent field. Create the child as a normal window and attach it to a parent as a sheet modal:

// Create child window
childWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Title: "Child Window",
})

// Attach to the parent — presents as a sheet on macOS.
mainWindow.AttachModal(childWindow)

Behaviour:

  • Child stays above parent.
  • Child is modal — blocks interaction with the parent.

Platform support:

  • macOS: Full support (presents as a sheet).
  • Windows: Not supported.
  • Linux: Not supported.

Platform-Specific Features

Windows-specific features:

// Flash taskbar button
window.Flash(true)  // Start flashing
window.Flash(false) // Stop flashing

// Trigger Windows 11 Snap Assist (Win+Z)
window.SnapAssist()

There is no per-window SetIcon — the application icon is set on the app via app.SetIcon([]byte) (or for a Linux-specific window icon, the application.LinuxWindow.Icon field at window creation).

Snap Assist: Shows Windows 11 snap layout options through the system shortcut path. For a custom HTML maximize button with native hover Snap Layouts, use Native Non-Client Regions on Windows instead.

Taskbar flashing: Useful for notifications when window is minimised.

Common Patterns

Splash Screen

// Create splash screen
splash := app.Window.NewWithOptions(application.WebviewWindowOptions{
    Title:     "Loading...",
    Width:     400,
    Height:    300,
    Frameless: true,
    AlwaysOnTop: true,
})

// Show splash
splash.Show()

// Initialise application
time.Sleep(2 * time.Second)

// Hide splash, show main window
splash.Close()
mainWindow.Show()

Settings Window

var settingsWindow *application.WebviewWindow

func showSettings() {
    if settingsWindow == nil {
        settingsWindow = app.Window.NewWithOptions(application.WebviewWindowOptions{
            Name:   "settings",
            Title:  "Settings",
            Width:  600,
            Height: 400,
        })
    }
    
    settingsWindow.Show()
    settingsWindow.Focus()
}

Confirm Before Close

window.RegisterHook(events.Common.WindowClosing, func(event *application.WindowEvent) {
    if hasUnsavedChanges() {
        // Show dialog
        result := showConfirmDialog("Unsaved changes. Close anyway?")
        if result != "yes" {
            // Cancel the close event
            event.Cancel()
        }
    }
})

Best Practices

✅ Do

  • Name important windows - Easier to find later
  • Set minimum size - Prevent unusable layouts
  • Centre windows - Better UX than random position
  • Handle close events - Prevent data loss
  • Test on all platforms - Behaviour varies
  • Use appropriate sizes - Consider different screen sizes

❌ Don’t

  • Don’t create too many windows - Confusing for users
  • Don’t forget to close windows - Memory leaks
  • Don’t hardcode positions - Different screen sizes
  • Don’t ignore platform differences - Test thoroughly
  • Don’t block the UI thread - Use goroutines for long operations

Troubleshooting

Window Not Showing

Possible causes:

  1. Window created as hidden
  2. Window off-screen
  3. Window behind other windows

Solution:

window.Show()
window.Center()
window.Focus()

Window Wrong Size

Cause: DPI scaling on Windows/Linux

Solution:

// Wails handles DPI automatically
// Just use logical pixels
window.SetSize(800, 600)

Window Closes Immediately

Cause: Application exits when last window closes

Solution:

app := application.New(application.Options{
    Mac: application.MacOptions{
        ApplicationShouldTerminateAfterLastWindowClosed: false,
    },
})

Next Steps

Window Options

Complete reference for all window options.

Learn More →

Multiple Windows

Patterns for multi-window applications.

Learn More →

Frameless Windows

Create custom window chrome.

Learn More →

Window Events

Handle window lifecycle events.

Learn More →


Questions? Ask in Discord or check the window examples.

Edit page

Last updated: