window

package
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 51 Imported by: 0

README

ui/window

English | 简体中文

Window: open, close, bring to front (including activation token), window shortcut keys, event loop, off-screen screenshots, as well as read system preferences and complete platform events that Gio does not have.

File Responsibility
window.go Open, Main, Options (including Overlay), Window (Raise, Activate, WaylandDisplay…)
memory.go Opt-in process-wide idle Go heap reclamation
shortcut.go Shortcut key analysis and distribution
icon*.go SetIcon: The runtime application icon (macOS Dock, Windows window, X11 _NET_WM_ICON), the shape is cut out by internal/appicon according to the platform specification
root.go Window root view: background, scroll, 24dp margins
glass* Opt-in macOS glass backdrop, transparent Metal rendering and platform fallback; see usage
position_* First display centered; macOS calculated based on available screen area, other platforms use Gio actions
screenshot.go Screenshot Off-screen rendering to PNG
decorations*.go Linux compositor is drawn by Keel when not drawing title bar
titlebar_darwin.* Title bar drag area of macOS borderless window
scene_ios.* Experimental iOS scene lifecycle adapter, selected by KeelSceneDelegate in Info.plist; see iOS simulator
activation_* Activate(token): Wayland uses xdg-activation, X11 writes the startup ID and then requests activation
motion_* System preferences: reduce dynamic effects (macOS), scrollbar auto-hide (macOS, Windows), write in theme
scroll_darwin.m, scroll_wayland* The device and gesture stages of scrolling (trackpad hand lift, scroll wheel) are not provided by Gio and are left to core.ReportScrollGesture
automation.go Automation mode: memory window, semantic snapshot, simulated click input scrolling
automation_server.go Automation protocol: JSON request on KEEL_AUTOMATION socket
testdata/raise Real window deadlock regression testing
  • Dependencies: core, theme, internal/appicon (icon shape, shared with scaffolding), and jezek/xgb (X11 activation) and libwayland-client (Gio natively linked) on Linux. Does not rely on el, kit: the window only recognizes the core.Widget interface, and the system preferences are handed over to el through theme.
  • Used by: Application code. cmd/keel-mcp drives it through the socket protocol and does not reference its code.

When the environment variable KEEL_AUTOMATION=1 (or socket path) is set to start the application, each window will have an additional shadow window for Agent operations; the real window will be displayed as usual, and the Agent's operations will be reflected on the screen in real time. Adding KEEL_HEADLESS=1 will not display the window, see Agent end-to-end test.

window.Open(window.Options{Title: "Hello", Content: page})
window.Main() // Exit the process after the last window is closed

Before changing the code here, read Architecture · Cannot wait for the main thread in the lock. See Window and Application for details.

Main for macOS subscribes to NSWorkspace's accessibility display preferences and scrollbar styles, reading "Reduce Dynamic Effects" and "Show Scrollbars" on startup, and updating theme.ReducedMotion and theme.SystemScrollbarsAutoHide when they change. The AppKit callback is handed to the background consumer through a bounded queue, and then the topic is updated in core.Update to avoid the main thread waiting for the frame lock. "Auto-hide scroll bars" is read once when Windows starts. Windowless and off-screen automation modes do not install native observers, Linux currently uses application settings.

macOS native traffic light layout

Frameless windows can retain AppKit's standard buttons and center them within a custom titlebar. Layout uses dp; native button size, appearance and behavior remain owned by AppKit. A nil TrafficLightLayout keeps system placement. A positive Height enables custom placement, Left sets the first button's left inset, and OffsetY shifts its center down (positive) or up (negative). Zero Spacing preserves the system spacing.

w := window.Open(window.Options{
    Frameless: true,
    NativeTrafficLights: true,
    TrafficLightLayout: &window.TrafficLightLayout{
        Height: 44, Left: 15, Spacing: 23,
    },
    Content: page,
})
w.SetTrafficLightLayout(window.TrafficLightLayout{Height: 64, Left: 20})

Reserve the top-left button area in your content. Keel reapplies placement after resizing, fullscreen transitions and AppKit layout passes. The option is macOS-only; runtime updates are safe from callbacks and background goroutines.

Application menus and appearance are configured through Go APIs: NewMenuBar, SetApplicationMenu, SystemAppearance and SetNativeAppearance. See Window and Application for customization and platform capabilities.

Menu backends: AppKit on macOS, Win32 on Windows, Keel-rendered window menus on Linux (X11/Wayland). Options.MenuDisplay permits a custom window menu or application renderer. Focused custom editors handle standard operations through core.NextEditAction.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GlassSupported added in v0.1.7

