--- title: Window Basics description: Creating and managing application windows in Wails sidebar: order: 1 --- import { Tabs, TabItem, Card, CardGrid } from "@astrojs/starlight/components"; ## 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 ```go 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: ```go 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: ```go 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](/features/windows/options) for complete list.** ### Named Windows Give windows names for easy retrieval: ```go window := app.Window.NewWithOptions(application.WebviewWindowOptions{ Name: "main-window", Title: "Main Application", }) // Later, find it by name mainWindow := app.GetWindowByName("main-window") if mainWindow != nil { mainWindow.Show() } ``` **Use cases:** - Multiple windows (main, settings, about) - Finding windows from different parts of your code - Window communication ## Controlling Windows ### Show and Hide ```go // 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 ```go // 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 ```go // 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 ```go // Set title window.SetTitle("My Application - Document.txt") // Set background colour window.SetBackgroundColour(0, 0, 0, 255) // RGBA // Set always on top window.SetAlwaysOnTop(true) // Set resizable window.SetResizable(false) ``` ### Closing Windows ```go // Close window window.Close() // Destroy window (force close) window.Destroy() ``` **Difference:** - `Close()` - Triggers close event, can be cancelled - `Destroy()` - Immediate destruction, cannot be cancelled ## Finding Windows ### By Name ```go window := app.GetWindowByName("settings") if window != nil { window.Show() } ``` ### By ID Every window has a unique ID: ```go id := window.ID() fmt.Printf("Window ID: %d\n", id) // Find by ID foundWindow := app.GetWindowByID(id) ``` ### Current Window Get the currently focused window: ```go current := app.Window.Current() if current != nil { current.SetTitle("Active Window") } ``` ### All Windows Get all windows: ```go 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 ```go app.OnWindowCreation(func(window *application.WebviewWindow) { fmt.Printf("Window created: %s\n", window.Name()) // Configure new windows window.SetMinSize(400, 300) }) ``` ### Closing ```go 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()`. ### Destruction ```go window.OnDestroy(func() { fmt.Println("Window destroyed") // Cleanup resources }) ``` ## Multiple Windows ### Creating Multiple Windows ```go // 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: ```go // In main window app.Event.Emit("data-updated", map[string]interface{}{ "value": 42, }) // In settings window app.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](/features/events/system) for more.** ### Parent-Child Windows ```go // Create child window childWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ Title: "Child Window", Parent: mainWindow, // Set parent }) ``` **Behaviour:** - Child closes when parent closes - Child stays above parent (on some platforms) - Child minimises with parent (on some platforms) **Platform support:** - **macOS:** Full support - **Windows:** Partial support - **Linux:** Varies by desktop environment ## Platform-Specific Features **Windows-specific features:** ```go // Flash taskbar button window.Flash(true) // Start flashing window.Flash(false) // Stop flashing // Trigger Windows 11 Snap Assist (Win+Z) window.SnapAssist() // Set window icon window.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:** ```go // Transparent title bar window := app.Window.NewWithOptions(application.WebviewWindowOptions{ Mac: application.MacWindow{ TitleBar: application.MacTitleBar{ AppearsTransparent: true, }, Backdrop: application.MacBackdropTranslucent, }, }) ``` **Backdrop types:** - `MacBackdropNormal` - Standard window - `MacBackdropTranslucent` - Translucent background - `MacBackdropTransparent` - Fully transparent **Collection behavior:** Control how windows behave across Spaces: - `MacWindowCollectionBehaviorCanJoinAllSpaces` - Visible on all Spaces - `MacWindowCollectionBehaviorFullScreenAuxiliary` - Can overlay fullscreen apps **Native fullscreen:** macOS fullscreen creates a new Space (virtual desktop). **Linux-specific features:** ```go // Set window icon window := app.Window.NewWithOptions(application.WebviewWindowOptions{ Linux: application.LinuxOptions{ Icon: iconBytes, }, }) ``` **Desktop environment notes:** - GNOME: Full support - KDE Plasma: Full support - XFCE: Partial support - Others: Varies **Tiling window managers (Hyprland, Sway, i3, etc.):** - `Minimise()` and `Maximise()` may not work as expected - the WM controls window geometry - `SetSize()` and `SetPosition()` requests are advisory and may be ignored - `Fullscreen()` typically works as expected - Some WMs don't support always-on-top ## Common Patterns ### Splash Screen ```go // 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 ```go 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() } ``` ### Confirm Before Close ```go window.OnClose(func() bool { if hasUnsavedChanges() { // Show dialog result := showConfirmdialog("Unsaved changes. Close anyway?") return result == "yes" } return true }) ``` ## 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:** ```go window.Show() window.Center() window.SetFocus() ``` ### Window Wrong Size **Cause:** DPI scaling on Windows/Linux **Solution:** ```go // Wails handles DPI automatically // Just use logical pixels window.SetSize(800, 600) ``` ### Window Closes Immediately **Cause:** Application exits when last window closes **Solution:** ```go app := application.New(application.Options{ Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: false, }, }) ``` ## Next Steps Complete reference for all window options. [Learn More →](/features/windows/options) Patterns for multi-window applications. [Learn More →](/features/windows/multiple) Create custom window chrome. [Learn More →](/features/windows/frameless) Handle window lifecycle events. [Learn More →](/features/windows/events) --- **Questions?** Ask in [Discord](https://discord.gg/JDdSxwjhGf) or check the [window examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples).