Lewati ke konten

Dasar-dasar Window

Wails menyediakan API manajemen window terpadu yang berfungsi di semua platform. Buat window, kendalikan perilakunya, dan kelola beberapa window dengan kontrol penuh atas pembuatan, tampilan, perilaku, dan siklus hidup.

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()
}

Itu saja! Anda sudah memiliki window lintas platform.

Cara paling sederhana untuk membuat window:

window := app.Window.New()

Yang Anda dapatkan:

  • Ukuran default (800x600)
  • Judul default (nama aplikasi)
  • WebView siap untuk frontend Anda
  • Tampilan native platform

Buat window dengan konfigurasi kustom:

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,
})

Opsi umum:

OpsiTipeDeskripsi
TitlestringJudul window
WidthintLebar window dalam piksel
HeightintTinggi window dalam piksel
XintPosisi X (dari kiri)
YintPosisi Y (dari atas)
AlwaysOnTopboolJaga window di atas window lain
FramelessboolHapus title bar dan border
HiddenboolMulai dalam keadaan tersembunyi
MinWidthintLebar minimum
MinHeightintTinggi minimum
MaxWidthintLebar maksimum
MaxHeightintTinggi maksimum

Lihat Opsi Window untuk daftar lengkap.

Berikan nama pada window agar mudah diambil kembali:

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()
}

Kasus penggunaan:

  • Beberapa window (main, settings, about)
  • Mencari window dari bagian kode yang berbeda
  • Komunikasi antar window
// Show window
window.Show()
// Hide window
window.Hide()
// Check if visible
if window.IsVisible() {
fmt.Println("Window is visible")
}

Kasus penggunaan:

  • Splash screen (tampilkan, lalu sembunyikan)
  • Window pengaturan (sembunyikan saat tidak diperlukan)
  • Window popup (tampilkan sesuai permintaan)
// 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()

Sistem koordinat:

  • (0, 0) adalah sudut kiri atas layar utama
  • X positif ke kanan
  • Y positif ke bawah
// 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")
}

Transisi status:

Normal ←→ Minimised
Normal ←→ Maximised
Normal ←→ Fullscreen
// 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)
// Close window — dispatches WindowClosing; a RegisterHook can call e.Cancel().
window.Close()

Tidak ada metode window.Destroy() di v3 — gunakan Close() dan dengarkan dengan OnWindowEvent (tidak dapat dibatalkan) atau hook dengan RegisterHook (dapat memanggil e.Cancel() untuk menjaga window tetap terbuka).

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

Setiap window memiliki ID unik:

id := window.ID()
fmt.Printf("Window ID: %d\n", id)
// Find by ID
if found, ok := app.Window.GetByID(id); ok {
found.Focus()
}

Dapatkan window yang sedang fokus:

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

Dapatkan semua window:

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)
})

Untuk mencegah window ditutup, gunakan RegisterHook dengan event WindowClosing:

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()
}
}
})

Penting: RegisterHook mencegat event close sebelum terjadi. Panggil event.Cancel() untuk mencegah window ditutup. Ini berfungsi untuk penutupan yang dipicu pengguna (mengklik tombol X).

Untuk melakukan cleanup saat window ditutup, gunakan OnWindowEvent dengan event WindowClosing:

window.OnWindowEvent(events.Common.WindowClosing, func(event *application.WindowEvent) {
fmt.Println("Window is closing")
// Cleanup resources
})
// 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 dapat berkomunikasi via event:

// 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)
})

Lihat Event untuk selengkapnya.

WebviewWindowOptions tidak memiliki field Parent. Buat child sebagai window normal dan lampirkan ke parent sebagai 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)

Perilaku:

  • Child tetap di atas parent.
  • Child bersifat modal — memblokir interaksi dengan parent.

Dukungan platform:

  • macOS: Dukungan penuh (ditampilkan sebagai sheet).
  • Windows: Tidak didukung.
  • Linux: Tidak didukung.

Fitur khusus Windows:

// Flash taskbar button
window.Flash(true) // Start flashing
window.Flash(false) // Stop flashing
// Trigger Windows 11 Snap Assist (Win+Z)
window.SnapAssist()

Tidak ada SetIcon per-window — ikon aplikasi diatur pada app via app.SetIcon([]byte) (atau untuk ikon window khusus Linux, field application.LinuxWindow.Icon saat pembuatan window).

Snap Assist: Menampilkan opsi layout snap Windows 11 untuk window.

Kedip taskbar: Berguna untuk notifikasi saat window diminimalkan.

// 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()
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()
}
}
})
  • Beri nama window penting - Lebih mudah ditemukan nanti
  • Atur ukuran minimum - Cegah layout yang tidak dapat digunakan
  • Pusatkan window - UX lebih baik daripada posisi acak
  • Tangani event close - Cegah kehilangan data
  • Uji di semua platform - Perilaku bervariasi
  • Gunakan ukuran yang sesuai - Pertimbangkan berbagai ukuran layar
  • Jangan buat terlalu banyak window - Membingungkan pengguna
  • Jangan lupa menutup window - Memory leak
  • Jangan hardcode posisi - Ukuran layar berbeda-beda
  • Jangan abaikan perbedaan platform - Uji secara menyeluruh
  • Jangan blokir UI thread - Gunakan goroutine untuk operasi panjang

Kemungkinan penyebab:

  1. Window dibuat dalam keadaan tersembunyi
  2. Window di luar layar
  3. Window berada di belakang window lain

Solusi:

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

Penyebab: Skala DPI di Windows/Linux

Solusi:

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

Penyebab: Aplikasi keluar saat window terakhir ditutup

Solusi:

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

Pertanyaan? Tanyakan di Discord atau lihat contoh window.