func GlassSupported() bool

GlassSupported reports whether this build supports a native glass backdrop. Headless screenshots cannot include the native compositor's effects.

func LiquidGlassSupported added in v0.1.7

func LiquidGlassSupported() bool

LiquidGlassSupported reports whether this build and OS support NSGlassEffectView. Otherwise Glass uses NSVisualEffectView on macOS.

func Main

func Main()

Main runs the platform event loop. The process exits after the last window closes. With KEEL_AUTOMATION set it also serves automation requests, or only those with KEEL_HEADLESS=1; see automation.go.

func NativeAppearanceSupported added in v0.1.6

func NativeAppearanceSupported() bool

NativeAppearanceSupported reports whether SetNativeAppearance can change native application chrome. Go-rendered content still uses the application's theme.

func NativeApplicationMenu added in v0.1.6

func NativeApplicationMenu() bool

NativeApplicationMenu reports whether this build has a native menu backend.

func Screenshot

func Screenshot(content core.Widget, width, height int, path string) error

Screenshot renders content as a window would, off-screen at 2× scale, and writes a PNG. Width and height are in dp.

func ScreenshotAtScale

func ScreenshotAtScale(content core.Widget, width, height int, scale float32, path string) error

ScreenshotAtScale renders the first frame at an explicit pixel density. Dimensions are in dp; scale must be finite and positive.

func SetApplicationMenu added in v0.1.6

func SetApplicationMenu(items ...MenuItem) error

SetApplicationMenu installs a menu without retaining a controller. Use NewMenuBar and Install when the menu will be updated dynamically.

func SetIcon added in v0.0.7

func SetIcon(artwork []byte) error

SetIcon sets the app's icon from full-bleed square PNG artwork, as in a keel project's appicon.png: macOS shows it in the Dock with Apple's plate and shadow; Windows on every window's title bar and taskbar button; Linux X11 on every window (_NET_WM_ICON). Wayland and the browser take their icon from the installed .desktop entry and the page, so SetIcon does nothing there. It applies to open windows and to those opened later; call it before Open, or any time to change the icon.

func SetIdleMemoryReclaim added in v0.1.6

func SetIdleMemoryReclaim(enabled bool)

SetIdleMemoryReclaim enables process-wide reclamation of unused Go heap pages after all Keel windows have been quiet for two seconds. It defaults to false. Reclamation requires at least 32 MiB of unused, unreturned heap pages and is limited to once per 30 seconds. It does not redraw windows or change GOGC.

This runs a Go collection and returns free pages to the OS. It can briefly pause other goroutines, including non-UI workloads. Applications with latency sensitive background work should leave it disabled. Disabling cancels pending work, but cannot undo a reclamation already in progress.

func SetNativeAppearance added in v0.1.6

func SetNativeAppearance(value Appearance) error

SetNativeAppearance chooses native chrome without replacing a custom Go palette. System restores OS-controlled appearance. Unsupported platforms keep their existing native chrome; query NativeAppearanceSupported if needed.

func SocketDir

func SocketDir() string

SocketDir is where apps started with KEEL_AUTOMATION=1 listen. keel-mcp computes the same path; keep the two in sync.

Types

type Appearance added in v0.1.6

type Appearance string

Appearance describes system preference or an explicit native chrome style. Application palette selection remains independent, e.g. theme.Apply(custom).

const (
	AppearanceSystem Appearance = "system"
	AppearanceLight  Appearance = "light"
	AppearanceDark   Appearance = "dark"
)

func SystemAppearance added in v0.1.6

func SystemAppearance() Appearance

SystemAppearance reads the platform preference, falling back to Light when unavailable. Linux portal updates are cached so rendering never waits on D-Bus.

type Element

