Newsletter, May 2026
Gio v0.10.0!

After a long period of newsletter/release dormancy, we’re back!

Changes in my (Chris’) personal life made it very difficult to write these newsletters during the last year. However, thanks to the generosity of the Gio community, I can now receive financial support for writing these newsletters and Gio maintainership from our OpenCollective funds. This should ensure that I can consistently spend time working to improve Gio and making releases at regular intervals. Thank you to everyone who has financially supported the project thus far!

In the seven months since the last newsletter, Gio has been polished by numerous community members. While this release does not contain major new features, you’ll find plenty of small new features and bugfixes throughout, as well as improved platform support.

This newsletter, I’d like to give a special thank you to Lucas Rodrigues and Egon Elbre for their steadfast contributions to Gio. Egon has contributed to Gio since 2019, and is always driving us towards greater performance at every level of Gio’s stack. Lucas started contributing in 2020, and is singlehandedly responsible for about half of gio-x. Lucas is always on the forefront of Gio’s mobile and web features, and apps wouldn’t work at all on mobile without Lucas’ care and attention. More than six years of each of your time and attention is a great gift to the Gio ecosystem. Thank you both.

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.0

There are no breaking API signature changes in this release, but several platforms now send different window lifecycle events or detect system meta keys using new heuristics. Since these changes have the potential to alter the behavior of application code, I’ve opted to bump the minor version number anyway. Below

Behavior changes by author

CoyAce:

  • app: [Android] Send focus lost event when the window is backgrounded. Fixes: #679 93419a77
  • app: [android] remove redundant ConfigEvent in onStop and onSurfaceDestroyed. Config.Focused represents window interaction focus, which should only change when the window gains or loses user interaction capability. 47ab4c97

Lucas Rodrigues:

  • app: [macOS] run main.main off the main thread when Gio is embedded. When Gio is embedded (such as on Android and iOS), we pretend that the Go library is the main program by running Go main on the main thread. To avoid deadlock, app.Main returns immediately to relinquish control of the main thread. 45963441
  • app,io: [js] change Shortcut key on macOS/iOS. Previously, the Shortcut key was hardcoded as ModCtrl. That patches tries to identify the OS and change the key. 8c2e45b8

Non-breaking changes by author

Egon Elbre:

  • all: run go fix. 3d6cafa9
  • text: fix length check. 9ab8095d
  • layout: add Flex.Gap for spacing out items. 9b38545f
  • layout: add List.Gap for spacing out items. 4ed9695d
  • widget/material: add LayoutWidgets for adding scrollable widgets. 8b966434
  • font/opentype: fix font.Face creation. typesetting introduced a cache field that needs to be properly initialized. Use constructor to avoid the issue. e8c1e1ba
  • text: avoid creating two Face instances. e2e2c1a0
  • go.mod: upgrade to github.com/go-text/typesetting@v0.3.4. dec57aea

CoyAce:

  • app: [Android] document DataDir limitations. Document that DataDir is not available before main. 42bc707f
  • app/permission: add microphone permissions. e38f80ad
  • app: [Android] delete redundant dataDirChan. 99647591
  • widget: fix text selection and selection area rendering issues. 1. When selecting multiple lines of text, the rendered selection area does not include the last character of the first line. 2. When selecting a specific line (other than the last line) in multiline text, the last character of that line cannot be selected. 9966e922
  • app: [android] replace OnFocusChangedListener with onPause/onResume. 92fa23b5
  • app: [iOS] fix focus event for iOS 13.0+ with backward compatibility. UIScene notifications are the correct way to track window focus on iOS 13.0+, because the Key Window API is scene-level on iOS 13.0+, but we need to maintain support for iOS 12 and earlier. 76036917

Lucas Rodrigues:

  • app: remove stale reference to NewWindow in the documentation. 818061a1
  • app: [Windows] use the app ID for the window class registry. We’re about to send messages between multiple instances of the same program, and we need something to distinguish Gio programs. Use the app ID. f48cc2c4
  • app/internal/windows: add SendMessage, FindWindow. 74671a7f
  • app: add custom scheme support. Now, it’s possible to launch one Gio app using a custom URI scheme, such as gio://some/data. 7bcb315e
  • app: [js] add IME support. f98baf7f
  • app: [js] fixes IME. Fix several issues in the IME implementation c3a6e85f
  • text: render SVG font as black-white outline. Previously, using SVG fonts will cause Gio to render invisible “characters”. 65d86895
  • app: [js] fixes IME. Fix several issues in the IME implementation c3a6e85f
  • text: render SVG font as black-white outline. Previously, using SVG fonts will cause Gio to render invisible “characters”. 65d86895

Elias Naur:

  • Revert “app: optimize window context locking”. This reverts commit 3e601e73c421929ce9e82a22786998d9fd8322f2 because it results in a blank window on Android. be8d9df8
  • Revert “gpu: replace f32.Point/Rectangle with image.Point/Rectangle”. 6e5bbfe8
  • .builds: fix builds. c250d7d5
  • app: remove go1.18 go:build conditional. 0d08eaa5
  • test: go fmt. a6da4083
  • app,io/key: go fmt. dfe4ff02

Eugene:

  • gesture: refresh PointerID on Press and Enter. Click and Hover both stored the first PointerID they observed in their internal pid field and only updated it when not currently hovered/entered. Once the gesture became hovered, any later event under a different PointerID was effectively ignored: Click.Press fell through ‘c.pid != e.PointerID’ and was silently dropped, and Hover could never reset entered when the matching Leave arrived under a new ID. e49c5b02
  • io/input: do not track scroll events as pointers. Scroll events arrived at pointerQueue.Push and went through pointerOf + deliverEnterLeaveEvents + deliverEvent like Move/Press/Release. The side effect: every scroll created or updated a state.pointers entry, populated p.entered with whatever handlers sat under the wheel position, and overwrote state.cursor based on hit-test at the scroll position. b1cadbdd

runitclean:

  • text: correct arabic diacritics handling. This commit fixes the association of diacritical marks with the proper script during text segmentation, as well as fixing the visual position of diacritical marks. The prior code inverted the Y axis positioning for diacritics, which made them frequently overlap the glyph they were meant to appear above or below. 3af0ebb3

Thomas Banks:

  • app: enable creation of top most windows. bbb54d5f

Chris Waldon:

  • text: drop obsolete comment about NewWindow. Fixes: #681 451b7d3a

gioui.org/x@v0.10.0

There are no breaking API changes, but quite a few improvements in this release of gio-x! CoyAce improved gio-x’s support for animations in UI components and the explorer API for opening system files, while Lucas expanded platform support for the pref package and Egon extended the richtext/styledtext packages to support line height customization.

CoyAce:

  • explorer: [android] add displayName and size info for imported file. file_darwin.go changed because need Size func to compile on darwin, so add a dummy implemention types.go added for platforms other than darwin and android add filename for exportFile e0fc477
  • component: bugfix - Progress didn’t initialize reverse progress cause immediately stop. Ensure that starting animations in the reverse direction initializes their progress correctly. 0a4bfd5
  • component: bugfix - TextField if become inactive, will loop animation forever. Prevent an animation loop on focus loss introduced by the previous fix to component animation. Before this change, the hint text would loop between its focused and unfocused positions indefinitely, whereas now it will correctly animate once. 17d36d9
  • component: add Reset method to Progress for reusability. Fix Progress animation not being reusable after completion. The Reset method returns the progress to its starting position (0.0 for Forward, 1.0 for Reverse), enabling the same Progress instance to be used multiple times. f9ca5c0
  • explorer: add ReadFile, URI and Seek API. Add ReadFile and URI API for reopening previously selected files across app sessions. Add Seek API for random access. 18aebcb
  • explorer: [android] format code for readability.. 2696b23
  • explorer: [android] implement persistent file URI handling. Add support for reopening previously selected files across app sessions: a3937d5
  • explorer: [iOS] implement name, size, seek and readFile.. Add support for reopening previously selected files across app sessions. This implementation copies selected file to document direction to support file persistence. 198eb5a
  • explorer: [macOS] import AppKit in a case sensitive way and clean build tag. 1683c69

Chris Waldon:

  • go.*: update stroke dependency to eliminate dashed infinite loop. This commit updates the https://github.com/andybalholm/stroke dependency to avoid an infinite loop condition when drawing dashed lines. It was previously possible to get stuck drawing zero-length line segments in an infinite loop. The issue is fixed upstream here: e9a8ba2
  • styledtext: fix gofmt. 36ee85a
  • ci: fix wine installation. Debian testing image apparently doesn’t have wine in the configured repos, so revert to the stable release that does. a5584ae
  • explorer: gofmt. 0fea58e

Lucas Rodrigues:

  • pref: [ios,macos] add support for iOS and macOS. This patch adds support for iOS and macOS for Theme and Locale packages. 29b4748

Egon Elbre:

  • richtext,styledtext: add LineHeight and LineHeightScale properties. When layouting text you rarely want the line-height scale to be 1. The usual value that doesn’t feel cramped any more is 1.2. 515cc0d

gioui.org/example@v0.10.0

Elias Naur:

  • kitchen: simplify progress indicator updating mechanism. 939a792

Egon Elbre:

Chris Waldon:

  • explorer,go.*: update to demonstrate re-opening files. The explorer package now supports reopening previously opened files on many platforms. This commit updates the explorer sample app to use this feature to reopen the previously viewed image without a new dialog requesting a file choice. aa0abd0

gioui.org/cmd@v0.10.0

Lucas and CoyAce both dramatically improved Android/iOS support. Applications can now launch other applications, consume deeplinks, and properly access the Android microphone.

Lucas Rodrigues:

  • gogio: add deeplink support. ae8a780
  • gogio: [wasm] fix compatibility with Go 1.23+. e1f06eb
  • gogio: [macOS] support custom profile. ed8d0aa
  • gogio: [iOS] fix compatibility with Apple Connect and iPad requirement. This pach fixes a total of 6 issues caused by gogio, when uploading .ipa to Apple Connect/Apple Store. 048614c
  • gogio: [Android] add support for querying apps. Previously, it was impossible to identify if a specific app was installed on the user device. It was also impossible to launch a external app from Gio using Intent. 8de547d
  • gogio: [android] bump target sdk version. Match the “Target SDK” with the mininum required by Google Play. 2e72e8f

CoyAce:

  • gogio: [Android] map the microphone permission to RECORD_AUDIO. f587d2f
  • gogio: [android] add CXX environment variable for cgo cross-compilation. Adds the CXX environment variable when building Android shared libraries to ensure proper C++ compiler selection for cgo-enabled packages. e5b1a4e
  • gogio: [ios] add CXX, CGO_CXXFLAGS environment variable for cgo cross-compilation and correct signKey. f4d6788

giouiorg

leojimenezg added scapmi to the application showcase, and Elias updated the Android documentation to use a non-obsolete environment variable.

leojimenezg:

  • doc/showcase: add scapmi. 4db1a9b

Elias Naur:

  • content/doc/install: replace ANDROID_SDK_ROOT reference with ANDROID_HOME. 7bd287d

End

Thanks for reading!

Chris Waldon