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 namemainWindow := app.GetWindowByName("main-window")if mainWindow != nil { 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 colourwindow.SetBackgroundColour(0, 0, 0, 255) // RGBA
// Set always on topwindow.SetAlwaysOnTop(true)
// Set resizablewindow.SetResizable(false)// Close windowwindow.Close()
// Destroy window (force close)window.Destroy()Difference:
Close() - Triggers close event, can be cancelledDestroy() - Immediate destruction, cannot be cancelledwindow := app.GetWindowByName("settings")if window != nil { window.Show()}Every window has a unique ID:
id := window.ID()fmt.Printf("Window ID: %d\n", id)
// Find by IDfoundWindow := app.GetWindowByID(id)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.OnWindowCreation(func(window *application.WebviewWindow) { fmt.Printf("Window created: %s\n", window.Name())
// Configure new windows window.SetMinSize(400, 300)})window.OnClose(func() bool { // Return false to cancel close // Return true to allow close
if hasUnsavedChanges() { result := showConfirmdialog("Unsaved changes. Close anyway?") return result == "yes" } return true})Important: OnClose only works for user-initiated closes (clicking X button). It doesn’t prevent window.Destroy().
window.OnDestroy(func() { fmt.Println("Window destroyed") // 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.WailsEvent) { data := event.Data.(map[string]interface{}) value := data["value"].(int) fmt.Printf("Received: %d\n", value)})See Events for more.
// Create child windowchildWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Title: "Child Window", Parent: mainWindow, // Set parent})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()
// Set window iconwindow.SetIcon(iconBytes)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 iconwindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Linux: application.LinuxOptions{ 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.SetFocus()}window.OnClose(func() bool { if hasUnsavedChanges() { // Show dialog result := showConfirmdialog("Unsaved changes. Close anyway?") return result == "yes" } return true})Possible causes:
Solution:
window.Show()window.Center()window.SetFocus()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.