diff --git a/stubs/wails/pkg/application/application.go b/stubs/wails/pkg/application/application.go
index 211611c..9f3937e 100644
--- a/stubs/wails/pkg/application/application.go
+++ b/stubs/wails/pkg/application/application.go
@@ -2,6 +2,7 @@ package application
import (
"sync"
+ "unsafe"
"github.com/wailsapp/wails/v3/pkg/events"
)
@@ -238,10 +239,11 @@ func (w *WebviewWindow) IsFocused() bool {
return w.focused
}
-func (w *WebviewWindow) SetTitle(title string) {
+func (w *WebviewWindow) SetTitle(title string) Window {
w.mu.Lock()
w.title = title
w.mu.Unlock()
+ return w
}
func (w *WebviewWindow) SetPosition(x, y int) {
@@ -251,25 +253,28 @@ func (w *WebviewWindow) SetPosition(x, y int) {
w.mu.Unlock()
}
-func (w *WebviewWindow) SetSize(width, height int) {
+func (w *WebviewWindow) SetSize(width, height int) Window {
w.mu.Lock()
w.width = width
w.height = height
w.mu.Unlock()
+ return w
}
-func (w *WebviewWindow) SetBackgroundColour(colour RGBA) {}
+func (w *WebviewWindow) SetBackgroundColour(colour RGBA) Window { return w }
-func (w *WebviewWindow) SetAlwaysOnTop(alwaysOnTop bool) {
+func (w *WebviewWindow) SetAlwaysOnTop(alwaysOnTop bool) Window {
w.mu.Lock()
w.alwaysOnTop = alwaysOnTop
w.mu.Unlock()
+ return w
}
-func (w *WebviewWindow) Maximise() {
+func (w *WebviewWindow) Maximise() Window {
w.mu.Lock()
w.maximised = true
w.mu.Unlock()
+ return w
}
func (w *WebviewWindow) Restore() {
@@ -279,7 +284,7 @@ func (w *WebviewWindow) Restore() {
w.mu.Unlock()
}
-func (w *WebviewWindow) Minimise() {}
+func (w *WebviewWindow) Minimise() Window { return w }
func (w *WebviewWindow) Focus() {
w.mu.Lock()
@@ -293,22 +298,25 @@ func (w *WebviewWindow) Close() {
w.mu.Unlock()
}
-func (w *WebviewWindow) Show() {
+func (w *WebviewWindow) Show() Window {
w.mu.Lock()
w.visible = true
w.mu.Unlock()
+ return w
}
-func (w *WebviewWindow) Hide() {
+func (w *WebviewWindow) Hide() Window {
w.mu.Lock()
w.visible = false
w.mu.Unlock()
+ return w
}
-func (w *WebviewWindow) Fullscreen() {
+func (w *WebviewWindow) Fullscreen() Window {
w.mu.Lock()
w.fullscreen = true
w.mu.Unlock()
+ return w
}
func (w *WebviewWindow) UnFullscreen() {
@@ -324,6 +332,376 @@ func (w *WebviewWindow) OnWindowEvent(eventType events.WindowEventType, callback
return func() {}
}
+// ID returns a stable numeric identifier for this window.
+//
+// id := w.ID()
+func (w *WebviewWindow) ID() uint { return 0 }
+
+// ClientID returns the client identifier (empty for native windows).
+//
+// cid := w.ClientID()
+func (w *WebviewWindow) ClientID() string { return "" }
+
+// Width returns the current window width in logical pixels.
+//
+// px := w.Width()
+func (w *WebviewWindow) Width() int {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return w.width
+}
+
+// Height returns the current window height in logical pixels.
+//
+// px := w.Height()
+func (w *WebviewWindow) Height() int {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return w.height
+}
+
+// IsVisible reports whether the window is currently shown.
+//
+// if w.IsVisible() { ... }
+func (w *WebviewWindow) IsVisible() bool {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return w.visible
+}
+
+// IsFullscreen reports whether the window is in fullscreen mode.
+//
+// if w.IsFullscreen() { ... }
+func (w *WebviewWindow) IsFullscreen() bool {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return w.fullscreen
+}
+
+// IsMinimised reports whether the window is minimised.
+//
+// if w.IsMinimised() { ... }
+func (w *WebviewWindow) IsMinimised() bool { return false }
+
+// IsIgnoreMouseEvents reports whether mouse events are being suppressed.
+//
+// if w.IsIgnoreMouseEvents() { ... }
+func (w *WebviewWindow) IsIgnoreMouseEvents() bool { return false }
+
+// Resizable reports whether the window can be resized by the user.
+//
+// if w.Resizable() { ... }
+func (w *WebviewWindow) Resizable() bool { return true }
+
+// Bounds returns the current position and size as a Rect.
+//
+// r := w.Bounds()
+func (w *WebviewWindow) Bounds() Rect {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return Rect{X: w.x, Y: w.y, Width: w.width, Height: w.height}
+}
+
+// SetBounds sets position and size simultaneously.
+//
+// w.SetBounds(Rect{X: 100, Y: 100, Width: 1280, Height: 800})
+func (w *WebviewWindow) SetBounds(bounds Rect) {
+ w.mu.Lock()
+ w.x, w.y, w.width, w.height = bounds.X, bounds.Y, bounds.Width, bounds.Height
+ w.mu.Unlock()
+}
+
+// RelativePosition returns the position relative to the screen origin.
+//
+// rx, ry := w.RelativePosition()
+func (w *WebviewWindow) RelativePosition() (int, int) {
+ w.mu.RLock()
+ defer w.mu.RUnlock()
+ return w.x, w.y
+}
+
+// SetRelativePosition sets the position relative to the screen.
+//
+// w.SetRelativePosition(0, 0)
+func (w *WebviewWindow) SetRelativePosition(x, y int) Window {
+ w.mu.Lock()
+ w.x = x
+ w.y = y
+ w.mu.Unlock()
+ return w
+}
+
+// SetMinSize sets the minimum window dimensions.
+//
+// w.SetMinSize(640, 480)
+func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) Window { return w }
+
+// SetMaxSize sets the maximum window dimensions.
+//
+// w.SetMaxSize(3840, 2160)
+func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) Window { return w }
+
+// Center positions the window at the centre of the screen.
+//
+// w.Center()
+func (w *WebviewWindow) Center() {}
+
+// SetURL navigates the webview to the given URL.
+//
+// w.SetURL("https://example.com")
+func (w *WebviewWindow) SetURL(url string) Window { return w }
+
+// SetHTML replaces the webview content with the given HTML string.
+//
+// w.SetHTML("
Hello
")
+func (w *WebviewWindow) SetHTML(html string) Window { return w }
+
+// SetFrameless toggles the window frame.
+//
+// w.SetFrameless(true)
+func (w *WebviewWindow) SetFrameless(frameless bool) Window { return w }
+
+// SetResizable controls whether the user can resize the window.
+//
+// w.SetResizable(false)
+func (w *WebviewWindow) SetResizable(b bool) Window { return w }
+
+// SetIgnoreMouseEvents suppresses or restores mouse event delivery.
+//
+// w.SetIgnoreMouseEvents(true)
+func (w *WebviewWindow) SetIgnoreMouseEvents(ignore bool) Window { return w }
+
+// SetMinimiseButtonState controls the minimise button appearance.
+//
+// w.SetMinimiseButtonState(ButtonHidden)
+func (w *WebviewWindow) SetMinimiseButtonState(state ButtonState) Window { return w }
+
+// SetMaximiseButtonState controls the maximise button appearance.
+//
+// w.SetMaximiseButtonState(ButtonDisabled)
+func (w *WebviewWindow) SetMaximiseButtonState(state ButtonState) Window { return w }
+
+// SetCloseButtonState controls the close button appearance.
+//
+// w.SetCloseButtonState(ButtonEnabled)
+func (w *WebviewWindow) SetCloseButtonState(state ButtonState) Window { return w }
+
+// SetEnabled enables or disables user interaction with the window.
+//
+// w.SetEnabled(false)
+func (w *WebviewWindow) SetEnabled(enabled bool) {}
+
+// SetContentProtection prevents the window contents from being captured.
+//
+// w.SetContentProtection(true)
+func (w *WebviewWindow) SetContentProtection(protection bool) Window { return w }
+
+// SetMenu attaches a menu to the window.
+//
+// w.SetMenu(myMenu)
+func (w *WebviewWindow) SetMenu(menu *Menu) {}
+
+// ShowMenuBar makes the menu bar visible.
+//
+// w.ShowMenuBar()
+func (w *WebviewWindow) ShowMenuBar() {}
+
+// HideMenuBar hides the menu bar.
+//
+// w.HideMenuBar()
+func (w *WebviewWindow) HideMenuBar() {}
+
+// ToggleMenuBar toggles menu bar visibility.
+//
+// w.ToggleMenuBar()
+func (w *WebviewWindow) ToggleMenuBar() {}
+
+// ToggleFrameless toggles the window frame.
+//
+// w.ToggleFrameless()
+func (w *WebviewWindow) ToggleFrameless() {}
+
+// ExecJS executes a JavaScript string in the webview.
+//
+// w.ExecJS("document.title = 'Ready'")
+func (w *WebviewWindow) ExecJS(js string) {}
+
+// Reload reloads the current page.
+//
+// w.Reload()
+func (w *WebviewWindow) Reload() {}
+
+// ForceReload bypasses the cache and reloads.
+//
+// w.ForceReload()
+func (w *WebviewWindow) ForceReload() {}
+
+// OpenDevTools opens the browser developer tools panel.
+//
+// w.OpenDevTools()
+func (w *WebviewWindow) OpenDevTools() {}
+
+// OpenContextMenu triggers a named context menu at the given position.
+//
+// w.OpenContextMenu(&ContextMenuData{Name: "edit", X: 100, Y: 200})
+func (w *WebviewWindow) OpenContextMenu(data *ContextMenuData) {}
+
+// Zoom applies the default zoom level.
+//
+// w.Zoom()
+func (w *WebviewWindow) Zoom() {}
+
+// ZoomIn increases the zoom level by one step.
+//
+// w.ZoomIn()
+func (w *WebviewWindow) ZoomIn() {}
+
+// ZoomOut decreases the zoom level by one step.
+//
+// w.ZoomOut()
+func (w *WebviewWindow) ZoomOut() {}
+
+// ZoomReset returns the zoom level to 1.0.
+//
+// w.ZoomReset()
+func (w *WebviewWindow) ZoomReset() Window { return w }
+
+// GetZoom returns the current zoom magnification factor.
+//
+// z := w.GetZoom()
+func (w *WebviewWindow) GetZoom() float64 { return 1.0 }
+
+// SetZoom sets the zoom magnification factor.
+//
+// w.SetZoom(1.5)
+func (w *WebviewWindow) SetZoom(magnification float64) Window { return w }
+
+// RegisterHook registers a pre-event hook for the given window event type.
+//
+// cancel := w.RegisterHook(events.Common.WindowClose, func(e *WindowEvent) { saveState() })
+// defer cancel()
+func (w *WebviewWindow) RegisterHook(eventType events.WindowEventType, callback func(event *WindowEvent)) func() {
+ return func() {}
+}
+
+// EmitEvent fires a named event from this window.
+//
+// w.EmitEvent("user:login", payload)
+func (w *WebviewWindow) EmitEvent(name string, data ...any) bool { return false }
+
+// DispatchWailsEvent sends a custom event through the Wails event bus.
+//
+// w.DispatchWailsEvent(&CustomEvent{Name: "init"})
+func (w *WebviewWindow) DispatchWailsEvent(event *CustomEvent) {}
+
+// GetScreen returns the screen on which this window is currently displayed.
+//
+// screen, err := w.GetScreen()
+func (w *WebviewWindow) GetScreen() (*Screen, error) { return nil, nil }
+
+// GetBorderSizes returns the platform-specific window border dimensions.
+//
+// borders := w.GetBorderSizes()
+func (w *WebviewWindow) GetBorderSizes() *LRTB { return nil }
+
+// EnableSizeConstraints activates the min/max size limits.
+//
+// w.EnableSizeConstraints()
+func (w *WebviewWindow) EnableSizeConstraints() {}
+
+// DisableSizeConstraints removes the min/max size limits.
+//
+// w.DisableSizeConstraints()
+func (w *WebviewWindow) DisableSizeConstraints() {}
+
+// AttachModal registers a modal window that blocks this window.
+//
+// w.AttachModal(confirmDialog)
+func (w *WebviewWindow) AttachModal(modalWindow Window) {}
+
+// Flash requests the window manager to flash or bounce this window.
+//
+// w.Flash(true)
+func (w *WebviewWindow) Flash(enabled bool) {}
+
+// Print opens the system print dialog for the webview contents.
+//
+// err := w.Print()
+func (w *WebviewWindow) Print() error { return nil }
+
+// Error logs an error-level message on behalf of this window.
+//
+// w.Error("load failed: %s", err)
+func (w *WebviewWindow) Error(message string, args ...any) {}
+
+// Info logs an info-level message on behalf of this window.
+//
+// w.Info("window ready")
+func (w *WebviewWindow) Info(message string, args ...any) {}
+
+// NativeWindow returns the platform-specific window handle (nil in stub).
+//
+// ptr := w.NativeWindow()
+func (w *WebviewWindow) NativeWindow() unsafe.Pointer { return nil }
+
+// Run starts the window event loop.
+//
+// w.Run()
+func (w *WebviewWindow) Run() {}
+
+// UnMaximise restores the window from maximised state.
+//
+// w.UnMaximise()
+func (w *WebviewWindow) UnMaximise() {
+ w.mu.Lock()
+ w.maximised = false
+ w.mu.Unlock()
+}
+
+// UnMinimise restores the window from minimised state.
+//
+// w.UnMinimise()
+func (w *WebviewWindow) UnMinimise() {}
+
+// ToggleFullscreen switches between fullscreen and windowed mode.
+//
+// w.ToggleFullscreen()
+func (w *WebviewWindow) ToggleFullscreen() {
+ w.mu.Lock()
+ w.fullscreen = !w.fullscreen
+ w.mu.Unlock()
+}
+
+// ToggleMaximise switches between maximised and restored state.
+//
+// w.ToggleMaximise()
+func (w *WebviewWindow) ToggleMaximise() {
+ w.mu.Lock()
+ w.maximised = !w.maximised
+ w.mu.Unlock()
+}
+
+// SnapAssist triggers the platform snap-assist feature.
+//
+// w.SnapAssist()
+func (w *WebviewWindow) SnapAssist() {}
+
+// Internal platform hooks — no-ops in the stub.
+
+func (w *WebviewWindow) handleDragAndDropMessage(filenames []string, dropTarget *DropTargetDetails) {}
+func (w *WebviewWindow) InitiateFrontendDropProcessing(filenames []string, x int, y int) {}
+func (w *WebviewWindow) HandleMessage(message string) {}
+func (w *WebviewWindow) HandleWindowEvent(id uint) {}
+func (w *WebviewWindow) HandleKeyEvent(acceleratorString string) {}
+func (w *WebviewWindow) shouldUnconditionallyClose() bool { return false }
+func (w *WebviewWindow) cut() {}
+func (w *WebviewWindow) copy() {}
+func (w *WebviewWindow) paste() {}
+func (w *WebviewWindow) undo() {}
+func (w *WebviewWindow) redo() {}
+func (w *WebviewWindow) delete() {}
+func (w *WebviewWindow) selectAll() {}
+
// WindowManager manages in-memory windows.
type WindowManager struct {
mu sync.RWMutex
@@ -338,10 +716,13 @@ func (wm *WindowManager) NewWithOptions(options WebviewWindowOptions) *WebviewWi
return window
}
-func (wm *WindowManager) GetAll() []any {
+// GetAll returns all windows managed by this manager.
+//
+// for _, w := range wm.GetAll() { w.Show() }
+func (wm *WindowManager) GetAll() []Window {
wm.mu.RLock()
defer wm.mu.RUnlock()
- out := make([]any, 0, len(wm.windows))
+ out := make([]Window, 0, len(wm.windows))
for _, window := range wm.windows {
out = append(out, window)
}
@@ -349,11 +730,23 @@ func (wm *WindowManager) GetAll() []any {
}
// App is the top-level application object used by the GUI packages.
+//
+// app := &application.App{}
+// app.Dialog.Info().SetTitle("Done").SetMessage("Saved.").Show()
+// app.Event.Emit("user:login", payload)
type App struct {
- Logger Logger
- Window WindowManager
- Menu MenuManager
- SystemTray SystemTrayManager
+ Logger Logger
+ Window WindowManager
+ Menu MenuManager
+ SystemTray SystemTrayManager
+ Dialog DialogManager
+ Event EventManager
+ Browser BrowserManager
+ Clipboard ClipboardManager
+ ContextMenu ContextMenuManager
+ Environment EnvironmentManager
+ Screen ScreenManager
+ KeyBinding KeyBindingManager
}
func (a *App) Quit() {}
diff --git a/stubs/wails/pkg/application/application_options.go b/stubs/wails/pkg/application/application_options.go
new file mode 100644
index 0000000..72f3ec4
--- /dev/null
+++ b/stubs/wails/pkg/application/application_options.go
@@ -0,0 +1,382 @@
+package application
+
+// Handler is a stub for net/http.Handler.
+// In the real Wails runtime this is http.Handler; the stub replaces it with
+// an interface so the application package compiles without importing net/http.
+//
+// var h Handler = myHTTPHandler
+type Handler interface {
+ ServeHTTP(w ResponseWriter, r *Request)
+}
+
+// ResponseWriter is a minimal stub for http.ResponseWriter.
+type ResponseWriter interface {
+ Header() map[string][]string
+ Write([]byte) (int, error)
+ WriteHeader(statusCode int)
+}
+
+// Request is a minimal stub for *http.Request.
+type Request struct {
+ Method string
+ URL string
+ Header map[string][]string
+ Body []byte
+}
+
+// FS is a stub for fs.FS (filesystem abstraction).
+// In the real Wails runtime this is io/fs.FS.
+type FS interface {
+ Open(name string) (interface{ Read([]byte) (int, error) }, error)
+}
+
+// Duration is a stub for time.Duration (nanoseconds).
+type Duration = int64
+
+// LogLevel is a stub for slog.Level.
+type LogLevel = int
+
+// Logger is a stub for *slog.Logger.
+// In production this is the standard library structured logger.
+type SlogLogger struct{}
+
+// Middleware defines HTTP middleware applied to the AssetServer.
+// The handler passed as next is the next handler in the chain.
+//
+// Middleware: func(next application.Handler) application.Handler { return myHandler }
+type Middleware func(next Handler) Handler
+
+// ChainMiddleware chains multiple middlewares into one.
+//
+// chained := application.ChainMiddleware(auth, logging, cors)
+func ChainMiddleware(middleware ...Middleware) Middleware {
+ return func(h Handler) Handler {
+ for i := len(middleware) - 1; i >= 0; i-- {
+ h = middleware[i](h)
+ }
+ return h
+ }
+}
+
+// AssetFileServerFS returns a handler serving assets from an FS.
+// In the stub this returns nil — no real file serving occurs.
+//
+// opts.Assets.Handler = application.AssetFileServerFS(embedFS)
+func AssetFileServerFS(assets FS) Handler { return nil }
+
+// BundledAssetFileServer returns a handler serving bundled assets.
+// In the stub this returns nil — no real file serving occurs.
+//
+// opts.Assets.Handler = application.BundledAssetFileServer(embedFS)
+func BundledAssetFileServer(assets FS) Handler { return nil }
+
+// ActivationPolicy controls the macOS application activation policy.
+//
+// Mac: MacOptions{ActivationPolicy: ActivationPolicyAccessory}
+type ActivationPolicy int
+
+const (
+ // ActivationPolicyRegular is for applications with a user interface.
+ ActivationPolicyRegular ActivationPolicy = iota
+ // ActivationPolicyAccessory is for menu-bar or background applications.
+ ActivationPolicyAccessory
+ // ActivationPolicyProhibited disables activation entirely.
+ ActivationPolicyProhibited
+)
+
+// NativeTabIcon is an SF Symbols name string used for iOS tab bar icons.
+//
+// NativeTabsItems: []NativeTabItem{{Title: "Home", SystemImage: NativeTabIconHouse}}
+type NativeTabIcon string
+
+const (
+ NativeTabIconNone NativeTabIcon = ""
+ NativeTabIconHouse NativeTabIcon = "house"
+ NativeTabIconGear NativeTabIcon = "gear"
+ NativeTabIconStar NativeTabIcon = "star"
+ NativeTabIconPerson NativeTabIcon = "person"
+ NativeTabIconBell NativeTabIcon = "bell"
+ NativeTabIconMagnify NativeTabIcon = "magnifyingglass"
+ NativeTabIconList NativeTabIcon = "list.bullet"
+ NativeTabIconFolder NativeTabIcon = "folder"
+)
+
+// NativeTabItem describes a single iOS UITabBar item.
+//
+// NativeTabsItems: []NativeTabItem{{Title: "Settings", SystemImage: NativeTabIconGear}}
+type NativeTabItem struct {
+ Title string `json:"Title"`
+ SystemImage NativeTabIcon `json:"SystemImage"`
+}
+
+// PanicDetails carries the information delivered to the panic handler.
+//
+// opts.PanicHandler = func(details *application.PanicDetails) { log(details.Message) }
+type PanicDetails struct {
+ // Message is the string form of the recovered panic value.
+ Message string
+ // Stack is the formatted goroutine stack trace.
+ Stack string
+}
+
+// Transport is the interface for custom IPC transport layers.
+// Implement this to replace the default HTTP fetch + js.Exec transport.
+//
+// opts.Transport = myWebSocketTransport
+type Transport interface{}
+
+// SingleInstanceOptions configures the single-instance lock behaviour.
+//
+// opts.SingleInstance = &application.SingleInstanceOptions{UniqueID: "com.example.myapp"}
+type SingleInstanceOptions struct {
+ // UniqueID is the identifier used to detect duplicate instances.
+ UniqueID string
+ // OnSecondInstanceLaunch is called in the first instance when a second
+ // one starts. Receives the arguments passed to the second instance.
+ OnSecondInstanceLaunch func(secondInstanceData SecondInstanceData)
+}
+
+// SecondInstanceData carries data from a second application instance launch.
+//
+// func handler(data application.SecondInstanceData) { openFile(data.Args[0]) }
+type SecondInstanceData struct {
+ // Args are the command-line arguments of the second instance.
+ Args []string
+ // WorkingDirectory is the cwd of the second instance.
+ WorkingDirectory string
+}
+
+// OriginInfo carries the origin details of a frontend message.
+//
+// opts.RawMessageHandler = func(w Window, msg string, info *application.OriginInfo) {}
+type OriginInfo struct {
+ // Origin is the origin of the frame that sent the message.
+ Origin string
+ // TopOrigin is the origin of the top-level frame.
+ TopOrigin string
+ // IsMainFrame is true when the message came from the main frame.
+ IsMainFrame bool
+}
+
+// AssetOptions configures the embedded asset server.
+//
+// opts.Assets = application.AssetOptions{Handler: application.AssetFileServerFS(embedFS)}
+type AssetOptions struct {
+ // Handler serves all content to the WebView.
+ Handler Handler
+
+ // Middleware hooks into the AssetServer request chain.
+ // Multiple middlewares can be composed with ChainMiddleware.
+ Middleware Middleware
+
+ // DisableLogging suppresses per-request AssetServer log output.
+ DisableLogging bool
+}
+
+// TLSOptions configures HTTPS for the headless server.
+//
+// opts.Server.TLS = &application.TLSOptions{CertFile: "cert.pem", KeyFile: "key.pem"}
+type TLSOptions struct {
+ // CertFile is the path to the TLS certificate file.
+ CertFile string
+ // KeyFile is the path to the TLS private key file.
+ KeyFile string
+}
+
+// ServerOptions configures the HTTP server used in headless (server) mode.
+// Enable server mode by building with: go build -tags server
+//
+// opts.Server = application.ServerOptions{Host: "0.0.0.0", Port: 8080}
+type ServerOptions struct {
+ // Host is the address to bind to. Defaults to "localhost".
+ Host string
+ // Port is the port to listen on. Defaults to 8080.
+ Port int
+ // ReadTimeout is the maximum duration for reading a request (nanoseconds).
+ ReadTimeout Duration
+ // WriteTimeout is the maximum duration for writing a response (nanoseconds).
+ WriteTimeout Duration
+ // IdleTimeout is the maximum idle connection duration (nanoseconds).
+ IdleTimeout Duration
+ // ShutdownTimeout is the maximum time to wait for graceful shutdown (nanoseconds).
+ ShutdownTimeout Duration
+ // TLS configures HTTPS. If nil, plain HTTP is used.
+ TLS *TLSOptions
+}
+
+// MacOptions contains macOS-specific application configuration.
+//
+// opts.Mac = application.MacOptions{ActivationPolicy: application.ActivationPolicyRegular}
+type MacOptions struct {
+ // ActivationPolicy controls how the app interacts with the Dock and menu bar.
+ ActivationPolicy ActivationPolicy
+ // ApplicationShouldTerminateAfterLastWindowClosed quits the app when the
+ // last window closes (matches NSApplicationDelegate behaviour).
+ ApplicationShouldTerminateAfterLastWindowClosed bool
+}
+
+// WindowsOptions contains Windows-specific application configuration.
+//
+// opts.Windows = application.WindowsOptions{WndClass: "MyAppWindow"}
+type WindowsOptions struct {
+ // WndClass is the Win32 window class name. Default: WailsWebviewWindow.
+ WndClass string
+ // WndProcInterceptor intercepts all Win32 messages for the application.
+ WndProcInterceptor func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnCode uintptr, shouldReturn bool)
+ // DisableQuitOnLastWindowClosed prevents auto-quit when the last window closes.
+ DisableQuitOnLastWindowClosed bool
+ // WebviewUserDataPath is the directory for WebView2 user data.
+ WebviewUserDataPath string
+ // WebviewBrowserPath is the directory containing WebView2 executables.
+ WebviewBrowserPath string
+ // EnabledFeatures lists WebView2 feature flags to enable.
+ EnabledFeatures []string
+ // DisabledFeatures lists WebView2 feature flags to disable.
+ DisabledFeatures []string
+ // AdditionalBrowserArgs are extra browser arguments (must include "--" prefix).
+ AdditionalBrowserArgs []string
+}
+
+// LinuxOptions contains Linux-specific application configuration.
+//
+// opts.Linux = application.LinuxOptions{ProgramName: "myapp"}
+type LinuxOptions struct {
+ // DisableQuitOnLastWindowClosed prevents auto-quit when the last window closes.
+ DisableQuitOnLastWindowClosed bool
+ // ProgramName sets g_set_prgname() for the window manager.
+ ProgramName string
+}
+
+// IOSOptions contains iOS-specific application configuration.
+//
+// opts.IOS = application.IOSOptions{EnableInlineMediaPlayback: true}
+type IOSOptions struct {
+ // DisableInputAccessoryView hides the iOS keyboard accessory bar.
+ DisableInputAccessoryView bool
+ // DisableScroll disables WebView scrolling.
+ DisableScroll bool
+ // DisableBounce disables the WebView bounce effect.
+ DisableBounce bool
+ // DisableScrollIndicators hides scroll indicators.
+ DisableScrollIndicators bool
+ // EnableBackForwardNavigationGestures enables swipe navigation.
+ EnableBackForwardNavigationGestures bool
+ // DisableLinkPreview disables link long-press previews.
+ DisableLinkPreview bool
+ // EnableInlineMediaPlayback allows media to play inline.
+ EnableInlineMediaPlayback bool
+ // EnableAutoplayWithoutUserAction allows media autoplay without a gesture.
+ EnableAutoplayWithoutUserAction bool
+ // DisableInspectable disables the Safari Web Inspector.
+ DisableInspectable bool
+ // UserAgent overrides the WebView user agent string.
+ UserAgent string
+ // ApplicationNameForUserAgent is appended to the user agent. Default: "wails.io".
+ ApplicationNameForUserAgent string
+ // AppBackgroundColourSet enables the custom BackgroundColour below.
+ AppBackgroundColourSet bool
+ // BackgroundColour is the app window background before WebView creation.
+ BackgroundColour RGBA
+ // EnableNativeTabs shows a native iOS UITabBar.
+ EnableNativeTabs bool
+ // NativeTabsItems configures the UITabBar items. Auto-enables tabs when non-empty.
+ NativeTabsItems []NativeTabItem
+}
+
+// AndroidOptions contains Android-specific application configuration.
+//
+// opts.Android = application.AndroidOptions{EnableZoom: true}
+type AndroidOptions struct {
+ // DisableScroll disables WebView scrolling.
+ DisableScroll bool
+ // DisableOverscroll disables the overscroll bounce effect.
+ DisableOverscroll bool
+ // EnableZoom allows pinch-to-zoom in the WebView.
+ EnableZoom bool
+ // UserAgent sets a custom user agent string.
+ UserAgent string
+ // BackgroundColour sets the WebView background colour.
+ BackgroundColour RGBA
+ // DisableHardwareAcceleration disables hardware acceleration.
+ DisableHardwareAcceleration bool
+}
+
+// Options is the top-level application configuration passed to New().
+//
+// app := application.New(application.Options{
+// Name: "MyApp",
+// Assets: application.AssetOptions{Handler: application.AssetFileServerFS(embedFS)},
+// Services: []application.Service{application.NewService(&myService{})},
+// })
+type Options struct {
+ // Name is the application name shown in the default about box.
+ Name string
+ // Description is shown in the default about box.
+ Description string
+ // Icon is the application icon bytes used in the about box.
+ Icon []byte
+
+ // Mac is the macOS-specific configuration.
+ Mac MacOptions
+ // Windows is the Windows-specific configuration.
+ Windows WindowsOptions
+ // Linux is the Linux-specific configuration.
+ Linux LinuxOptions
+ // IOS is the iOS-specific configuration.
+ IOS IOSOptions
+ // Android is the Android-specific configuration.
+ Android AndroidOptions
+
+ // Services are the bound Go service instances exposed to the frontend.
+ Services []Service
+ // MarshalError serialises error values from service methods to JSON.
+ // A nil return falls back to the default error handler.
+ MarshalError func(error) []byte
+ // BindAliases maps alias IDs to bound method IDs.
+ // Example: map[uint32]uint32{1: 1411160069}
+ BindAliases map[uint32]uint32
+
+ // Logger is the structured logger for Wails system messages.
+ // If nil, a default logger is used.
+ Logger *SlogLogger
+ // LogLevel sets the log level for the Wails system logger.
+ LogLevel LogLevel
+
+ // Assets configures the embedded asset server.
+ Assets AssetOptions
+ // Flags are key-value pairs exposed to the frontend.
+ Flags map[string]any
+
+ // PanicHandler is called when a panic occurs in a service method.
+ PanicHandler func(*PanicDetails)
+ // DisableDefaultSignalHandler disables the built-in SIGINT/SIGTERM handler.
+ DisableDefaultSignalHandler bool
+
+ // KeyBindings maps accelerator strings to window callbacks.
+ KeyBindings map[string]func(window Window)
+ // OnShutdown is called before the application terminates.
+ OnShutdown func()
+ // PostShutdown is called after shutdown completes, just before process exit.
+ PostShutdown func()
+ // ShouldQuit is called when the user requests quit. Return false to cancel.
+ ShouldQuit func() bool
+ // RawMessageHandler handles raw messages sent from the frontend.
+ RawMessageHandler func(window Window, message string, originInfo *OriginInfo)
+ // WarningHandler is called when a non-fatal warning occurs.
+ WarningHandler func(string)
+ // ErrorHandler is called when an error occurs.
+ ErrorHandler func(err error)
+
+ // FileAssociations lists file extensions associated with this application.
+ // Example: []string{".txt", ".md"} — the leading dot is required.
+ FileAssociations []string
+ // SingleInstance configures single-instance enforcement.
+ SingleInstance *SingleInstanceOptions
+
+ // Transport provides a custom IPC transport layer.
+ // When nil, the default HTTP fetch transport is used.
+ Transport Transport
+
+ // Server configures the headless HTTP server (requires -tags server).
+ Server ServerOptions
+}
diff --git a/stubs/wails/pkg/application/browser_manager.go b/stubs/wails/pkg/application/browser_manager.go
new file mode 100644
index 0000000..7e014af
--- /dev/null
+++ b/stubs/wails/pkg/application/browser_manager.go
@@ -0,0 +1,36 @@
+package application
+
+import "sync"
+
+// BrowserManager manages browser-related operations in-memory.
+//
+// manager := &BrowserManager{}
+// manager.OpenURL("https://example.com")
+// last := manager.LastURL // "https://example.com"
+type BrowserManager struct {
+ mu sync.RWMutex
+ LastURL string
+ LastFile string
+}
+
+// OpenURL stores the URL as the last opened URL.
+//
+// manager.OpenURL("https://lthn.io")
+// _ = manager.LastURL // "https://lthn.io"
+func (bm *BrowserManager) OpenURL(url string) error {
+ bm.mu.Lock()
+ bm.LastURL = url
+ bm.mu.Unlock()
+ return nil
+}
+
+// OpenFile stores the path as the last opened file.
+//
+// manager.OpenFile("/home/user/report.pdf")
+// _ = manager.LastFile // "/home/user/report.pdf"
+func (bm *BrowserManager) OpenFile(path string) error {
+ bm.mu.Lock()
+ bm.LastFile = path
+ bm.mu.Unlock()
+ return nil
+}
diff --git a/stubs/wails/pkg/application/browser_window.go b/stubs/wails/pkg/application/browser_window.go
new file mode 100644
index 0000000..8bef2a4
--- /dev/null
+++ b/stubs/wails/pkg/application/browser_window.go
@@ -0,0 +1,192 @@
+package application
+
+import (
+ "sync"
+ "unsafe"
+
+ "github.com/wailsapp/wails/v3/pkg/events"
+)
+
+// ButtonState controls window button appearance.
+type ButtonState int
+
+const (
+ ButtonEnabled ButtonState = 0
+ ButtonDisabled ButtonState = 1
+ ButtonHidden ButtonState = 2
+)
+
+// LRTB represents Left, Right, Top, Bottom border sizes.
+type LRTB struct {
+ Left, Right, Top, Bottom int
+}
+
+// ContextMenuData carries context menu trigger details.
+type ContextMenuData struct {
+ Name string
+ X, Y int
+ Data any
+}
+
+// BrowserWindow represents a browser client connection in server mode.
+// Implements the Window interface — most methods are no-ops since browser
+// clients are controlled via WebSocket, not native APIs.
+//
+// browserWindow := application.NewBrowserWindow(1, "client-abc123")
+type BrowserWindow struct {
+ mu sync.RWMutex
+ id uint
+ name string
+ clientID string
+}
+
+// NewBrowserWindow creates a browser window with the given ID and client ID.
+//
+// browserWindow := application.NewBrowserWindow(1, "nanoid-abc123")
+func NewBrowserWindow(id uint, clientID string) *BrowserWindow {
+ return &BrowserWindow{
+ id: id,
+ name: "browser-" + string(rune('0'+id%10)),
+ clientID: clientID,
+ }
+}
+
+func (browserWindow *BrowserWindow) ID() uint { return browserWindow.id }
+func (browserWindow *BrowserWindow) Name() string { return browserWindow.name }
+func (browserWindow *BrowserWindow) ClientID() string { return browserWindow.clientID }
+
+func (browserWindow *BrowserWindow) DispatchWailsEvent(event *CustomEvent) {}
+func (browserWindow *BrowserWindow) EmitEvent(name string, data ...any) bool {
+ return true
+}
+
+func (browserWindow *BrowserWindow) Error(message string, arguments ...any) {}
+func (browserWindow *BrowserWindow) Info(message string, arguments ...any) {}
+
+// No-op methods — browser windows are controlled via WebSocket, not native APIs.
+func (browserWindow *BrowserWindow) Center() {}
+func (browserWindow *BrowserWindow) Close() {}
+func (browserWindow *BrowserWindow) DisableSizeConstraints() {}
+func (browserWindow *BrowserWindow) EnableSizeConstraints() {}
+func (browserWindow *BrowserWindow) ExecJS(javascript string) {}
+func (browserWindow *BrowserWindow) Focus() {}
+func (browserWindow *BrowserWindow) ForceReload() {}
+func (browserWindow *BrowserWindow) Fullscreen() Window { return browserWindow }
+func (browserWindow *BrowserWindow) GetBorderSizes() *LRTB { return nil }
+func (browserWindow *BrowserWindow) GetScreen() (*Screen, error) {
+ return nil, nil
+}
+func (browserWindow *BrowserWindow) GetZoom() float64 { return 1.0 }
+func (browserWindow *BrowserWindow) handleDragAndDropMessage(filenames []string, dropTarget *DropTargetDetails) {
+}
+func (browserWindow *BrowserWindow) HandleMessage(message string) {}
+func (browserWindow *BrowserWindow) HandleWindowEvent(identifier uint) {}
+func (browserWindow *BrowserWindow) Height() int { return 0 }
+func (browserWindow *BrowserWindow) Hide() Window { return browserWindow }
+func (browserWindow *BrowserWindow) HideMenuBar() {}
+func (browserWindow *BrowserWindow) IsFocused() bool { return false }
+func (browserWindow *BrowserWindow) IsFullscreen() bool { return false }
+func (browserWindow *BrowserWindow) IsIgnoreMouseEvents() bool { return false }
+func (browserWindow *BrowserWindow) IsMaximised() bool { return false }
+func (browserWindow *BrowserWindow) IsMinimised() bool { return false }
+func (browserWindow *BrowserWindow) HandleKeyEvent(accelerator string) {}
+func (browserWindow *BrowserWindow) Maximise() Window { return browserWindow }
+func (browserWindow *BrowserWindow) Minimise() Window { return browserWindow }
+func (browserWindow *BrowserWindow) OnWindowEvent(eventType events.WindowEventType, callback func(event *WindowEvent)) func() {
+ return func() {}
+}
+func (browserWindow *BrowserWindow) OpenContextMenu(data *ContextMenuData) {}
+func (browserWindow *BrowserWindow) Position() (int, int) { return 0, 0 }
+func (browserWindow *BrowserWindow) RelativePosition() (int, int) { return 0, 0 }
+func (browserWindow *BrowserWindow) Reload() {}
+func (browserWindow *BrowserWindow) Resizable() bool { return false }
+func (browserWindow *BrowserWindow) Restore() {}
+func (browserWindow *BrowserWindow) Run() {}
+func (browserWindow *BrowserWindow) SetPosition(x, y int) {}
+func (browserWindow *BrowserWindow) SetAlwaysOnTop(alwaysOnTop bool) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetBackgroundColour(colour RGBA) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetFrameless(frameless bool) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetHTML(html string) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetMinimiseButtonState(state ButtonState) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetMaximiseButtonState(state ButtonState) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetCloseButtonState(state ButtonState) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetMaxSize(maxWidth, maxHeight int) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetMinSize(minWidth, minHeight int) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetRelativePosition(x, y int) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetResizable(resizable bool) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetIgnoreMouseEvents(ignore bool) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetSize(width, height int) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetTitle(title string) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetURL(url string) Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetZoom(magnification float64) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) Show() Window { return browserWindow }
+func (browserWindow *BrowserWindow) ShowMenuBar() {}
+func (browserWindow *BrowserWindow) Size() (int, int) { return 0, 0 }
+func (browserWindow *BrowserWindow) OpenDevTools() {}
+func (browserWindow *BrowserWindow) ToggleFullscreen() {}
+func (browserWindow *BrowserWindow) ToggleMaximise() {}
+func (browserWindow *BrowserWindow) ToggleMenuBar() {}
+func (browserWindow *BrowserWindow) ToggleFrameless() {}
+func (browserWindow *BrowserWindow) UnFullscreen() {}
+func (browserWindow *BrowserWindow) UnMaximise() {}
+func (browserWindow *BrowserWindow) UnMinimise() {}
+func (browserWindow *BrowserWindow) Width() int { return 0 }
+func (browserWindow *BrowserWindow) IsVisible() bool { return true }
+func (browserWindow *BrowserWindow) Bounds() Rect { return Rect{} }
+func (browserWindow *BrowserWindow) SetBounds(bounds Rect) {}
+func (browserWindow *BrowserWindow) Zoom() {}
+func (browserWindow *BrowserWindow) ZoomIn() {}
+func (browserWindow *BrowserWindow) ZoomOut() {}
+func (browserWindow *BrowserWindow) ZoomReset() Window { return browserWindow }
+func (browserWindow *BrowserWindow) SetMenu(menu *Menu) {}
+func (browserWindow *BrowserWindow) SnapAssist() {}
+func (browserWindow *BrowserWindow) SetContentProtection(protection bool) Window {
+ return browserWindow
+}
+func (browserWindow *BrowserWindow) SetEnabled(enabled bool) {}
+func (browserWindow *BrowserWindow) Flash(enabled bool) {}
+func (browserWindow *BrowserWindow) Print() error { return nil }
+func (browserWindow *BrowserWindow) RegisterHook(eventType events.WindowEventType, callback func(event *WindowEvent)) func() {
+ return func() {}
+}
+
+// Internal platform hooks — no-ops for browser windows.
+
+func (browserWindow *BrowserWindow) InitiateFrontendDropProcessing(filenames []string, x int, y int) {
+}
+func (browserWindow *BrowserWindow) shouldUnconditionallyClose() bool { return false }
+func (browserWindow *BrowserWindow) cut() {}
+func (browserWindow *BrowserWindow) copy() {}
+func (browserWindow *BrowserWindow) paste() {}
+func (browserWindow *BrowserWindow) undo() {}
+func (browserWindow *BrowserWindow) redo() {}
+func (browserWindow *BrowserWindow) delete() {}
+func (browserWindow *BrowserWindow) selectAll() {}
+
+// NativeWindow returns nil — browser windows have no native handle.
+//
+// ptr := w.NativeWindow()
+func (browserWindow *BrowserWindow) NativeWindow() unsafe.Pointer { return nil }
+
+// AttachModal registers a modal window that blocks this window.
+//
+// w.AttachModal(confirmDialog)
+func (browserWindow *BrowserWindow) AttachModal(modalWindow Window) {}
diff --git a/stubs/wails/pkg/application/clipboard.go b/stubs/wails/pkg/application/clipboard.go
new file mode 100644
index 0000000..db85f35
--- /dev/null
+++ b/stubs/wails/pkg/application/clipboard.go
@@ -0,0 +1,69 @@
+package application
+
+import "sync"
+
+// Clipboard stores and retrieves text in-memory.
+//
+// cb := &Clipboard{}
+// cb.SetText("hello")
+// text, ok := cb.Text() // "hello", true
+type Clipboard struct {
+ mu sync.RWMutex
+ text string
+ set bool
+}
+
+// SetText stores the given text in the in-memory clipboard.
+//
+// cb.SetText("copied content")
+func (c *Clipboard) SetText(text string) bool {
+ c.mu.Lock()
+ c.text = text
+ c.set = true
+ c.mu.Unlock()
+ return true
+}
+
+// Text returns the stored clipboard text and whether any text has been set.
+//
+// text, ok := cb.Text()
+// if !ok { text = "" }
+func (c *Clipboard) Text() (string, bool) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return c.text, c.set
+}
+
+// ClipboardManager manages clipboard operations via a lazily created Clipboard.
+//
+// manager := &ClipboardManager{}
+// manager.SetText("hello")
+// text, ok := manager.Text() // "hello", true
+type ClipboardManager struct {
+ mu sync.Mutex
+ clipboard *Clipboard
+}
+
+// SetText sets text in the clipboard.
+//
+// manager.SetText("some text")
+func (cm *ClipboardManager) SetText(text string) bool {
+ return cm.getClipboard().SetText(text)
+}
+
+// Text gets text from the clipboard.
+//
+// text, ok := manager.Text()
+func (cm *ClipboardManager) Text() (string, bool) {
+ return cm.getClipboard().Text()
+}
+
+// getClipboard returns the clipboard instance, creating it if needed.
+func (cm *ClipboardManager) getClipboard() *Clipboard {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+ if cm.clipboard == nil {
+ cm.clipboard = &Clipboard{}
+ }
+ return cm.clipboard
+}
diff --git a/stubs/wails/pkg/application/context_menu.go b/stubs/wails/pkg/application/context_menu.go
new file mode 100644
index 0000000..1ac45de
--- /dev/null
+++ b/stubs/wails/pkg/application/context_menu.go
@@ -0,0 +1,84 @@
+package application
+
+import "sync"
+
+// ContextMenu is a named menu used for right-click context menus.
+//
+// menu := &ContextMenu{name: "file-list", Menu: NewMenu()}
+// menu.Add("Open")
+type ContextMenu struct {
+ *Menu
+ name string
+}
+
+// ContextMenuManager manages all context menu operations in-memory.
+//
+// manager := &ContextMenuManager{}
+// menu := manager.New()
+// manager.Add("file-list", menu)
+// retrieved, ok := manager.Get("file-list")
+type ContextMenuManager struct {
+ mu sync.RWMutex
+ contextMenus map[string]*ContextMenu
+}
+
+// New creates a new context menu.
+//
+// menu := manager.New()
+// menu.Add("Delete")
+func (cmm *ContextMenuManager) New() *ContextMenu {
+ return &ContextMenu{
+ Menu: NewMenu(),
+ }
+}
+
+// Add registers a context menu under the given name.
+//
+// manager.Add("item-actions", menu)
+func (cmm *ContextMenuManager) Add(name string, menu *ContextMenu) {
+ cmm.mu.Lock()
+ defer cmm.mu.Unlock()
+ if cmm.contextMenus == nil {
+ cmm.contextMenus = make(map[string]*ContextMenu)
+ }
+ cmm.contextMenus[name] = menu
+}
+
+// Remove removes a context menu by name.
+//
+// manager.Remove("item-actions")
+func (cmm *ContextMenuManager) Remove(name string) {
+ cmm.mu.Lock()
+ defer cmm.mu.Unlock()
+ if cmm.contextMenus != nil {
+ delete(cmm.contextMenus, name)
+ }
+}
+
+// Get retrieves a context menu by name.
+//
+// menu, ok := manager.Get("item-actions")
+// if !ok { return nil }
+func (cmm *ContextMenuManager) Get(name string) (*ContextMenu, bool) {
+ cmm.mu.RLock()
+ defer cmm.mu.RUnlock()
+ if cmm.contextMenus == nil {
+ return nil, false
+ }
+ menu, exists := cmm.contextMenus[name]
+ return menu, exists
+}
+
+// GetAll returns all registered context menus as a slice.
+//
+// menus := manager.GetAll()
+// for _, m := range menus { _ = m }
+func (cmm *ContextMenuManager) GetAll() []*ContextMenu {
+ cmm.mu.RLock()
+ defer cmm.mu.RUnlock()
+ result := make([]*ContextMenu, 0, len(cmm.contextMenus))
+ for _, menu := range cmm.contextMenus {
+ result = append(result, menu)
+ }
+ return result
+}
diff --git a/stubs/wails/pkg/application/dialog.go b/stubs/wails/pkg/application/dialog.go
new file mode 100644
index 0000000..8613911
--- /dev/null
+++ b/stubs/wails/pkg/application/dialog.go
@@ -0,0 +1,421 @@
+package application
+
+import "sync"
+
+// DialogType identifies the visual style of a message dialog.
+type DialogType int
+
+const (
+ InfoDialogType DialogType = iota
+ QuestionDialogType
+ WarningDialogType
+ ErrorDialogType
+)
+
+// FileFilter restricts which files are shown in a file dialog.
+//
+// filter := FileFilter{DisplayName: "Images", Pattern: "*.png;*.jpg"}
+type FileFilter struct {
+ DisplayName string
+ Pattern string
+}
+
+// OpenFileDialogOptions configures an open-file dialog.
+//
+// opts := &OpenFileDialogOptions{Title: "Choose file", AllowsMultipleSelection: true}
+type OpenFileDialogOptions struct {
+ Title string
+ Directory string
+ Filters []FileFilter
+ AllowsMultipleSelection bool
+ CanChooseDirectories bool
+ CanChooseFiles bool
+ ShowHiddenFiles bool
+}
+
+// SaveFileDialogOptions configures a save-file dialog.
+//
+// opts := &SaveFileDialogOptions{Title: "Save report", Directory: "/tmp"}
+type SaveFileDialogOptions struct {
+ Title string
+ Directory string
+ Filename string
+ Filters []FileFilter
+ ShowHiddenFiles bool
+}
+
+// OpenFileDialogStruct is an in-memory open-file dialog.
+//
+// dialog := &OpenFileDialogStruct{}
+// dialog.SetTitle("Pick a file")
+// path, _ := dialog.PromptForSingleSelection()
+type OpenFileDialogStruct struct {
+ mu sync.RWMutex
+ title string
+ directory string
+ filters []FileFilter
+ multipleAllowed bool
+ canChooseDirs bool
+ canChooseFiles bool
+ showHidden bool
+ selectedFiles []string
+}
+
+func newOpenFileDialog() *OpenFileDialogStruct {
+ return &OpenFileDialogStruct{canChooseFiles: true}
+}
+
+// SetOptions applies OpenFileDialogOptions to the dialog.
+//
+// dialog.SetOptions(&OpenFileDialogOptions{Title: "Open log", ShowHiddenFiles: true})
+func (d *OpenFileDialogStruct) SetOptions(options *OpenFileDialogOptions) {
+ if options == nil {
+ return
+ }
+ d.mu.Lock()
+ d.title = options.Title
+ d.directory = options.Directory
+ d.filters = append([]FileFilter(nil), options.Filters...)
+ d.multipleAllowed = options.AllowsMultipleSelection
+ d.canChooseDirs = options.CanChooseDirectories
+ d.canChooseFiles = options.CanChooseFiles
+ d.showHidden = options.ShowHiddenFiles
+ d.mu.Unlock()
+}
+
+// SetTitle sets the dialog window title.
+//
+// dialog.SetTitle("Select configuration file")
+func (d *OpenFileDialogStruct) SetTitle(title string) *OpenFileDialogStruct {
+ d.mu.Lock()
+ d.title = title
+ d.mu.Unlock()
+ return d
+}
+
+// SetDirectory sets the initial directory shown in the dialog.
+//
+// dialog.SetDirectory("/home/user/documents")
+func (d *OpenFileDialogStruct) SetDirectory(directory string) *OpenFileDialogStruct {
+ d.mu.Lock()
+ d.directory = directory
+ d.mu.Unlock()
+ return d
+}
+
+// AddFilter appends a file filter to the dialog.
+//
+// dialog.AddFilter("Go source", "*.go")
+func (d *OpenFileDialogStruct) AddFilter(displayName, pattern string) *OpenFileDialogStruct {
+ d.mu.Lock()
+ d.filters = append(d.filters, FileFilter{DisplayName: displayName, Pattern: pattern})
+ d.mu.Unlock()
+ return d
+}
+
+// SetAllowsMultipleSelection controls whether multiple files can be selected.
+//
+// dialog.SetAllowsMultipleSelection(true)
+func (d *OpenFileDialogStruct) SetAllowsMultipleSelection(allow bool) *OpenFileDialogStruct {
+ d.mu.Lock()
+ d.multipleAllowed = allow
+ d.mu.Unlock()
+ return d
+}
+
+// SetSelectedFiles injects pre-selected files for stub testing.
+//
+// dialog.SetSelectedFiles([]string{"/tmp/a.txt", "/tmp/b.txt"})
+func (d *OpenFileDialogStruct) SetSelectedFiles(paths []string) {
+ d.mu.Lock()
+ d.selectedFiles = append([]string(nil), paths...)
+ d.mu.Unlock()
+}
+
+// PromptForSingleSelection returns the first injected file path, or "" if none.
+//
+// path, err := dialog.PromptForSingleSelection()
+// if err != nil { return err }
+func (d *OpenFileDialogStruct) PromptForSingleSelection() (string, error) {
+ d.mu.RLock()
+ defer d.mu.RUnlock()
+ if len(d.selectedFiles) > 0 {
+ return d.selectedFiles[0], nil
+ }
+ return "", nil
+}
+
+// PromptForMultipleSelection returns all injected file paths.
+//
+// paths, err := dialog.PromptForMultipleSelection()
+// for _, p := range paths { process(p) }
+func (d *OpenFileDialogStruct) PromptForMultipleSelection() ([]string, error) {
+ d.mu.RLock()
+ defer d.mu.RUnlock()
+ return append([]string(nil), d.selectedFiles...), nil
+}
+
+// SaveFileDialogStruct is an in-memory save-file dialog.
+//
+// dialog := &SaveFileDialogStruct{}
+// dialog.SetFilename("report.pdf")
+// path, _ := dialog.PromptForSingleSelection()
+type SaveFileDialogStruct struct {
+ mu sync.RWMutex
+ title string
+ directory string
+ filename string
+ filters []FileFilter
+ showHidden bool
+ selectedPath string
+}
+
+func newSaveFileDialog() *SaveFileDialogStruct {
+ return &SaveFileDialogStruct{}
+}
+
+// SetOptions applies SaveFileDialogOptions to the dialog.
+//
+// dialog.SetOptions(&SaveFileDialogOptions{Title: "Export", Filename: "data.json"})
+func (d *SaveFileDialogStruct) SetOptions(options *SaveFileDialogOptions) {
+ if options == nil {
+ return
+ }
+ d.mu.Lock()
+ d.title = options.Title
+ d.directory = options.Directory
+ d.filename = options.Filename
+ d.filters = append([]FileFilter(nil), options.Filters...)
+ d.showHidden = options.ShowHiddenFiles
+ d.mu.Unlock()
+}
+
+// SetTitle sets the dialog window title.
+//
+// dialog.SetTitle("Export configuration")
+func (d *SaveFileDialogStruct) SetTitle(title string) *SaveFileDialogStruct {
+ d.mu.Lock()
+ d.title = title
+ d.mu.Unlock()
+ return d
+}
+
+// SetDirectory sets the initial directory shown in the dialog.
+//
+// dialog.SetDirectory("/home/user/exports")
+func (d *SaveFileDialogStruct) SetDirectory(directory string) *SaveFileDialogStruct {
+ d.mu.Lock()
+ d.directory = directory
+ d.mu.Unlock()
+ return d
+}
+
+// SetFilename sets the default filename shown in the dialog.
+//
+// dialog.SetFilename("backup-2026.tar.gz")
+func (d *SaveFileDialogStruct) SetFilename(filename string) *SaveFileDialogStruct {
+ d.mu.Lock()
+ d.filename = filename
+ d.mu.Unlock()
+ return d
+}
+
+// AddFilter appends a file filter to the dialog.
+//
+// dialog.AddFilter("JSON files", "*.json")
+func (d *SaveFileDialogStruct) AddFilter(displayName, pattern string) *SaveFileDialogStruct {
+ d.mu.Lock()
+ d.filters = append(d.filters, FileFilter{DisplayName: displayName, Pattern: pattern})
+ d.mu.Unlock()
+ return d
+}
+
+// SetSelectedPath injects the path returned by PromptForSingleSelection for stub testing.
+//
+// dialog.SetSelectedPath("/tmp/output.csv")
+func (d *SaveFileDialogStruct) SetSelectedPath(path string) {
+ d.mu.Lock()
+ d.selectedPath = path
+ d.mu.Unlock()
+}
+
+// PromptForSingleSelection returns the injected save path, or "" if none.
+//
+// path, err := dialog.PromptForSingleSelection()
+// if err != nil { return err }
+func (d *SaveFileDialogStruct) PromptForSingleSelection() (string, error) {
+ d.mu.RLock()
+ defer d.mu.RUnlock()
+ return d.selectedPath, nil
+}
+
+// MessageButton represents a button in a message dialog.
+type MessageButton struct {
+ Label string
+ IsDefault bool
+ IsCancel bool
+}
+
+// MessageDialog is an in-memory message dialog (info, question, warning, error).
+//
+// dialog := &MessageDialog{dialogType: InfoDialogType}
+// dialog.SetTitle("Done").SetMessage("File saved successfully.")
+// _ = dialog.Show()
+type MessageDialog struct {
+ mu sync.RWMutex
+ dialogType DialogType
+ title string
+ message string
+ buttons []MessageButton
+ clickedButton string
+}
+
+func newMessageDialog(dialogType DialogType) *MessageDialog {
+ return &MessageDialog{dialogType: dialogType}
+}
+
+// SetTitle sets the dialog window title.
+//
+// dialog.SetTitle("Confirm deletion")
+func (d *MessageDialog) SetTitle(title string) *MessageDialog {
+ d.mu.Lock()
+ d.title = title
+ d.mu.Unlock()
+ return d
+}
+
+// SetMessage sets the body text of the dialog.
+//
+// dialog.SetMessage("Are you sure you want to delete this file?")
+func (d *MessageDialog) SetMessage(message string) *MessageDialog {
+ d.mu.Lock()
+ d.message = message
+ d.mu.Unlock()
+ return d
+}
+
+// AddButton appends a button to the dialog.
+//
+// dialog.AddButton("Yes").AddButton("No")
+func (d *MessageDialog) AddButton(label string) *MessageDialog {
+ d.mu.Lock()
+ d.buttons = append(d.buttons, MessageButton{Label: label})
+ d.mu.Unlock()
+ return d
+}
+
+// SetDefaultButton marks the named button as the default action.
+//
+// dialog.SetDefaultButton("OK")
+func (d *MessageDialog) SetDefaultButton(label string) *MessageDialog {
+ d.mu.Lock()
+ for index := range d.buttons {
+ d.buttons[index].IsDefault = d.buttons[index].Label == label
+ }
+ d.mu.Unlock()
+ return d
+}
+
+// SetCancelButton marks the named button as the cancel action.
+//
+// dialog.SetCancelButton("Cancel")
+func (d *MessageDialog) SetCancelButton(label string) *MessageDialog {
+ d.mu.Lock()
+ for index := range d.buttons {
+ d.buttons[index].IsCancel = d.buttons[index].Label == label
+ }
+ d.mu.Unlock()
+ return d
+}
+
+// SetButtonClickedForStub injects which button was clicked for stub testing.
+//
+// dialog.SetButtonClickedForStub("Yes")
+// result, _ := dialog.Show()
+func (d *MessageDialog) SetButtonClickedForStub(label string) {
+ d.mu.Lock()
+ d.clickedButton = label
+ d.mu.Unlock()
+}
+
+// Show displays the dialog and returns the label of the clicked button.
+//
+// clicked, err := dialog.Show()
+// if clicked == "Yes" { deleteFile() }
+func (d *MessageDialog) Show() (string, error) {
+ d.mu.RLock()
+ defer d.mu.RUnlock()
+ return d.clickedButton, nil
+}
+
+// DialogManager manages dialog operations in-memory.
+//
+// manager := &DialogManager{}
+// dialog := manager.Info().SetTitle("Done").SetMessage("Saved.")
+type DialogManager struct {
+ mu sync.RWMutex
+}
+
+// OpenFile creates an open-file dialog.
+//
+// dialog := manager.OpenFile()
+// dialog.SetTitle("Choose config")
+// path, _ := dialog.PromptForSingleSelection()
+func (dm *DialogManager) OpenFile() *OpenFileDialogStruct {
+ return newOpenFileDialog()
+}
+
+// OpenFileWithOptions creates an open-file dialog pre-configured from options.
+//
+// dialog := manager.OpenFileWithOptions(&OpenFileDialogOptions{Title: "Select log"})
+func (dm *DialogManager) OpenFileWithOptions(options *OpenFileDialogOptions) *OpenFileDialogStruct {
+ dialog := newOpenFileDialog()
+ dialog.SetOptions(options)
+ return dialog
+}
+
+// SaveFile creates a save-file dialog.
+//
+// dialog := manager.SaveFile()
+// dialog.SetFilename("export.csv")
+// path, _ := dialog.PromptForSingleSelection()
+func (dm *DialogManager) SaveFile() *SaveFileDialogStruct {
+ return newSaveFileDialog()
+}
+
+// SaveFileWithOptions creates a save-file dialog pre-configured from options.
+//
+// dialog := manager.SaveFileWithOptions(&SaveFileDialogOptions{Title: "Export data"})
+func (dm *DialogManager) SaveFileWithOptions(options *SaveFileDialogOptions) *SaveFileDialogStruct {
+ dialog := newSaveFileDialog()
+ dialog.SetOptions(options)
+ return dialog
+}
+
+// Info creates an information message dialog.
+//
+// manager.Info().SetTitle("Done").SetMessage("File saved.").Show()
+func (dm *DialogManager) Info() *MessageDialog {
+ return newMessageDialog(InfoDialogType)
+}
+
+// Question creates a question message dialog.
+//
+// manager.Question().SetTitle("Confirm").SetMessage("Delete file?").AddButton("Yes").AddButton("No").Show()
+func (dm *DialogManager) Question() *MessageDialog {
+ return newMessageDialog(QuestionDialogType)
+}
+
+// Warning creates a warning message dialog.
+//
+// manager.Warning().SetTitle("Warning").SetMessage("Disk almost full.").Show()
+func (dm *DialogManager) Warning() *MessageDialog {
+ return newMessageDialog(WarningDialogType)
+}
+
+// Error creates an error message dialog.
+//
+// manager.Error().SetTitle("Error").SetMessage("Operation failed.").Show()
+func (dm *DialogManager) Error() *MessageDialog {
+ return newMessageDialog(ErrorDialogType)
+}
diff --git a/stubs/wails/pkg/application/environment.go b/stubs/wails/pkg/application/environment.go
new file mode 100644
index 0000000..98651c9
--- /dev/null
+++ b/stubs/wails/pkg/application/environment.go
@@ -0,0 +1,85 @@
+package application
+
+import "sync"
+
+// EnvironmentInfo holds information about the host environment.
+//
+// info := manager.Info()
+// if info.IsDarkMode { applyDarkTheme() }
+type EnvironmentInfo struct {
+ OS string
+ Arch string
+ Debug bool
+ IsDarkMode bool
+ AccentColour string
+ PlatformInfo map[string]any
+}
+
+// EnvironmentManager tracks environment state in-memory.
+//
+// manager := &EnvironmentManager{}
+// manager.SetDarkMode(true)
+// dark := manager.IsDarkMode() // true
+type EnvironmentManager struct {
+ mu sync.RWMutex
+ darkMode bool
+ accentColour string
+ operatingSystem string
+ architecture string
+ debugMode bool
+}
+
+// SetDarkMode sets the dark mode state used by IsDarkMode.
+//
+// manager.SetDarkMode(true)
+func (em *EnvironmentManager) SetDarkMode(darkMode bool) {
+ em.mu.Lock()
+ em.darkMode = darkMode
+ em.mu.Unlock()
+}
+
+// IsDarkMode returns true when the environment is in dark mode.
+//
+// if manager.IsDarkMode() { applyDarkTheme() }
+func (em *EnvironmentManager) IsDarkMode() bool {
+ em.mu.RLock()
+ defer em.mu.RUnlock()
+ return em.darkMode
+}
+
+// SetAccentColour sets the accent colour returned by GetAccentColor.
+//
+// manager.SetAccentColour("rgb(0,122,255)")
+func (em *EnvironmentManager) SetAccentColour(colour string) {
+ em.mu.Lock()
+ em.accentColour = colour
+ em.mu.Unlock()
+}
+
+// GetAccentColor returns the stored accent colour, or the default blue if unset.
+//
+// colour := manager.GetAccentColor() // "rgb(0,122,255)"
+func (em *EnvironmentManager) GetAccentColor() string {
+ em.mu.RLock()
+ defer em.mu.RUnlock()
+ if em.accentColour == "" {
+ return "rgb(0,122,255)"
+ }
+ return em.accentColour
+}
+
+// Info returns a snapshot of the current environment state.
+//
+// info := manager.Info()
+// _ = info.OS // e.g. "linux"
+func (em *EnvironmentManager) Info() EnvironmentInfo {
+ em.mu.RLock()
+ defer em.mu.RUnlock()
+ return EnvironmentInfo{
+ OS: em.operatingSystem,
+ Arch: em.architecture,
+ Debug: em.debugMode,
+ IsDarkMode: em.darkMode,
+ AccentColour: em.accentColour,
+ }
+}
diff --git a/stubs/wails/pkg/application/events.go b/stubs/wails/pkg/application/events.go
new file mode 100644
index 0000000..e063871
--- /dev/null
+++ b/stubs/wails/pkg/application/events.go
@@ -0,0 +1,212 @@
+package application
+
+import (
+ "sync"
+ "sync/atomic"
+
+ "github.com/wailsapp/wails/v3/pkg/events"
+)
+
+// ApplicationEventContext carries optional context for an application event.
+//
+// ctx := event.Context()
+// _ = ctx // reserved for future platform-specific fields
+type ApplicationEventContext struct{}
+
+func newApplicationEventContext() *ApplicationEventContext {
+ return &ApplicationEventContext{}
+}
+
+// ApplicationEvent is emitted by the application layer for system-level events.
+//
+// manager.OnApplicationEvent(events.Mac.ApplicationShouldTerminate, func(e *ApplicationEvent) {
+// e.Cancel()
+// })
+type ApplicationEvent struct {
+ Id uint
+ ctx *ApplicationEventContext
+ cancelled atomic.Bool
+}
+
+// Context returns the context attached to this application event.
+//
+// ctx := event.Context()
+func (e *ApplicationEvent) Context() *ApplicationEventContext {
+ return e.ctx
+}
+
+// Cancel prevents further processing of this application event.
+//
+// event.Cancel()
+func (e *ApplicationEvent) Cancel() {
+ e.cancelled.Store(true)
+}
+
+// IsCancelled reports whether Cancel has been called on this event.
+//
+// if event.IsCancelled() { return }
+func (e *ApplicationEvent) IsCancelled() bool {
+ return e.cancelled.Load()
+}
+
+// CustomEvent is a named application-level event carrying arbitrary data.
+//
+// manager.Emit("user:login", userPayload)
+type CustomEvent struct {
+ Name string `json:"name"`
+ Data any `json:"data"`
+ Sender string `json:"sender,omitempty"`
+ cancelled atomic.Bool
+}
+
+// Cancel prevents further processing of this custom event.
+//
+// event.Cancel()
+func (e *CustomEvent) Cancel() {
+ e.cancelled.Store(true)
+}
+
+// IsCancelled reports whether Cancel has been called on this event.
+//
+// if event.IsCancelled() { return }
+func (e *CustomEvent) IsCancelled() bool {
+ return e.cancelled.Load()
+}
+
+// customEventListener holds a callback and its remaining invocation count.
+type customEventListener struct {
+ callback func(*CustomEvent)
+ counter int
+}
+
+// applicationEventListener holds a callback for an application event.
+type applicationEventListener struct {
+ callback func(*ApplicationEvent)
+}
+
+// EventManager manages custom and application events in-memory.
+//
+// manager := &EventManager{}
+// cancel := manager.On("data:ready", func(e *CustomEvent) { process(e.Data) })
+// defer cancel()
+type EventManager struct {
+ mu sync.RWMutex
+ customListeners map[string][]*customEventListener
+ appListeners map[uint][]*applicationEventListener
+}
+
+func newEventManager() *EventManager {
+ return &EventManager{
+ customListeners: make(map[string][]*customEventListener),
+ appListeners: make(map[uint][]*applicationEventListener),
+ }
+}
+
+// Emit fires a named custom event with optional data to all registered listeners.
+// Returns true if the event was cancelled by a listener.
+//
+// cancelled := manager.Emit("file:saved", "/home/user/doc.txt")
+// if cancelled { log("event cancelled") }
+func (em *EventManager) Emit(name string, data ...any) bool {
+ event := &CustomEvent{Name: name}
+ switch len(data) {
+ case 0:
+ // no data
+ case 1:
+ event.Data = data[0]
+ default:
+ event.Data = data
+ }
+
+ em.mu.Lock()
+ listeners := append([]*customEventListener(nil), em.customListeners[name]...)
+ remaining := em.customListeners[name][:0]
+ for _, listener := range em.customListeners[name] {
+ if listener.counter < 0 {
+ remaining = append(remaining, listener)
+ } else {
+ listener.counter--
+ if listener.counter > 0 {
+ remaining = append(remaining, listener)
+ }
+ }
+ }
+ em.customListeners[name] = remaining
+ em.mu.Unlock()
+
+ for _, listener := range listeners {
+ if event.IsCancelled() {
+ break
+ }
+ listener.callback(event)
+ }
+ return event.IsCancelled()
+}
+
+// On registers a persistent listener for the named custom event.
+// Returns a cancellation function that removes the listener.
+//
+// cancel := manager.On("theme:changed", func(e *CustomEvent) { applyTheme(e.Data) })
+// defer cancel()
+func (em *EventManager) On(name string, callback func(*CustomEvent)) func() {
+ listener := &customEventListener{callback: callback, counter: -1}
+ em.mu.Lock()
+ em.customListeners[name] = append(em.customListeners[name], listener)
+ em.mu.Unlock()
+ return func() {
+ em.mu.Lock()
+ defer em.mu.Unlock()
+ updated := em.customListeners[name][:0]
+ for _, existing := range em.customListeners[name] {
+ if existing != listener {
+ updated = append(updated, existing)
+ }
+ }
+ em.customListeners[name] = updated
+ }
+}
+
+// Off removes all listeners for the named custom event.
+//
+// manager.Off("theme:changed")
+func (em *EventManager) Off(name string) {
+ em.mu.Lock()
+ delete(em.customListeners, name)
+ em.mu.Unlock()
+}
+
+// OnMultiple registers a listener for the named custom event that fires at most counter times.
+//
+// manager.OnMultiple("startup:phase", onPhase, 3)
+func (em *EventManager) OnMultiple(name string, callback func(*CustomEvent), counter int) {
+ listener := &customEventListener{callback: callback, counter: counter}
+ em.mu.Lock()
+ em.customListeners[name] = append(em.customListeners[name], listener)
+ em.mu.Unlock()
+}
+
+// OnApplicationEvent registers a listener for application-level events.
+// Returns a cancellation function that removes the listener.
+//
+// cancel := manager.OnApplicationEvent(events.Mac.ApplicationShouldTerminate, func(e *ApplicationEvent) {
+// saveState()
+// })
+// defer cancel()
+func (em *EventManager) OnApplicationEvent(eventType events.ApplicationEventType, callback func(*ApplicationEvent)) func() {
+ eventID := uint(eventType)
+ listener := &applicationEventListener{callback: callback}
+ em.mu.Lock()
+ em.appListeners[eventID] = append(em.appListeners[eventID], listener)
+ em.mu.Unlock()
+ return func() {
+ em.mu.Lock()
+ defer em.mu.Unlock()
+ updated := em.appListeners[eventID][:0]
+ for _, existing := range em.appListeners[eventID] {
+ if existing != listener {
+ updated = append(updated, existing)
+ }
+ }
+ em.appListeners[eventID] = updated
+ }
+}
diff --git a/stubs/wails/pkg/application/keybinding.go b/stubs/wails/pkg/application/keybinding.go
new file mode 100644
index 0000000..c190bf0
--- /dev/null
+++ b/stubs/wails/pkg/application/keybinding.go
@@ -0,0 +1,71 @@
+package application
+
+import "sync"
+
+// KeyBinding pairs an accelerator string with its registered callback.
+//
+// binding := &KeyBinding{Accelerator: "CmdOrCtrl+K", Callback: handler}
+type KeyBinding struct {
+ Accelerator string
+ Callback func(window Window)
+}
+
+// KeyBindingManager stores and dispatches global key bindings.
+//
+// manager.Add("CmdOrCtrl+K", func(w Window) { w.Focus() })
+// handled := manager.Process("CmdOrCtrl+K", currentWindow)
+type KeyBindingManager struct {
+ mu sync.RWMutex
+ bindings map[string]func(window Window)
+}
+
+// Add registers a callback for the given accelerator string.
+//
+// manager.Add("CmdOrCtrl+Shift+P", func(w Window) { launchCommandPalette(w) })
+func (m *KeyBindingManager) Add(accelerator string, callback func(window Window)) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ if m.bindings == nil {
+ m.bindings = make(map[string]func(window Window))
+ }
+ m.bindings[accelerator] = callback
+}
+
+// Remove deregisters the callback for the given accelerator string.
+//
+// manager.Remove("CmdOrCtrl+Shift+P")
+func (m *KeyBindingManager) Remove(accelerator string) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ delete(m.bindings, accelerator)
+}
+
+// Process fires the callback for the given accelerator and returns true if handled.
+//
+// if manager.Process("CmdOrCtrl+K", window) { return }
+func (m *KeyBindingManager) Process(accelerator string, window Window) bool {
+ m.mu.RLock()
+ callback, exists := m.bindings[accelerator]
+ m.mu.RUnlock()
+ if exists && callback != nil {
+ callback(window)
+ return true
+ }
+ return false
+}
+
+// GetAll returns a snapshot of all registered key bindings.
+//
+// for _, kb := range manager.GetAll() { log(kb.Accelerator) }
+func (m *KeyBindingManager) GetAll() []*KeyBinding {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ bindings := make([]*KeyBinding, 0, len(m.bindings))
+ for accelerator, callback := range m.bindings {
+ bindings = append(bindings, &KeyBinding{
+ Accelerator: accelerator,
+ Callback: callback,
+ })
+ }
+ return bindings
+}
diff --git a/stubs/wails/pkg/application/menuitem.go b/stubs/wails/pkg/application/menuitem.go
new file mode 100644
index 0000000..4c60f16
--- /dev/null
+++ b/stubs/wails/pkg/application/menuitem.go
@@ -0,0 +1,304 @@
+package application
+
+// Role identifies a platform-specific menu role.
+// It is the same underlying type as MenuRole so existing constants (AppMenu,
+// FileMenu, EditMenu, ViewMenu, WindowMenu, HelpMenu) are valid Role values.
+//
+// quitItem := application.NewRole(application.Quit)
+type Role = MenuRole
+
+const (
+ // NoRole indicates no special platform role.
+ NoRole MenuRole = iota + 100
+
+ // ServicesMenu is the macOS Services sub-menu.
+ ServicesMenu
+
+ // SpeechMenu is the macOS Speech sub-menu.
+ SpeechMenu
+
+ // Hide hides the current application.
+ Hide
+
+ // HideOthers hides all other applications.
+ HideOthers
+
+ // UnHide shows all hidden applications.
+ UnHide
+
+ // Front brings all windows to front.
+ Front
+
+ // Undo triggers the standard Undo action.
+ Undo
+
+ // Redo triggers the standard Redo action.
+ Redo
+
+ // Cut triggers the standard Cut action.
+ Cut
+
+ // Copy triggers the standard Copy action.
+ Copy
+
+ // Paste triggers the standard Paste action.
+ Paste
+
+ // PasteAndMatchStyle pastes without source formatting.
+ PasteAndMatchStyle
+
+ // SelectAll triggers the standard Select All action.
+ SelectAll
+
+ // Delete triggers the standard Delete action.
+ Delete
+
+ // Quit quits the application.
+ Quit
+
+ // CloseWindow closes the focused window.
+ CloseWindow
+
+ // About opens the About panel.
+ About
+
+ // Reload reloads the current webview.
+ Reload
+
+ // ForceReload force-reloads the current webview.
+ ForceReload
+
+ // ToggleFullscreen toggles fullscreen mode.
+ ToggleFullscreen
+
+ // OpenDevTools opens the developer tools panel.
+ OpenDevTools
+
+ // ResetZoom resets the webview zoom level.
+ ResetZoom
+
+ // ZoomIn increases the webview zoom level.
+ ZoomIn
+
+ // ZoomOut decreases the webview zoom level.
+ ZoomOut
+
+ // Minimise minimises the focused window.
+ Minimise
+
+ // Zoom zooms the focused window (macOS).
+ Zoom
+
+ // FullScreen enters fullscreen (macOS).
+ FullScreen
+
+ // Print opens the print dialog.
+ Print
+
+ // PageLayout opens the page layout dialog.
+ PageLayout
+
+ // ShowAll shows all windows.
+ ShowAll
+
+ // BringAllToFront brings all windows to front.
+ BringAllToFront
+
+ // NewFile triggers the New File action.
+ NewFile
+
+ // Open triggers the Open action.
+ Open
+
+ // Save triggers the Save action.
+ Save
+
+ // SaveAs triggers the Save As action.
+ SaveAs
+
+ // StartSpeaking starts text-to-speech on selected text.
+ StartSpeaking
+
+ // StopSpeaking stops text-to-speech.
+ StopSpeaking
+
+ // Revert triggers the Revert action.
+ Revert
+
+ // Find triggers the Find action.
+ Find
+
+ // FindAndReplace triggers the Find and Replace action.
+ FindAndReplace
+
+ // FindNext finds the next match.
+ FindNext
+
+ // FindPrevious finds the previous match.
+ FindPrevious
+
+ // Help opens the application help.
+ Help
+)
+
+// NewMenuItem creates a new text menu item with the given label.
+//
+// item := application.NewMenuItem("Open File").SetAccelerator("CmdOrCtrl+O")
+func NewMenuItem(label string) *MenuItem {
+ return &MenuItem{Label: label, Enabled: true}
+}
+
+// NewMenuItemSeparator creates a horizontal separator for use in menus.
+//
+// menu.Items = append(menu.Items, application.NewMenuItemSeparator())
+func NewMenuItemSeparator() *MenuItem {
+ return &MenuItem{Label: "---"}
+}
+
+// NewMenuItemCheckbox creates a checkable menu item.
+//
+// item := application.NewMenuItemCheckbox("Show Toolbar", true)
+func NewMenuItemCheckbox(label string, checked bool) *MenuItem {
+ return &MenuItem{Label: label, Checked: checked, Enabled: true}
+}
+
+// NewMenuItemRadio creates a radio-group menu item.
+//
+// item := application.NewMenuItemRadio("Small", false)
+func NewMenuItemRadio(label string, checked bool) *MenuItem {
+ return &MenuItem{Label: label, Checked: checked, Enabled: true}
+}
+
+// NewSubMenuItem creates a menu item that opens a sub-menu.
+//
+// sub := application.NewSubMenuItem("Recent Files")
+func NewSubMenuItem(label string) *MenuItem {
+ return &MenuItem{Label: label, Enabled: true}
+}
+
+// NewRole creates a menu item pre-configured for a platform role.
+//
+// quitItem := application.NewRole(application.Quit)
+func NewRole(role Role) *MenuItem {
+ return &MenuItem{Label: roleLabel(role), Enabled: true}
+}
+
+// NewServicesMenu creates the macOS Services sub-menu item.
+//
+// servicesMenu := application.NewServicesMenu()
+func NewServicesMenu() *MenuItem {
+ return NewSubMenuItem("Services")
+}
+
+// GetAccelerator returns the accelerator string currently set on the item.
+//
+// accel := item.GetAccelerator() // e.g. "CmdOrCtrl+S"
+func (mi *MenuItem) GetAccelerator() string {
+ return mi.Accelerator
+}
+
+// roleLabel maps a Role constant to a human-readable label.
+func roleLabel(role Role) string {
+ switch role {
+ case AppMenu:
+ return "App"
+ case EditMenu:
+ return "Edit"
+ case FileMenu:
+ return "File"
+ case ViewMenu:
+ return "View"
+ case ServicesMenu:
+ return "Services"
+ case SpeechMenu:
+ return "Speech"
+ case WindowMenu:
+ return "Window"
+ case HelpMenu:
+ return "Help"
+ case Hide:
+ return "Hide"
+ case HideOthers:
+ return "Hide Others"
+ case UnHide:
+ return "Show All"
+ case Front:
+ return "Bring All to Front"
+ case Undo:
+ return "Undo"
+ case Redo:
+ return "Redo"
+ case Cut:
+ return "Cut"
+ case Copy:
+ return "Copy"
+ case Paste:
+ return "Paste"
+ case PasteAndMatchStyle:
+ return "Paste and Match Style"
+ case SelectAll:
+ return "Select All"
+ case Delete:
+ return "Delete"
+ case Quit:
+ return "Quit"
+ case CloseWindow:
+ return "Close Window"
+ case About:
+ return "About"
+ case Reload:
+ return "Reload"
+ case ForceReload:
+ return "Force Reload"
+ case ToggleFullscreen:
+ return "Toggle Full Screen"
+ case OpenDevTools:
+ return "Open Developer Tools"
+ case ResetZoom:
+ return "Reset Zoom"
+ case ZoomIn:
+ return "Zoom In"
+ case ZoomOut:
+ return "Zoom Out"
+ case Minimise:
+ return "Minimise"
+ case Zoom:
+ return "Zoom"
+ case FullScreen:
+ return "Full Screen"
+ case Print:
+ return "Print"
+ case PageLayout:
+ return "Page Layout"
+ case ShowAll:
+ return "Show All"
+ case BringAllToFront:
+ return "Bring All to Front"
+ case NewFile:
+ return "New"
+ case Open:
+ return "Open"
+ case Save:
+ return "Save"
+ case SaveAs:
+ return "Save As"
+ case StartSpeaking:
+ return "Start Speaking"
+ case StopSpeaking:
+ return "Stop Speaking"
+ case Revert:
+ return "Revert"
+ case Find:
+ return "Find"
+ case FindAndReplace:
+ return "Find and Replace"
+ case FindNext:
+ return "Find Next"
+ case FindPrevious:
+ return "Find Previous"
+ case Help:
+ return "Help"
+ default:
+ return ""
+ }
+}
diff --git a/stubs/wails/pkg/application/screen.go b/stubs/wails/pkg/application/screen.go
new file mode 100644
index 0000000..6bf8d7b
--- /dev/null
+++ b/stubs/wails/pkg/application/screen.go
@@ -0,0 +1,146 @@
+package application
+
+import "sync"
+
+// Screen describes a physical or logical display.
+//
+// primary := manager.GetPrimary()
+// if primary != nil { useSize(primary.Size) }
+type Screen struct {
+ ID string // A unique identifier for the display
+ Name string // The name of the display
+ ScaleFactor float32 // The scale factor of the display (DPI/96)
+ X int // The x-coordinate of the top-left corner of the display
+ Y int // The y-coordinate of the top-left corner of the display
+ Size Size // The logical size of the display
+ Bounds Rect // The logical bounds of the display
+ PhysicalBounds Rect // The physical bounds before scaling
+ WorkArea Rect // The work area (excluding taskbars etc.)
+ PhysicalWorkArea Rect // The physical work area before scaling
+ IsPrimary bool // Whether this is the primary display
+ Rotation float32 // The rotation of the display in degrees
+}
+
+// Rect is an axis-aligned rectangle in either logical or physical pixels.
+//
+// if rect.Contains(Point{X: 100, Y: 200}) { ... }
+type Rect struct {
+ X int
+ Y int
+ Width int
+ Height int
+}
+
+// Point is a two-dimensional coordinate.
+//
+// centre := Point{X: bounds.X + bounds.Width/2, Y: bounds.Y + bounds.Height/2}
+type Point struct {
+ X int
+ Y int
+}
+
+// Size holds the width and height dimensions of a display or region.
+//
+// if size.Width > 1920 { useHiResLayout() }
+type Size struct {
+ Width int
+ Height int
+}
+
+// Origin returns the top-left corner of the rectangle.
+func (r Rect) Origin() Point {
+ return Point{X: r.X, Y: r.Y}
+}
+
+// Corner returns the exclusive bottom-right corner (X+Width, Y+Height).
+func (r Rect) Corner() Point {
+ return Point{X: r.X + r.Width, Y: r.Y + r.Height}
+}
+
+// IsEmpty reports whether the rectangle has non-positive area.
+func (r Rect) IsEmpty() bool {
+ return r.Width <= 0 || r.Height <= 0
+}
+
+// Contains reports whether point pt lies within the rectangle.
+//
+// if bounds.Contains(cursorPoint) { highlightWindow() }
+func (r Rect) Contains(pt Point) bool {
+ return pt.X >= r.X && pt.X < r.X+r.Width && pt.Y >= r.Y && pt.Y < r.Y+r.Height
+}
+
+// RectSize returns the dimensions of the rectangle as a Size value.
+func (r Rect) RectSize() Size {
+ return Size{Width: r.Width, Height: r.Height}
+}
+
+// ScreenManager tracks connected screens and the active screen.
+//
+// manager.SetScreens(detectedScreens)
+// primary := manager.GetPrimary()
+type ScreenManager struct {
+ mu sync.RWMutex
+ screens []*Screen
+ current *Screen
+ primary *Screen
+}
+
+// SetScreens replaces the full list of known screens and recomputes primary.
+//
+// manager.SetScreens(platformDetectedScreens)
+func (m *ScreenManager) SetScreens(screens []*Screen) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ m.screens = screens
+ m.primary = nil
+ for _, screen := range screens {
+ if screen.IsPrimary {
+ m.primary = screen
+ break
+ }
+ }
+ if m.current == nil && m.primary != nil {
+ m.current = m.primary
+ }
+}
+
+// SetCurrent marks the given screen as the currently active one.
+//
+// manager.SetCurrent(screenUnderPointer)
+func (m *ScreenManager) SetCurrent(screen *Screen) {
+ m.mu.Lock()
+ m.current = screen
+ m.mu.Unlock()
+}
+
+// GetAll returns all registered screens.
+//
+// for _, s := range manager.GetAll() { renderMonitorPreview(s) }
+func (m *ScreenManager) GetAll() []*Screen {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ out := make([]*Screen, len(m.screens))
+ copy(out, m.screens)
+ return out
+}
+
+// GetPrimary returns the primary screen, or nil if none has been registered.
+//
+// primary := manager.GetPrimary()
+func (m *ScreenManager) GetPrimary() *Screen {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ return m.primary
+}
+
+// GetCurrent returns the most recently active screen, or the primary if unset.
+//
+// current := manager.GetCurrent()
+func (m *ScreenManager) GetCurrent() *Screen {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ if m.current != nil {
+ return m.current
+ }
+ return m.primary
+}
diff --git a/stubs/wails/pkg/application/services.go b/stubs/wails/pkg/application/services.go
new file mode 100644
index 0000000..e4b3f57
--- /dev/null
+++ b/stubs/wails/pkg/application/services.go
@@ -0,0 +1,105 @@
+package application
+
+import (
+ "context"
+ "reflect"
+)
+
+// ServiceOptions provides optional parameters when constructing a Service.
+//
+// svc := NewServiceWithOptions(&myImpl, ServiceOptions{Name: "MyService", Route: "/api"})
+type ServiceOptions struct {
+ // Name overrides the service name used for logging and debugging.
+ // When empty the name is derived from the ServiceName interface or the type name.
+ Name string
+
+ // Route mounts the service on the internal asset server at this prefix
+ // if the service instance implements http.Handler.
+ Route string
+
+ // MarshalError serialises error values returned by service methods to JSON.
+ // A nil return falls back to the globally configured error handler.
+ MarshalError func(error) []byte
+}
+
+// DefaultServiceOptions holds the default values used when no ServiceOptions
+// are passed to NewService.
+var DefaultServiceOptions = ServiceOptions{}
+
+// Service wraps a bound type instance for registration with the application.
+// The zero value is invalid; obtain valid values via NewService or NewServiceWithOptions.
+//
+// svc := NewService(&myStruct)
+// app.RegisterService(svc)
+type Service struct {
+ instance any
+ options ServiceOptions
+}
+
+// NewService wraps instance in a Service using DefaultServiceOptions.
+//
+// svc := NewService(&MyController{})
+func NewService[T any](instance *T) Service {
+ return Service{instance: instance, options: DefaultServiceOptions}
+}
+
+// NewServiceWithOptions wraps instance in a Service with explicit options.
+//
+// svc := NewServiceWithOptions(&MyController{}, ServiceOptions{Name: "ctrl", Route: "/ctrl"})
+func NewServiceWithOptions[T any](instance *T, options ServiceOptions) Service {
+ service := NewService(instance)
+ service.options = options
+ return service
+}
+
+// Instance returns the underlying pointer originally passed to NewService.
+//
+// ctrl := svc.Instance().(*MyController)
+func (s Service) Instance() any {
+ return s.instance
+}
+
+// Options returns the ServiceOptions associated with this service.
+func (s Service) Options() ServiceOptions {
+ return s.options
+}
+
+// ServiceName is an optional interface that service instances may implement
+// to provide a human-readable name for logging and debugging.
+//
+// func (s *MyService) ServiceName() string { return "MyService" }
+type ServiceName interface {
+ ServiceName() string
+}
+
+// ServiceStartup is an optional interface for service initialisation.
+// Called during application startup in registration order.
+// A non-nil return aborts startup and surfaces the error to the caller.
+//
+// func (s *MyService) ServiceStartup(ctx context.Context, opts ServiceOptions) error {
+// return s.connect(ctx)
+// }
+type ServiceStartup interface {
+ ServiceStartup(ctx context.Context, options ServiceOptions) error
+}
+
+// ServiceShutdown is an optional interface for service cleanup.
+// Called during application shutdown in reverse registration order,
+// after all user-provided shutdown hooks have run.
+//
+// func (s *MyService) ServiceShutdown() error { return s.db.Close() }
+type ServiceShutdown interface {
+ ServiceShutdown() error
+}
+
+// getServiceName resolves the display name for a service using, in order:
+// the explicit options name, the ServiceName interface, and the reflect type name.
+func getServiceName(service Service) string {
+ if service.options.Name != "" {
+ return service.options.Name
+ }
+ if named, ok := service.Instance().(ServiceName); ok {
+ return named.ServiceName()
+ }
+ return reflect.TypeOf(service.Instance()).Elem().String()
+}
diff --git a/stubs/wails/pkg/application/webview_window_options.go b/stubs/wails/pkg/application/webview_window_options.go
new file mode 100644
index 0000000..a8b48bb
--- /dev/null
+++ b/stubs/wails/pkg/application/webview_window_options.go
@@ -0,0 +1,574 @@
+package application
+
+import "github.com/wailsapp/wails/v3/pkg/events"
+
+// WindowState represents the visible state of a window.
+//
+// opts := application.WebviewWindowOptions{StartState: application.WindowStateMaximised}
+type WindowState int
+
+const (
+ // WindowStateNormal is the default windowed state.
+ WindowStateNormal WindowState = iota
+ // WindowStateMinimised is the minimised (iconified) state.
+ WindowStateMinimised
+ // WindowStateMaximised fills the available work area.
+ WindowStateMaximised
+ // WindowStateFullscreen occupies the full screen.
+ WindowStateFullscreen
+)
+
+// WindowStartPosition controls where a window first appears.
+//
+// opts := application.WebviewWindowOptions{InitialPosition: application.WindowCentered}
+type WindowStartPosition int
+
+const (
+ // WindowCentered places the window at the centre of the screen.
+ WindowCentered WindowStartPosition = 0
+ // WindowXY places the window at the coordinates given by X and Y.
+ WindowXY WindowStartPosition = 1
+)
+
+// BackgroundType determines how the window background is rendered.
+//
+// opts := application.WebviewWindowOptions{BackgroundType: application.BackgroundTypeTranslucent}
+type BackgroundType int
+
+const (
+ // BackgroundTypeSolid renders a solid opaque background.
+ BackgroundTypeSolid BackgroundType = iota
+ // BackgroundTypeTransparent renders a fully transparent background.
+ BackgroundTypeTransparent
+ // BackgroundTypeTranslucent renders a frosted/blur translucent background.
+ BackgroundTypeTranslucent
+)
+
+// NewRGB constructs an opaque RGBA value from red, green, blue components.
+//
+// colour := application.NewRGB(0xff, 0x00, 0x00) // red
+func NewRGB(red, green, blue uint8) RGBA {
+ return RGBA{Red: red, Green: green, Blue: blue, Alpha: 255}
+}
+
+// NewRGBPtr encodes red, green, blue as a packed *uint32 in 0x00BBGGRR order.
+//
+// ptr := application.NewRGBPtr(0xff, 0x80, 0x00)
+func NewRGBPtr(red, green, blue uint8) *uint32 {
+ value := uint32(red) | uint32(green)<<8 | uint32(blue)<<16
+ return &value
+}
+
+/******* Windows Options *******/
+
+// BackdropType selects the translucent backdrop style on Windows 11.
+//
+// opts.Windows = application.WindowsWindow{BackdropType: application.Mica}
+type BackdropType int32
+
+const (
+ // Auto lets the system choose the best backdrop.
+ Auto BackdropType = 0
+ // None disables the translucent backdrop.
+ None BackdropType = 1
+ // Mica applies the Mica material (Windows 11 22H2+).
+ Mica BackdropType = 2
+ // Acrylic applies the Acrylic blur-behind material.
+ Acrylic BackdropType = 3
+ // Tabbed applies the Tabbed/MICA-Alt material.
+ Tabbed BackdropType = 4
+)
+
+// CoreWebView2PermissionKind enumerates the types of WebView2 permissions.
+type CoreWebView2PermissionKind uint32
+
+const (
+ CoreWebView2PermissionKindUnknownPermission CoreWebView2PermissionKind = iota
+ CoreWebView2PermissionKindMicrophone
+ CoreWebView2PermissionKindCamera
+ CoreWebView2PermissionKindGeolocation
+ CoreWebView2PermissionKindNotifications
+ CoreWebView2PermissionKindOtherSensors
+ CoreWebView2PermissionKindClipboardRead
+)
+
+// CoreWebView2PermissionState enumerates the allowed states for a WebView2 permission.
+type CoreWebView2PermissionState uint32
+
+const (
+ CoreWebView2PermissionStateDefault CoreWebView2PermissionState = iota
+ CoreWebView2PermissionStateAllow
+ CoreWebView2PermissionStateDeny
+)
+
+// Theme selects between the system default, dark, and light UI themes on Windows.
+//
+// opts.Windows = application.WindowsWindow{Theme: application.Dark}
+type Theme int
+
+const (
+ // SystemDefault follows the OS theme and reacts to changes.
+ SystemDefault Theme = 0
+ // Dark forces the dark theme.
+ Dark Theme = 1
+ // Light forces the light theme.
+ Light Theme = 2
+)
+
+// WindowTheme defines colour overrides for a single window activity state.
+//
+// wt := &application.WindowTheme{TitleBarColour: application.NewRGBPtr(0x1e, 0x1e, 0x1e)}
+type WindowTheme struct {
+ // BorderColour is the colour of the window border (0x00BBGGRR).
+ BorderColour *uint32
+ // TitleBarColour is the colour of the title bar (0x00BBGGRR).
+ TitleBarColour *uint32
+ // TitleTextColour is the colour of the title text (0x00BBGGRR).
+ TitleTextColour *uint32
+}
+
+// TextTheme defines foreground and background colours for a text element.
+type TextTheme struct {
+ // Text is the foreground colour.
+ Text *uint32
+ // Background is the background colour.
+ Background *uint32
+}
+
+// MenuBarTheme defines colours for a menu bar in default, hovered, and selected states.
+type MenuBarTheme struct {
+ // Default is the theme used when the item is neither hovered nor selected.
+ Default *TextTheme
+ // Hover is the theme used when the pointer is over the item.
+ Hover *TextTheme
+ // Selected is the theme used when the item is selected.
+ Selected *TextTheme
+}
+
+// ThemeSettings defines custom colours used in dark or light mode.
+// Colour values use packed 0x00BBGGRR encoding — use NewRGBPtr to construct them.
+//
+// ts := application.ThemeSettings{
+// DarkModeActive: &application.WindowTheme{TitleBarColour: application.NewRGBPtr(0x1e, 0x1e, 0x2e)},
+// }
+type ThemeSettings struct {
+ // DarkModeActive applies when the window is active in dark mode.
+ DarkModeActive *WindowTheme
+ // DarkModeInactive applies when the window is inactive in dark mode.
+ DarkModeInactive *WindowTheme
+ // LightModeActive applies when the window is active in light mode.
+ LightModeActive *WindowTheme
+ // LightModeInactive applies when the window is inactive in light mode.
+ LightModeInactive *WindowTheme
+ // DarkModeMenuBar applies to the menu bar in dark mode.
+ DarkModeMenuBar *MenuBarTheme
+ // LightModeMenuBar applies to the menu bar in light mode.
+ LightModeMenuBar *MenuBarTheme
+}
+
+// WindowsWindow contains Windows-specific window configuration.
+//
+// opts.Windows = application.WindowsWindow{BackdropType: application.Mica, Theme: application.Dark}
+type WindowsWindow struct {
+ // BackdropType selects the translucent material. Requires Windows 11 22621+.
+ // Only used when BackgroundType is BackgroundTypeTranslucent.
+ // Default: Auto
+ BackdropType BackdropType
+
+ // DisableIcon removes the application icon from the title bar.
+ // Default: false
+ DisableIcon bool
+
+ // Theme selects between dark, light, or system-default title bar styling.
+ // Default: SystemDefault
+ Theme Theme
+
+ // CustomTheme overrides colours for dark/light active/inactive states.
+ // Default: zero value (no override)
+ CustomTheme ThemeSettings
+
+ // DisableFramelessWindowDecorations suppresses Aero shadow and rounded corners
+ // when the window is frameless. Rounded corners require Windows 11.
+ // Default: false
+ DisableFramelessWindowDecorations bool
+
+ // WindowMask sets the window shape via a PNG with an alpha channel.
+ // Default: nil
+ WindowMask []byte
+
+ // WindowMaskDraggable allows the window to be dragged via the mask area.
+ // Default: false
+ WindowMaskDraggable bool
+
+ // ResizeDebounceMS debounces WebView2 redraws during resize.
+ // Default: 0
+ ResizeDebounceMS uint16
+
+ // WindowDidMoveDebounceMS debounces the WindowDidMove event.
+ // Default: 0
+ WindowDidMoveDebounceMS uint16
+
+ // EventMapping translates platform window events to common event types.
+ // Default: nil
+ EventMapping map[events.WindowEventType]events.WindowEventType
+
+ // HiddenOnTaskbar excludes the window from the taskbar.
+ // Default: false
+ HiddenOnTaskbar bool
+
+ // EnableSwipeGestures enables horizontal swipe gestures.
+ // Default: false
+ EnableSwipeGestures bool
+
+ // Menu is the window-level menu.
+ Menu *Menu
+
+ // Permissions configures WebView2 permission grants.
+ // Default: nil (system defaults apply)
+ Permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState
+
+ // ExStyle is the extended window style flags (WS_EX_*).
+ ExStyle int
+
+ // GeneralAutofillEnabled enables general autofill in WebView2.
+ GeneralAutofillEnabled bool
+
+ // PasswordAutosaveEnabled enables password autosave in WebView2.
+ PasswordAutosaveEnabled bool
+}
+
+/****** Mac Options *******/
+
+// MacBackdrop controls the translucency of the macOS window background.
+//
+// opts.Mac = application.MacWindow{Backdrop: application.MacBackdropTranslucent}
+type MacBackdrop int
+
+const (
+ // MacBackdropNormal renders a standard opaque background.
+ MacBackdropNormal MacBackdrop = iota
+ // MacBackdropTransparent renders a fully transparent background.
+ MacBackdropTransparent
+ // MacBackdropTranslucent renders a frosted vibrancy background.
+ MacBackdropTranslucent
+ // MacBackdropLiquidGlass applies Apple's Liquid Glass effect (macOS 15+,
+ // falls back to translucent on earlier releases).
+ MacBackdropLiquidGlass
+)
+
+// MacToolbarStyle controls the toolbar layout relative to the title bar.
+//
+// opts.Mac.TitleBar.ToolbarStyle = application.MacToolbarStyleUnified
+type MacToolbarStyle int
+
+const (
+ // MacToolbarStyleAutomatic lets the system decide based on configuration.
+ MacToolbarStyleAutomatic MacToolbarStyle = iota
+ // MacToolbarStyleExpanded shows the toolbar below the title bar.
+ MacToolbarStyleExpanded
+ // MacToolbarStylePreference shows the toolbar below the title bar with
+ // equal-width items where possible.
+ MacToolbarStylePreference
+ // MacToolbarStyleUnified merges the title bar and toolbar into one row.
+ MacToolbarStyleUnified
+ // MacToolbarStyleUnifiedCompact is like Unified but with reduced margins.
+ MacToolbarStyleUnifiedCompact
+)
+
+// MacLiquidGlassStyle defines the appearance of the Liquid Glass effect.
+type MacLiquidGlassStyle int
+
+const (
+ // LiquidGlassStyleAutomatic lets the system choose the best style.
+ LiquidGlassStyleAutomatic MacLiquidGlassStyle = iota
+ // LiquidGlassStyleLight uses a light glass appearance.
+ LiquidGlassStyleLight
+ // LiquidGlassStyleDark uses a dark glass appearance.
+ LiquidGlassStyleDark
+ // LiquidGlassStyleVibrant uses an enhanced vibrant glass appearance.
+ LiquidGlassStyleVibrant
+)
+
+// NSVisualEffectMaterial mirrors NSVisualEffectMaterial from the macOS SDK.
+type NSVisualEffectMaterial int
+
+const (
+ NSVisualEffectMaterialAppearanceBased NSVisualEffectMaterial = 0
+ NSVisualEffectMaterialLight NSVisualEffectMaterial = 1
+ NSVisualEffectMaterialDark NSVisualEffectMaterial = 2
+ NSVisualEffectMaterialTitlebar NSVisualEffectMaterial = 3
+ NSVisualEffectMaterialSelection NSVisualEffectMaterial = 4
+ NSVisualEffectMaterialMenu NSVisualEffectMaterial = 5
+ NSVisualEffectMaterialPopover NSVisualEffectMaterial = 6
+ NSVisualEffectMaterialSidebar NSVisualEffectMaterial = 7
+ NSVisualEffectMaterialHeaderView NSVisualEffectMaterial = 10
+ NSVisualEffectMaterialSheet NSVisualEffectMaterial = 11
+ NSVisualEffectMaterialWindowBackground NSVisualEffectMaterial = 12
+ NSVisualEffectMaterialHUDWindow NSVisualEffectMaterial = 13
+ NSVisualEffectMaterialFullScreenUI NSVisualEffectMaterial = 15
+ NSVisualEffectMaterialToolTip NSVisualEffectMaterial = 17
+ NSVisualEffectMaterialContentBackground NSVisualEffectMaterial = 18
+ NSVisualEffectMaterialUnderWindowBackground NSVisualEffectMaterial = 21
+ NSVisualEffectMaterialUnderPageBackground NSVisualEffectMaterial = 22
+ // NSVisualEffectMaterialAuto selects the material automatically based on Style.
+ NSVisualEffectMaterialAuto NSVisualEffectMaterial = -1
+)
+
+// MacLiquidGlass configures the Liquid Glass visual effect (macOS 15+).
+//
+// opts.Mac.LiquidGlass = application.MacLiquidGlass{Style: application.LiquidGlassStyleDark}
+type MacLiquidGlass struct {
+ // Style of the glass effect.
+ Style MacLiquidGlassStyle
+
+ // Material for the NSVisualEffectView fallback.
+ // Use NSVisualEffectMaterialAuto for automatic selection based on Style.
+ Material NSVisualEffectMaterial
+
+ // CornerRadius specifies the corner radius in points (0 for square corners).
+ CornerRadius float64
+
+ // TintColor adds an optional colour tint to the glass (nil for no tint).
+ TintColor *RGBA
+
+ // GroupID merges multiple glass windows into a single visual group.
+ GroupID string
+
+ // GroupSpacing is the spacing between grouped glass elements in points.
+ GroupSpacing float64
+}
+
+// MacAppearanceType selects a Cocoa NSAppearance for the window.
+//
+// opts.Mac = application.MacWindow{Appearance: application.NSAppearanceNameDarkAqua}
+type MacAppearanceType string
+
+const (
+ // DefaultAppearance follows the system setting.
+ DefaultAppearance MacAppearanceType = ""
+ // NSAppearanceNameAqua is the standard light system appearance.
+ NSAppearanceNameAqua MacAppearanceType = "NSAppearanceNameAqua"
+ // NSAppearanceNameDarkAqua is the standard dark system appearance.
+ NSAppearanceNameDarkAqua MacAppearanceType = "NSAppearanceNameDarkAqua"
+ // NSAppearanceNameVibrantLight is the light vibrant appearance.
+ NSAppearanceNameVibrantLight MacAppearanceType = "NSAppearanceNameVibrantLight"
+ // NSAppearanceNameAccessibilityHighContrastAqua is high-contrast light.
+ NSAppearanceNameAccessibilityHighContrastAqua MacAppearanceType = "NSAppearanceNameAccessibilityHighContrastAqua"
+ // NSAppearanceNameAccessibilityHighContrastDarkAqua is high-contrast dark.
+ NSAppearanceNameAccessibilityHighContrastDarkAqua MacAppearanceType = "NSAppearanceNameAccessibilityHighContrastDarkAqua"
+ // NSAppearanceNameAccessibilityHighContrastVibrantLight is high-contrast light vibrant.
+ NSAppearanceNameAccessibilityHighContrastVibrantLight MacAppearanceType = "NSAppearanceNameAccessibilityHighContrastVibrantLight"
+ // NSAppearanceNameAccessibilityHighContrastVibrantDark is high-contrast dark vibrant.
+ NSAppearanceNameAccessibilityHighContrastVibrantDark MacAppearanceType = "NSAppearanceNameAccessibilityHighContrastVibrantDark"
+)
+
+// MacWindowLevel controls the z-order stacking group of the window.
+//
+// opts.Mac = application.MacWindow{WindowLevel: application.MacWindowLevelFloating}
+type MacWindowLevel string
+
+const (
+ MacWindowLevelNormal MacWindowLevel = "normal"
+ MacWindowLevelFloating MacWindowLevel = "floating"
+ MacWindowLevelTornOffMenu MacWindowLevel = "tornOffMenu"
+ MacWindowLevelModalPanel MacWindowLevel = "modalPanel"
+ MacWindowLevelMainMenu MacWindowLevel = "mainMenu"
+ MacWindowLevelStatus MacWindowLevel = "status"
+ MacWindowLevelPopUpMenu MacWindowLevel = "popUpMenu"
+ MacWindowLevelScreenSaver MacWindowLevel = "screenSaver"
+)
+
+// MacWindowCollectionBehavior controls how the window participates in macOS
+// Spaces and fullscreen. Values correspond to NSWindowCollectionBehavior bits
+// and may be combined with bitwise OR.
+//
+// opts.Mac.CollectionBehavior = application.MacWindowCollectionBehaviorCanJoinAllSpaces |
+// application.MacWindowCollectionBehaviorFullScreenAuxiliary
+type MacWindowCollectionBehavior int
+
+const (
+ // MacWindowCollectionBehaviorDefault uses FullScreenPrimary for backwards compatibility.
+ MacWindowCollectionBehaviorDefault MacWindowCollectionBehavior = 0
+ // MacWindowCollectionBehaviorCanJoinAllSpaces shows the window on all Spaces.
+ MacWindowCollectionBehaviorCanJoinAllSpaces MacWindowCollectionBehavior = 1 << 0
+ // MacWindowCollectionBehaviorMoveToActiveSpace moves the window to the active Space when shown.
+ MacWindowCollectionBehaviorMoveToActiveSpace MacWindowCollectionBehavior = 1 << 1
+ // MacWindowCollectionBehaviorManaged is the default managed window behaviour.
+ MacWindowCollectionBehaviorManaged MacWindowCollectionBehavior = 1 << 2
+ // MacWindowCollectionBehaviorTransient marks the window as temporary.
+ MacWindowCollectionBehaviorTransient MacWindowCollectionBehavior = 1 << 3
+ // MacWindowCollectionBehaviorStationary keeps the window stationary during Space switches.
+ MacWindowCollectionBehaviorStationary MacWindowCollectionBehavior = 1 << 4
+ // MacWindowCollectionBehaviorParticipatesInCycle includes the window in Cmd+` cycling.
+ MacWindowCollectionBehaviorParticipatesInCycle MacWindowCollectionBehavior = 1 << 5
+ // MacWindowCollectionBehaviorIgnoresCycle excludes the window from Cmd+` cycling.
+ MacWindowCollectionBehaviorIgnoresCycle MacWindowCollectionBehavior = 1 << 6
+ // MacWindowCollectionBehaviorFullScreenPrimary allows the window to enter fullscreen.
+ MacWindowCollectionBehaviorFullScreenPrimary MacWindowCollectionBehavior = 1 << 7
+ // MacWindowCollectionBehaviorFullScreenAuxiliary allows the window to overlay fullscreen apps.
+ MacWindowCollectionBehaviorFullScreenAuxiliary MacWindowCollectionBehavior = 1 << 8
+ // MacWindowCollectionBehaviorFullScreenNone prevents the window from entering fullscreen (10.7+).
+ MacWindowCollectionBehaviorFullScreenNone MacWindowCollectionBehavior = 1 << 9
+ // MacWindowCollectionBehaviorFullScreenAllowsTiling allows side-by-side tiling (10.11+).
+ MacWindowCollectionBehaviorFullScreenAllowsTiling MacWindowCollectionBehavior = 1 << 11
+ // MacWindowCollectionBehaviorFullScreenDisallowsTiling prevents tiling in fullscreen (10.11+).
+ MacWindowCollectionBehaviorFullScreenDisallowsTiling MacWindowCollectionBehavior = 1 << 12
+)
+
+// MacWebviewPreferences configures Safari-level webview behaviour on macOS.
+type MacWebviewPreferences struct {
+ // TabFocusesLinks enables keyboard navigation to links via Tab.
+ TabFocusesLinks bool
+ // TextInteractionEnabled allows the user to select and interact with text.
+ TextInteractionEnabled bool
+ // FullscreenEnabled allows the webview to enter fullscreen.
+ FullscreenEnabled bool
+ // AllowsBackForwardNavigationGestures enables horizontal swipe for navigation.
+ AllowsBackForwardNavigationGestures bool
+}
+
+// MacTitleBar configures the macOS title bar appearance.
+//
+// opts.Mac = application.MacWindow{TitleBar: application.MacTitleBarHiddenInset}
+type MacTitleBar struct {
+ // AppearsTransparent makes the title bar background transparent.
+ AppearsTransparent bool
+ // Hide removes the title bar entirely.
+ Hide bool
+ // HideTitle omits the window title text.
+ HideTitle bool
+ // FullSizeContent extends the content area behind the title bar.
+ FullSizeContent bool
+ // UseToolbar renders a toolbar in place of the standard title bar.
+ UseToolbar bool
+ // HideToolbarSeparator removes the separator line below the toolbar.
+ HideToolbarSeparator bool
+ // ShowToolbarWhenFullscreen keeps the toolbar visible in fullscreen mode.
+ ShowToolbarWhenFullscreen bool
+ // ToolbarStyle controls how the toolbar relates to the title bar.
+ ToolbarStyle MacToolbarStyle
+}
+
+// MacTitleBarDefault is the stock macOS title bar with all decorations visible.
+var MacTitleBarDefault = MacTitleBar{}
+
+// MacTitleBarHidden hides the title text and extends content behind the title bar,
+// while keeping the traffic-light window controls visible.
+var MacTitleBarHidden = MacTitleBar{
+ AppearsTransparent: true,
+ HideTitle: true,
+ FullSizeContent: true,
+}
+
+// MacTitleBarHiddenInset is like MacTitleBarHidden but uses an inset toolbar so the
+// traffic lights sit slightly further from the window edge.
+var MacTitleBarHiddenInset = MacTitleBar{
+ AppearsTransparent: true,
+ HideTitle: true,
+ FullSizeContent: true,
+ UseToolbar: true,
+ HideToolbarSeparator: true,
+}
+
+// MacTitleBarHiddenInsetUnified is like MacTitleBarHiddenInset but merges the toolbar
+// and title bar into a single unified row.
+var MacTitleBarHiddenInsetUnified = MacTitleBar{
+ AppearsTransparent: true,
+ HideTitle: true,
+ FullSizeContent: true,
+ UseToolbar: true,
+ HideToolbarSeparator: true,
+ ToolbarStyle: MacToolbarStyleUnified,
+}
+
+// MacWindow contains macOS-specific window configuration.
+//
+// opts.Mac = application.MacWindow{
+// Backdrop: application.MacBackdropTranslucent,
+// TitleBar: application.MacTitleBarHiddenInset,
+// Appearance: application.NSAppearanceNameDarkAqua,
+// }
+type MacWindow struct {
+ // Backdrop controls the translucency of the window background.
+ Backdrop MacBackdrop
+ // DisableShadow removes the drop shadow cast by the window.
+ DisableShadow bool
+ // TitleBar configures the title bar appearance.
+ TitleBar MacTitleBar
+ // Appearance sets a specific NSAppearance for the window.
+ Appearance MacAppearanceType
+ // InvisibleTitleBarHeight sets the height (in points) of a draggable but
+ // invisible title bar region at the top of the content area.
+ InvisibleTitleBarHeight int
+ // EventMapping translates platform window events to common event types.
+ EventMapping map[events.WindowEventType]events.WindowEventType
+ // EnableFraudulentWebsiteWarnings shows browser-level phishing warnings.
+ // Default: false
+ EnableFraudulentWebsiteWarnings bool
+ // WebviewPreferences configures Safari webview-level preferences.
+ WebviewPreferences MacWebviewPreferences
+ // WindowLevel controls the z-order stacking group of the window.
+ WindowLevel MacWindowLevel
+ // CollectionBehavior controls how the window interacts with Spaces and fullscreen.
+ CollectionBehavior MacWindowCollectionBehavior
+ // LiquidGlass configures the Liquid Glass visual effect (macOS 15+).
+ LiquidGlass MacLiquidGlass
+}
+
+/******** Linux Options ********/
+
+// WebviewGpuPolicy controls hardware acceleration for the Linux webview.
+//
+// opts.Linux = application.LinuxWindow{WebviewGpuPolicy: application.WebviewGpuPolicyAlways}
+type WebviewGpuPolicy int
+
+const (
+ // WebviewGpuPolicyAlways always enables hardware acceleration.
+ WebviewGpuPolicyAlways WebviewGpuPolicy = iota
+ // WebviewGpuPolicyOnDemand enables acceleration as requested by web content.
+ WebviewGpuPolicyOnDemand
+ // WebviewGpuPolicyNever always disables hardware acceleration.
+ WebviewGpuPolicyNever
+)
+
+// LinuxMenuStyle controls how the application menu is displayed on Linux (GTK4 only).
+// On GTK3 builds this option is ignored and MenuBar style is always used.
+//
+// opts.Linux = application.LinuxWindow{MenuStyle: application.LinuxMenuStylePrimaryMenu}
+type LinuxMenuStyle int
+
+const (
+ // LinuxMenuStyleMenuBar shows a traditional menu bar below the title bar.
+ LinuxMenuStyleMenuBar LinuxMenuStyle = iota
+ // LinuxMenuStylePrimaryMenu shows a primary menu button in the header bar (GNOME style).
+ LinuxMenuStylePrimaryMenu
+)
+
+// LinuxWindow contains Linux-specific window configuration.
+//
+// opts.Linux = application.LinuxWindow{
+// WindowIsTranslucent: true,
+// WebviewGpuPolicy: application.WebviewGpuPolicyAlways,
+// }
+type LinuxWindow struct {
+ // Icon is the window icon shown when the window is minimised.
+ // Provide PNG-encoded image data.
+ Icon []byte
+
+ // WindowIsTranslucent makes the window background transparent.
+ WindowIsTranslucent bool
+
+ // WebviewGpuPolicy sets the hardware acceleration policy for the webview.
+ // Defaults to WebviewGpuPolicyNever when LinuxWindow is nil in options.
+ WebviewGpuPolicy WebviewGpuPolicy
+
+ // WindowDidMoveDebounceMS is the debounce time in milliseconds for the
+ // WindowDidMove event.
+ WindowDidMoveDebounceMS uint16
+
+ // Menu is the window-level menu.
+ Menu *Menu
+
+ // MenuStyle controls how the menu is displayed (GTK4 only; ignored on GTK3).
+ MenuStyle LinuxMenuStyle
+}
diff --git a/stubs/wails/pkg/application/window.go b/stubs/wails/pkg/application/window.go
new file mode 100644
index 0000000..db2c3a9
--- /dev/null
+++ b/stubs/wails/pkg/application/window.go
@@ -0,0 +1,240 @@
+package application
+
+import (
+ "unsafe"
+
+ "github.com/wailsapp/wails/v3/pkg/events"
+)
+
+// Window is the interface satisfied by both WebviewWindow and BrowserWindow.
+// All methods mirror the Wails v3 Window interface exactly, including unexported
+// platform hooks required for internal dispatch.
+//
+// var w Window = app.Window.NewWithOptions(opts)
+// w.SetTitle("My App").Show()
+type Window interface {
+ // Identity
+
+ // w.ID() → 1
+ ID() uint
+ // w.Name() → "main"
+ Name() string
+
+ // Lifecycle
+
+ // w.Show().Focus()
+ Show() Window
+ // w.Hide()
+ Hide() Window
+ // w.Close()
+ Close()
+ // w.Focus()
+ Focus()
+ // w.Run()
+ Run()
+ // w.Restore()
+ Restore()
+
+ // Geometry
+
+ // x, y := w.Position()
+ Position() (int, int)
+ // x, y := w.RelativePosition()
+ RelativePosition() (int, int)
+ // w, h := w.Size()
+ Size() (width int, height int)
+ // px := w.Width()
+ Width() int
+ // px := w.Height()
+ Height() int
+ // r := w.Bounds()
+ Bounds() Rect
+ // w.SetBounds(Rect{X: 0, Y: 0, Width: 1280, Height: 800})
+ SetBounds(bounds Rect)
+ // w.SetPosition(100, 200)
+ SetPosition(x, y int)
+ // w.SetRelativePosition(0, 0)
+ SetRelativePosition(x, y int) Window
+ // w.SetSize(1280, 800)
+ SetSize(width, height int) Window
+ // w.SetMinSize(640, 480)
+ SetMinSize(minWidth, minHeight int) Window
+ // w.SetMaxSize(3840, 2160)
+ SetMaxSize(maxWidth, maxHeight int) Window
+ // w.Center()
+ Center()
+
+ // Title and content
+
+ // t := w.Title() — not in interface, provided by concrete types
+ // w.SetTitle("My App")
+ SetTitle(title string) Window
+ // w.SetURL("https://example.com")
+ SetURL(url string) Window
+ // w.SetHTML("Hello
")
+ SetHTML(html string) Window
+
+ // Visibility states
+
+ // w.IsVisible()
+ IsVisible() bool
+ // w.IsFullscreen()
+ IsFullscreen() bool
+ // w.IsMaximised()
+ IsMaximised() bool
+ // w.IsMinimised()
+ IsMinimised() bool
+ // w.IsFocused()
+ IsFocused() bool
+ // w.IsIgnoreMouseEvents()
+ IsIgnoreMouseEvents() bool
+ // w.Resizable()
+ Resizable() bool
+
+ // Window state transitions
+
+ // w.Fullscreen()
+ Fullscreen() Window
+ // w.UnFullscreen()
+ UnFullscreen()
+ // w.Maximise()
+ Maximise() Window
+ // w.UnMaximise()
+ UnMaximise()
+ // w.Minimise()
+ Minimise() Window
+ // w.UnMinimise()
+ UnMinimise()
+ // w.ToggleFullscreen()
+ ToggleFullscreen()
+ // w.ToggleMaximise()
+ ToggleMaximise()
+ // w.SnapAssist()
+ SnapAssist()
+
+ // Style
+
+ // w.SetAlwaysOnTop(true)
+ SetAlwaysOnTop(b bool) Window
+ // w.SetBackgroundColour(application.NewRGBA(0, 0, 0, 255))
+ SetBackgroundColour(colour RGBA) Window
+ // w.SetFrameless(true)
+ SetFrameless(frameless bool) Window
+ // w.SetResizable(false)
+ SetResizable(b bool) Window
+ // w.SetIgnoreMouseEvents(true)
+ SetIgnoreMouseEvents(ignore bool) Window
+ // w.SetMinimiseButtonState(ButtonHidden)
+ SetMinimiseButtonState(state ButtonState) Window
+ // w.SetMaximiseButtonState(ButtonDisabled)
+ SetMaximiseButtonState(state ButtonState) Window
+ // w.SetCloseButtonState(ButtonEnabled)
+ SetCloseButtonState(state ButtonState) Window
+ // w.SetEnabled(false)
+ SetEnabled(enabled bool)
+ // w.SetContentProtection(true)
+ SetContentProtection(protection bool) Window
+
+ // Menu
+
+ // w.SetMenu(myMenu)
+ SetMenu(menu *Menu)
+ // w.ShowMenuBar()
+ ShowMenuBar()
+ // w.HideMenuBar()
+ HideMenuBar()
+ // w.ToggleMenuBar()
+ ToggleMenuBar()
+ // w.ToggleFrameless()
+ ToggleFrameless()
+
+ // WebView
+
+ // w.ExecJS("document.title = 'Hello'")
+ ExecJS(js string)
+ // w.Reload()
+ Reload()
+ // w.ForceReload()
+ ForceReload()
+ // w.OpenDevTools()
+ OpenDevTools()
+ // w.OpenContextMenu(&ContextMenuData{Name: "main"})
+ OpenContextMenu(data *ContextMenuData)
+
+ // Zoom
+
+ // w.Zoom()
+ Zoom()
+ // w.ZoomIn()
+ ZoomIn()
+ // w.ZoomOut()
+ ZoomOut()
+ // w.ZoomReset()
+ ZoomReset() Window
+ // z := w.GetZoom()
+ GetZoom() float64
+ // w.SetZoom(1.5)
+ SetZoom(magnification float64) Window
+
+ // Events
+
+ // cancel := w.OnWindowEvent(events.Common.WindowFocus, func(e *WindowEvent) { ... })
+ OnWindowEvent(eventType events.WindowEventType, callback func(event *WindowEvent)) func()
+ // cancel := w.RegisterHook(events.Common.WindowClose, func(e *WindowEvent) { ... })
+ RegisterHook(eventType events.WindowEventType, callback func(event *WindowEvent)) func()
+ // w.EmitEvent("user:login", payload)
+ EmitEvent(name string, data ...any) bool
+ // w.DispatchWailsEvent(&CustomEvent{Name: "init"})
+ DispatchWailsEvent(event *CustomEvent)
+
+ // Screen and display
+
+ // screen, err := w.GetScreen()
+ GetScreen() (*Screen, error)
+ // borders := w.GetBorderSizes()
+ GetBorderSizes() *LRTB
+
+ // Constraints
+
+ // w.EnableSizeConstraints()
+ EnableSizeConstraints()
+ // w.DisableSizeConstraints()
+ DisableSizeConstraints()
+
+ // Modal
+
+ // w.AttachModal(modalWindow)
+ AttachModal(modalWindow Window)
+
+ // Utilities
+
+ // w.Flash(true)
+ Flash(enabled bool)
+ // err := w.Print()
+ Print() error
+ // w.Error("something went wrong: %s", details)
+ Error(message string, args ...any)
+ // w.Info("window ready")
+ Info(message string, args ...any)
+
+ // Platform
+
+ // ptr := w.NativeWindow()
+ NativeWindow() unsafe.Pointer
+
+ // Internal platform hooks — implemented by concrete window types.
+
+ handleDragAndDropMessage(filenames []string, dropTarget *DropTargetDetails)
+ InitiateFrontendDropProcessing(filenames []string, x int, y int)
+ HandleMessage(message string)
+ HandleWindowEvent(id uint)
+ HandleKeyEvent(acceleratorString string)
+ shouldUnconditionallyClose() bool
+ cut()
+ copy()
+ paste()
+ undo()
+ redo()
+ delete()
+ selectAll()
+}
diff --git a/stubs/wails/pkg/application/window_manager_expanded.go b/stubs/wails/pkg/application/window_manager_expanded.go
new file mode 100644
index 0000000..59bcd98
--- /dev/null
+++ b/stubs/wails/pkg/application/window_manager_expanded.go
@@ -0,0 +1,32 @@
+package application
+
+// Get returns the first window whose Name() matches the given name, or nil if
+// no match is found.
+//
+// w := app.Window.Get("main")
+// if w == nil { panic("main window not registered") }
+func (wm *WindowManager) Get(name string) Window {
+ wm.mu.RLock()
+ defer wm.mu.RUnlock()
+ for _, window := range wm.windows {
+ if window.Name() == name {
+ return window
+ }
+ }
+ return nil
+}
+
+// GetByID returns the window with the given numeric ID, or nil if not found.
+//
+// w := app.Window.GetByID(1)
+// if w != nil { w.Focus() }
+func (wm *WindowManager) GetByID(id uint) Window {
+ wm.mu.RLock()
+ defer wm.mu.RUnlock()
+ for _, window := range wm.windows {
+ if window.ID() == id {
+ return window
+ }
+ }
+ return nil
+}
diff --git a/stubs/wails/pkg/events/events.go b/stubs/wails/pkg/events/events.go
index 3f3204d..6b163de 100644
--- a/stubs/wails/pkg/events/events.go
+++ b/stubs/wails/pkg/events/events.go
@@ -1,5 +1,8 @@
package events
+// ApplicationEventType identifies an application-level event.
+type ApplicationEventType int
+
// WindowEventType identifies a window event emitted by the application layer.
type WindowEventType int