Skip to content

v0.4.0

Latest

Choose a tag to compare

@dyike dyike released this 25 Oct 00:37
· 1 commit to main since this release
dec3ec8

Desktop builds without cgo, platform accessibility, paint-only frames, and a testable app.

Desktop targets now build and run with CGO_ENABLED=0.

  • macOS: CoreText glyph rasterization (ui/theme), OpenGL, Cocoa initialization, Metal, the headless Metal context and the window itself (gio/app) drive AppKit and Metal through purego instead of cgo. The macOS window logic is shared over plain handles between the two bindings.
  • Linux: EGL, xkbcommon, Vulkan, X11 and Wayland windows all load without cgo, so the Linux desktop path builds and runs with CGO_ENABLED=0. A new linux-cgo-free CI job covers it.
  • cgo stays the default where it already worked; -tags purego or CGO_ENABLED=0 selects the new bindings. No .c, .m or .h files were added.

Accessibility reaches all three desktop platforms.

  • ui/window exposes Keel windows to macOS accessibility (AppKit), Linux AT-SPI and Windows UI Automation, including scroll areas and what is scrolled out of view. Keel's elements are built from the semantic tree, so a window reports what it draws rather than a parallel description.
  • The semantic node that holds keyboard focus is marked, reported to VoiceOver, AT-SPI and UI Automation, and assistive technology can move keyboard focus with gio focusing a semantic node from any goroutine.
  • gio/app exposes the semantic tree and accepts synthesized input; a new docs/accessibility.md covers the model.

Applications can be tested in memory.

  • window.OpenHeadless opens a window in memory with no native window and no Main: it lists elements as keel-mcp reports them, finds them by visible text, clicks, types, presses keys, scrolls, resizes and takes screenshots, and closing it never quits the process.
  • The new ui/window/windowtest package wraps it for testing.TB (app.Click("Save"), app.Want("Hello, Ada!")); keel new now writes such a test and a CI workflow.
  • keel run keeps application state across reloads, so editing a view no longer resets navigation.

Rendering and CPU.

  • ImageOp.PaintQuads (PaintTintedQuads on Metal) draws a glyph run as one operation instead of seven per glyph; a 3,200-glyph benchmark went from 0.99 to 0.52 ms a frame with byte-identical pixels. Keel's CoreText atlas batches consecutive masks on one page.
  • el.Context.AnimatingAmbient ticks ambient indicators (spinners, indeterminate progress, skeleton shimmer) at a shared 30 Hz instead of every display frame: the gallery's Button page went from 27-29% to about 18% CPU. Transitions, scrolling and input keep full frame rate; reduced motion requests nothing.
  • Large immutable Metal buffers are pooled, Tab targets are collected only when Tab is pressed, and node state is cached per frame.
  • Frames that only advance paint-time animation are repainted, and gio/input reports pending input.

CLI.

  • -h exits 0 without an error line; keel version names the commit for source builds; keel doctor and generated projects agree on Go 1.26.1.
  • keel new -lang generates English by default (zh-CN for Chinese); unknown values are refused.

Validation: gofmt, vet, all module tests, go test -race on ui/ and internal/, the Gio and go-text patch tests, the offline component check, CGO_ENABLED=0 GOOS=windows go build ./..., and cgo-free builds of the whole module on macOS. The Linux no-cgo path runs in its new CI job. The macOS real-window tests could not run on the release machine: with the screen locked (CGSSessionScreenIsLocked), windows never receive a new drawable, and v0.3.8 fails them the same way there. Run KEEL_DESKTOP=1 go test -run RealWindows ./ui/window on an unlocked machine before relying on window-level behavior.

本版是 0.4.0:macOS 与 Linux 桌面都能在 CGO_ENABLED=0 下构建和运行;三个桌面平台都接入了无障碍(AppKit、AT-SPI、UI Automation),键盘焦点可读可改;新增 window.OpenHeadless 与 ui/window/windowtest,应用视图可在内存中测试,keel new 会生带测试和 CI 的项目;ImageOp.PaintQuads 把一段字形绘制合成一次操作,环境指示器按共享 30 Hz 刷新。macOS 真窗口测试因发版机器处于锁屏状态无法运行,v0.3.8 在同机同样失败,请在解锁的机器上补跑。

Compare: v0.3.8...v0.4.0