type Element struct {
	Ref      string `json:"ref"`
	Role     string `json:"role"` // see roleOf
	Name     string `json:"name,omitempty"`
	Value    string `json:"value,omitempty"`    // textbox content, select choice, progress
	Checked  *bool  `json:"checked,omitempty"`  // checkbox, radio, switch
	Selected *bool  `json:"selected,omitempty"` // tab, row, option; a button only when selected
	Disabled bool   `json:"disabled,omitempty"`
	X        int    `json:"x"`
	Y        int    `json:"y"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
}

Element is one node of a window's semantic tree, as reported to agents.

type GlassOptions added in v0.1.7

type GlassOptions struct {
	Style GlassStyle
	// CornerRadius is in dp. Zero uses the system's default glass curvature.
	CornerRadius float32
}

GlassOptions configures a glass backdrop covering the window content area. The backdrop samples content behind the window, not pixels drawn by Gio. Opaque content hides it; transparent content exposes it.

type GlassStyle added in v0.1.7

type GlassStyle uint8

GlassStyle selects the macOS backdrop material.

const (
	GlassRegular GlassStyle = iota // Liquid Glass on macOS 26+, vibrancy on older systems.
	GlassClear                     // More transparent Liquid Glass; vibrancy on older systems.
	GlassFrosted                   // NSVisualEffectView on all supported macOS versions.
)
type MenuAction string

MenuAction forwards a standard editing command to the focused native view. OnSelect, when supplied, overrides the action. Go editors consume actions through core.NextEditAction; AppKit also forwards to the focused native view.

const (
	MenuCopy      MenuAction = "copy"
	MenuCut       MenuAction = "cut"
	MenuPaste     MenuAction = "paste"
	MenuSelectAll MenuAction = "select-all"
	MenuUndo      MenuAction = "undo"
	MenuRedo      MenuAction = "redo"
)
type MenuBar struct {
	// contains filtered or unexported fields
}

MenuBar owns a portable application menu model. Install uses AppKit on macOS, Win32 menus on Windows, and Keel-rendered window menus on Linux X11/Wayland. Items can also drive an application's own Go menu renderer.

func NewMenuBar added in v0.1.6

func NewMenuBar(items ...MenuItem) (*MenuBar, error)
func (m *MenuBar) Install() error
func (m *MenuBar) Invoke(id string) bool

Invoke activates an enabled leaf item from UI code, e.g. a custom menu view. It returns false for missing/disabled items or unavailable native edit actions.

func (m *MenuBar) Items() []MenuItem

Items returns a deep copy, including Go callbacks for custom renderers.

func (m *MenuBar) SetItems(items ...MenuItem) error

SetItems replaces the model atomically. Validation errors leave it unchanged.

func (m *MenuBar) UpdateItem(id string, edit func(*MenuItem)) error

UpdateItem edits a copy of one item. The editor must not call methods on m. Titles, shortcuts, checked/disabled states, children and callbacks are mutable.

type MenuDisplay uint8

MenuDisplay selects how an installed application menu is shown in this window.

const (
	MenuDisplayAuto   MenuDisplay = iota // AppKit/Win32 menus, in-window menus on Linux.
	MenuDisplayWindow                    // Keel-drawn menu; useful for custom title bars and testing.
	MenuDisplayHidden                    // Application provides its own renderer; shortcuts remain available.
)
type MenuItem struct {
	ID, Title, Shortcut          string
	Disabled, Checked, Separator bool
	Role                         MenuRole
	Action                       MenuAction
	Children                     []MenuItem
	OnSelect                     func()
}

MenuItem describes a top-level menu, submenu, action or separator. IDs are optional, but explicit IDs permit UpdateItem and Invoke. Items are copied; callers may reuse slices. Callbacks run serially with other UI callbacks.

type MenuRole string

MenuRole assigns a macOS system menu slot without prescribing its contents.

const (
	MenuApplication MenuRole = "application"
	MenuEdit        MenuRole = "edit"
	MenuWindow      MenuRole = "window"
	MenuHelp        MenuRole = "help"
	MenuServices    MenuRole = "services"
)

type Options

type Options struct {
	MenuDisplay   MenuDisplay
	Title         string
	Width, Height int
	// MinWidth and MinHeight constrain the client area in dp; zero leaves an axis unconstrained.
	MinWidth, MinHeight int
	Content             core.Widget
	// Overlay is drawn over the whole window, above Content, for hand-written
	// Gio content; el views declare overlays with cx.Overlay instead. It should
	// take no space while it has nothing to show.
	Overlay core.Widget
	// Shortcuts maps accelerators to callbacks while the window has focus, e.g.
	// "mod+," (Cmd on macOS, Ctrl elsewhere), "ctrl+shift+s", "esc".
	Shortcuts map[string]func()
	OnClose   func()
	// OnResize receives the actual client-area size in dp, on the first frame
	// and when it changes. It runs on the UI update queue.
	OnResize func(width, height int)
	// Frameless hides the system title bar so the content can draw its own,
	// e.g. a kit.TitleBar; the content then starts at the window's top edge.
	Frameless bool
	// NativeTrafficLights keeps AppKit's standard window buttons visible over
	// frameless content on macOS. Reserve the top-left titlebar area in Content.
	// Other platforms ignore this option.
	NativeTrafficLights bool
	TrafficLightLayout  *TrafficLightLayout
	// Glass enables a native macOS glass backdrop. Leave the desired glass
	// areas transparent in Content. Other platforms keep the theme background.
	Glass *GlassOptions
}

Options configures a window. Width and Height are in dp; zero uses 640×480.

type Snapshot

type Snapshot struct {
	Window   WindowInfo `json:"window"`
	Elements []Element  `json:"elements"`
}

Snapshot is a window and its elements.

type TrafficLightLayout added in v0.1.5

type TrafficLightLayout struct {
	Height, Left, OffsetY, Spacing float32
}

TrafficLightLayout positions macOS's standard window buttons in dp. Buttons retain their system size, rendering and native behavior. Height is the custom titlebar height; buttons are centered vertically in it. Left is the first button's left inset. OffsetY moves the center down (or up when negative). Spacing is the distance between button centers; zero keeps AppKit's spacing. A nil layout in Options keeps AppKit's default placement.

type Window

type Window struct {
	// contains filtered or unexported fields
}

func Open

func Open(o Options) *Window

Open creates and shows a centered window where the platform supports it. Call it before Main or from any callback. It panics on an invalid shortcut, which is a programming error.

func (*Window) Activate added in v0.0.4

func (w *Window) Activate(token string)

Activate brings the window to the front with an activation token that another program granted, such as notification.Activation.Token after a system notification was clicked. Window managers let a token through their focus-stealing prevention, where a plain Raise may only flash the taskbar. On Wayland the token goes to xdg-activation; on X11 it is a startup ID. Elsewhere, with an empty token, or if the platform refuses, Activate is Raise.

func (*Window) Close

func (w *Window) Close()

Close closes the window as if the user clicked its close button.

func (*Window) Closed

func (w *Window) Closed() bool

Closed reports whether the window has been destroyed. Call it from UI code.

func (*Window) Focused

func (w *Window) Focused() bool

func (*Window) Frameless

func (w *Window) Frameless() bool

Frameless reports whether the window draws its own title bar.

func (*Window) Maximized

func (w *Window) Maximized() bool

Maximized reports whether the window is maximized. Call it from UI code.

func (*Window) Minimize

func (w *Window) Minimize()

Minimize hides the window in the Dock or taskbar.

func (*Window) Raise

func (w *Window) Raise()

Raise brings the window to the front.

func (*Window) Resize added in v0.1.6

func (w *Window) Resize(width, height int) error

Resize requests a client-area size in dp. It is safe from callbacks and background goroutines. The platform may constrain the request; Size and OnResize report the actual size on the next frame. Closed windows are ignored.

func (*Window) SetTrafficLightLayout added in v0.1.5

func (w *Window) SetTrafficLightLayout(layout TrafficLightLayout)

SetTrafficLightLayout updates native button placement without recreating the window. It is safe from callbacks or background goroutines; the change is applied on the next frame. NativeTrafficLights must be enabled in Options.

func (*Window) Size added in v0.1.6

func (w *Window) Size() (width, height int)

Size returns the most recently observed client-area width and height in dp. Before the first frame it returns the requested initial size. It is safe from callbacks and background goroutines, and includes window menus/decorations drawn by Keel. The operating system's external frame is excluded.

func (*Window) TakeEditAction added in v0.1.6

func (w *Window) TakeEditAction() (core.EditAction, bool)

TakeEditAction implements the focused-editor bridge used by core.NextEditAction. Call from UI code; editors normally use core.NextEditAction instead.

func (*Window) TitleBarArea

func (w *Window) TitleBarArea(x, y, width, height float32)

func (*Window) ToggleMaximize

func (w *Window) ToggleMaximize()

ToggleMaximize maximizes the window (zooms it on macOS), or restores it when it is maximized.

func (*Window) WaylandDisplay added in v0.0.4

func (w *Window) WaylandDisplay() unsafe.Pointer

WaylandDisplay is this window's wl_display on Linux Wayland, nil elsewhere or before the window is shown. Pass it to native/clipboard's UseWaylandDisplay to read the clipboard while this window has focus.

type WindowInfo

type WindowInfo struct {
	ID     string `json:"id"`
	Title  string `json:"title"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	Active bool   `json:"active"`
}

WindowInfo describes an open window.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL