Newsletter, August 2026
A Gnarly Bug Resolved

This month I’m excited to announce Gio v0.10.2! This should be an easy release for everyone to update to, as there are no API changes, just little improvements. I’m especially excited to announce the resolution of a 4-month-old rendering bug affecting NVIDIA and Google hardware. More detail below.

Sponsorship

These past few months, Gio thanks the following organizations and community members for their ongoing support!

Supporting the whole team:

Supporting a maintainer:

  • Kristian Mide via GitHub Sponsorship of Elias.
  • Dmitri Shuralyov via GitHub Sponsorship of Elias.
  • anedel via GitHub Sponsorship of Elias.
  • A number of anonymous community members supporting both Elias and Chris.

Sponsorship money given to Gio enables Elias and I to cover the costs of running Gio’s infrastructure, to pay for some of our time spent maintaining and improving Gio, and to plan for funding significant feature work. You can support Gio by contributing on OpenCollective or GitHub Sponsors.

gioui.org@v0.10.2

This month we can thank qiannian and Devon Krisman for a flurry of improvements to IME and Windows integration. Additionally, Egon Elbre documented an edge case and Elias cleaned up many internal packages.

This release also includes the resolution to our long running issue 686, which originally reported that on certain devices (NVIDIA GPUs and Google Pixel 10 phones), text would sometimes appear translucent instead of the expected opaque color. Ultimately, the issue was that text is frequently not perfectly aligned to the pixel grid, and the affected devices would mis-render when any path was not pixel-aligned due to insufficient GLSL precision. This took a long time to figure out, but is now fixed in the gio-shader repo.

Changes by Author

Elias Naur:

  • all: use unsafe.SliceData and StringData to avoid out of bounds panics. 0dd8eb80
  • all: go fix. 9033d393
  • all: remove obsolete +build directives. ffa383ce
  • internal/gl: don’t allocate C string for glShaderSource. 89000b37
  • gpu/internal/metal: propagate errors from MTLDevice methods. 50d51958
  • gpu/internal/driver: derive BlendDesc.Enable from src, dst parameters. 23e823d2
  • app/internal/windows: don’t return a pointer from GetWindowPlacement. 18034696
  • internal/vk: replace use of reflect.StringHeader with unsafe.StringData. 20857f9d
  • internal/byteslice: replace reflect with generic implementations. 050f3030
  • gpu: simplify error handling. a7fa0095

qiannian:

  • app: don’t cancel IME on expanded snippets. SnippetCmd can grow to include surrounding text while an IME composition is active. If the selection has not moved and the old snippet still matches the new one, don’t cancel the platform composition. 84882820
  • app: [Windows] place IME candidates under composition. Send the editor’s visible composition bounds with SelectionCmd and use them as the CFS_EXCLUDE rectangle for ImmSetCandidateWindow. That puts the candidate list below the text being composed, instead of just under the caret. 6a9cc6d9
  • app,widget: avoid redundant IME state updates. a73013eb
  • app: [Windows] center windows in the work area. Use the current monitor’s work area for system.ActionCenter. Include the work area’s origin when calculating the window position. This keeps centered windows out of the taskbar and on secondary monitors. b4932447
  • internal/stroke: fix angle wraparound. Normalize angle differences to the shortest arc so turns that cross the atan2 boundary keep the correct direction. 2253f8af

Devon Krisman:

  • app: restore a minimized window on system.ActionRaise. SetForegroundWindow does not un-minimize a window. A window sitting iconified in the taskbar therefore ignored ActionRaise entirely: the call succeeded, the window stayed minimized, and nothing came to the front. This is the normal state for an application asking to be raised from a tray icon, a single-instance handoff, or a notification click, which is exactly when ActionRaise matters. 64b13936
  • app: prefer the IDI_APPLICATION icon for the window class. The window class icon was loaded from resource ID 1, the first icon group in the binary. That group is also what Explorer and the taskbar use for the executable itself, so an application could not give its window a different icon from its file icon - a common wish when the file icon is a detailed product mark and the title bar wants a simple glyph that survives being drawn at 16x16. 399dec5d

Chris Waldon:

  • widget: use higher-level layout primitive in test. This doesn’t change the meaning or results of the test, but slightly decouples it from the editor’s implementation details. c7e3d6c1
  • go.*: update gio-shader to v1.0.9. This picks up the shader fix for text and other paths being unexpectedly transparent when their x origin coordinate was not pixel-aligned. 4575fbb5

Egon Elbre:

  • io/key, io/input: document system event matching special case. The empty key.Filter.Name does not match keys with platform side-effects, such as Tab for focus navigation. This behavior was introduced in c3f2abeb (“io/input: implement key.Filter.Name special case for matching every key”), but was only mentioned in the SystemEvent doc, which app users never see. Document it on key.Filter.Name and expand the SystemEvent doc with the affected keys and fallback behavior. 33f5fd30

gioui.org/x@v0.10.2

Devon fixed a subtle mistake in explorer’s use of the Windows API that caused the application process to change its working directory each time it opened a file in the dialog.

Changes by Author

Devon Krisman:

  • explorer: set OFN_NOCHANGEDIR on the Windows file dialogs. The Win32 common dialogs change the calling process’s current working directory to the directory of the selected file unless OFN_NOCHANGEDIR is passed. Because explorer runs the dialog on the application’s own process, picking a file silently relocated the process CWD, breaking every relative path the application resolved afterwards - config lookups, log destinations and asset loading all started pointing at whatever folder the user last browsed to. bf24362

Chris Waldon:

  • go.*: update Gio to v0.10.2. a0e809e

gioui.org/example@v0.10.2

Example is now updated to leverage the latest core and x changes.

Changes by Author

Chris Waldon:

  • go.*: update Gio and Gio-x to v0.10.2. 40086a9

gioui.org/shader@v1.0.9

Elias cleaned up the build instructions in the shader repository and committed the fix for issue 686 (discussed above).

Changes by Author

Elias Naur:

  • flake.*: add Nix flakes for setting up a development shell. 1ae659b
  • flake.*: upgrade to nixpkgs 25.05. 2378538
  • gio: bump precision of stencil.frag to highp. Precision mediump poses issues on (at least) Mesa drivers. b3dde1f
  • flake.*: nix flake update to nixpkgs 26.05. 873e607
  • README.md: document how to select the Xcode SDK paths. 964dd60
  • gio,cmd/convertshaders: force “highp” precision for fragment shaders. References: #686 01ffb6c
  • README.md: fix Nix instructions. 2631b83

End

Thanks for reading!

Chris Waldon