Window Options
Complete reference for all window options.
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.
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.
The simplest way to create a window:
window := app.Window.New()What you get:
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.
Give windows names for easy retrieval:
window := app.Window.NewWithOptions(application.WebviewWindowOptions{ Name: "main-window", Title: "Main Application",})
// Later, find it by nameif mainWindow, ok := app.Window.GetByName("main-window"); ok { mainWindow.Show()}Use cases:
// Show windowwindow.Show()
// Hide windowwindow.Hide()
// Check if visibleif window.IsVisible() { fmt.Println("Window is visible")}Use cases:
// Set sizewindow.SetSize(1024, 768)
// Set positionwindow.SetPosition(100, 100)
// Centre on screenwindow.Center()
// Get current sizewidth, height := window.Size()
// Get current positionx, y := window.Position()Coordinate system:
// Minimisewindow.Minimise()
// Maximisewindow.Maximise()
// Fullscreenwindow.Fullscreen()
// Restore to normalwindow.Restore()
// Check stateif 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 ←→ MinimisedNormal ←→ MaximisedNormal ←→ Fullscreen// Set titlewindow.SetTitle("My Application - Document.txt")
// Set background colour — RGBA value (helper for RGB)window.SetBackgroundColour(application.NewRGBA(0, 0, 0, 255))
// Set always on topwindow.SetAlwaysOnTop(true)
// Set resizablewindow.SetResizable(false)// 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).
if window, ok := app.Window.GetByName("settings"); ok { window.Show()}Every window has a unique ID:
id := window.ID()fmt.Printf("Window ID: %d\n", id)
// Find by IDif found, ok := app.Window.GetByID(id); ok { found.Focus()}Get the currently focused window:
current := app.Window.Current()if current != nil { current.SetTitle("Active Window")}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())}app.Window.OnCreate(func(window application.Window) { fmt.Printf("Window created: %s\n", window.Name())
// Configure new windows window.SetMinSize(400, 300)})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).
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})// Main windowmainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Name: "main", Title: "Main Application", Width: 1200, Height: 800,})
// Settings windowsettingsWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Name: "settings", Title: "Settings", Width: 600, Height: 400, Hidden: true, // Start hidden})
// Show settings when neededsettingsWindow.Show()Windows can communicate via events:
// In main windowapp.Event.Emit("data-updated", map[string]interface{}{ "value": 42,})
// In settings windowapp.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.
WebviewWindowOptions has no Parent field. Create the child as a normal window and attach it to a parent as a sheet modal:
// Create child windowchildWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Title: "Child Window",})
// Attach to the parent — presents as a sheet on macOS.mainWindow.AttachModal(childWindow)Behaviour:
Platform support:
Windows-specific features:
// Flash taskbar buttonwindow.Flash(true) // Start flashingwindow.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 for the window.
Taskbar flashing: Useful for notifications when window is minimised.
macOS-specific features:
// Transparent title barwindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBar{ AppearsTransparent: true, }, Backdrop: application.MacBackdropTranslucent, },})Backdrop types:
MacBackdropNormal - Standard windowMacBackdropTranslucent - Translucent backgroundMacBackdropTransparent - Fully transparentCollection behavior: Control how windows behave across Spaces:
MacWindowCollectionBehaviorCanJoinAllSpaces - Visible on all SpacesMacWindowCollectionBehaviorFullScreenAuxiliary - Can overlay fullscreen appsNative fullscreen: macOS fullscreen creates a new Space (virtual desktop).
Linux-specific features:
// Set window icon (per-window struct is LinuxWindow, not the app-level LinuxOptions)window := app.Window.NewWithOptions(application.WebviewWindowOptions{ Linux: application.LinuxWindow{ Icon: iconBytes, },})Desktop environment notes:
Tiling window managers (Hyprland, Sway, i3, etc.):
Minimise() and Maximise() may not work as expected - the WM controls window geometrySetSize() and SetPosition() requests are advisory and may be ignoredFullscreen() typically works as expected// Create splash screensplash := app.Window.NewWithOptions(application.WebviewWindowOptions{ Title: "Loading...", Width: 400, Height: 300, Frameless: true, AlwaysOnTop: true,})
// Show splashsplash.Show()
// Initialise applicationtime.Sleep(2 * time.Second)
// Hide splash, show main windowsplash.Close()mainWindow.Show()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()}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() } }})Possible causes:
Solution:
window.Show()window.Center()window.Focus()Cause: DPI scaling on Windows/Linux
Solution:
// Wails handles DPI automatically// Just use logical pixelswindow.SetSize(800, 600)Cause: Application exits when last window closes
Solution:
app := application.New(application.Options{ Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: false, },})Window Options
Complete reference for all window options.
Multiple Windows
Patterns for multi-window applications.
Frameless Windows
Create custom window chrome.
Window Events
Handle window lifecycle events.
Questions? Ask in Discord or check the window examples.