Newsletter, April 2022
io/key changes

GUI survey

As many of you know, Fyne and Gio together ran a “Go GUI Developer Survey” recently, and Andy from Fyne has published the results here:

https://fynelabs.com/2022/05/03/go-gui-developer-survey-results/

Gio and Fyne both have growing communities that are supplanting more entrenched options like binding to GTK or Qt. It’s really encouraging to see so much interest and adoption.

core gio

This month, Elias focused on keyboard input and frame lifecycle. Applications can now register multiple layers of global keyboard shortcut handlers, the window no longer emits all key and pointer events as window events, and the system.FrameEvent.Frame was changed to give applications as much time as possible to execute other tasks on their primary event loop between frames. Additionally, gioui.org/cmd was moved to a new repository.

Elias has also posted an RFC to convert Gio’s handling of units (Dp, Sp, and Px) to a new API. Please try out the units branch of core in your applications and respond to this email thread with your thoughts:

https://lists.sr.ht/~eliasnaur/gio/%3CCAMAFT9XLLdmRBfSz%3D7v9Hnr0NBcNFygABVfd3V7kt57wp%3D9pJA%40mail.gmail.com%3E

There were 33 commits to core since the last newsletter.

Breaking API changes by author:

Elias Naur:

  • io/key: [API] rename tab and modifier keys, introduce NameCommand. We already have precedence for word-named keys (“Space”) and the new names are less obscure and matches Modifiers.String. (ed8d3e85)
  • io/key: [API] implement key event propagation. Before this change, every Event would be passed to the focused InputOp tag, making it impossible to implement, say, program-wide shortcuts. This change implements key.Event routing similar to how pointer.Events are routed: every InputOp describes the set of keys it can handle, and the router use that information to deliver an Event to the matching handler. (380f96b3)
  • app,io/key,io/system: [API] replace system.CommandEvent with key.Event. It’s much simpler to map the Android back button to a key.Event and let the usual key filtering determine whether to block its default behaviour. (6c76fa6d)

Jack Mordaunt:

  • app: [API] don’t relay raw input events from app.Window. Avoid sending raw input events over the window channel. (4e488f4c)

Non-breaking changes by author:

Elias Naur:

  • app: [macOS] fix caret position calculation after IME text insert. Fixes: #385 (49bd5787)
  • app: don’t delay FrameEvent.Frame by v-sync latency. We should return as soon as possible from FrameEvent.Frame to allow the main goroutine to continue processing other tasks. Whereas GPU.Frame may touch the frame ops, GPU.Present will not, so this change moves Present to after returning from FrameEvent.Frame. (38ff78df)
  • gpu/headless: return error if NewTexture fails. (6e662038)
  • Revert “app: don’t delay FrameEvent.Frame by v-sync latency”. This reverts commit 38ff78df5dbeb8fcb13fa743a891237afd9ff573, because it broke OpenGL by moving eglSwapBuffers outside the MakeCurrent context scope. (405215f8)
  • app: don’t delay FrameEvent.Frame by v-sync latency. We should return as soon as possible from FrameEvent.Frame to allow the main goroutine to continue processing other tasks. Whereas GPU.Frame may touch the frame ops, GPU.Present will not, so this change moves Present to after returning from FrameEvent.Frame. (43865dda)
  • gpu/internal/opengl: add fallback for sparse OpenGL ES 2.0 ReadPixels. OpenGL ES 2.0 doesn’t support GL_PACK_ROW_LENGTH, so this change implements a fallback using a temporary buffer. (6a142696)
  • app: don’t panic when the client doesn’t call FrameEvent.Frame. Fixes: #396 (dc25afda)
  • io/key: change Modifiers.String separator to “-”. We’re about to express sets of key combinations as - where modifiers are separated by dashes as well. To make Modifers.String useful for expressing key sets, change its separator to “-”. (9c59612e)
  • io/router: deliver synthetic events to sibling pointer handlers. Before this change, synthetic events such as scrolling caused by focus movement would use semantic information to determine potential receivers. However, there can only be one handler per area so sibling handlers would not be considered. This change makes the event delivery traverse the entire tree of handlers, including siblings. (bec0283e)
  • app: give key handlers a chance to process Tab and Shift-Tab. Before this change, Tab and Shift-Tab would always result in focus movement. With this change, a key.InputOp with a matching Keys set will block focus movement and deliver the events to it. (d37197f4)
  • app,io/key: introduce keys for directional navigation. This change adds key.NameUp/Down/Left/Right and maps the Android TV remote directional keys to them. As a side-effect a key.InputOp can now receive directional keys (and block their focus movement). (ad7c1eb7)
  • io/system: describe FrameEvent.Insets more precisely. (3a4b8b81)
  • widget/material: remove redundant offset op. (76298742)
  • widget: fix Editor key set. Arrow and delete/backspace shortcuts use ShortcutAlt, not Shortcut. (6ddc13ce)
  • io/router: send key events to root handlers if nothing else wants them. Fixes: #403 (30fa85f5)
  • app: [Android] take snippet offset into account for getCursorCapsMode. References: #404 (f3265e56)
  • app,io/router: expand IME snippets if a new range overlaps the old. Instead of completely replacing the IME snippet for every update, expand the old range if there is overlap. This change avoids never-ending restarts of the IME on Android where snippets are expanded in two calls, one for expanding before the selection and one for expanding after the selection. (02732037)
  • io/router,widget: give every key.InputOp a chance to process events. If the currently focused handler doesn’t want the key event, try every other handler, from top to bottom. This change requires widgets to only react when focused. (2381c5ad)
  • widget: don’t draw Editor selection when not focused. (3c45a6d4)
  • io/pointer: remove unused functions. (8630fee6)
  • app: [Android] avoid out-of-bounds access in getCursorCapsMode. Fixes: #404 (6ede60d8)
  • app: replace driver.Raise with Perform(ActionRaise). (1a833ab0)
  • app: replace Config.center with Perform(ActionCenter). (d22ec125)
  • app: only perform actions and apply options on wakeups. In particular, avoid a race between the setup of the platform window returned by NewWindow and Window.Perform. (1071f561)
  • cmd: delete tools module. (4e6a9c09)
  • io/router: remove unused frect function. (aa140563)
  • go.*: upgrade github.com/benoitkugler/textlayout to v0.1.0. (a9a9a7c0)

Thomas Mathews:

  • layout: improve layout.List documentation. Updated the documentation for layout.List to include the details about how drawing is performed for items in it. This gives the user an understanding about how so many items can be drawn with good performance. (45e8c781)

Chris Waldon:

  • deps: update golang.org/x/text and go-text. Fixes a panic parsing language tags. (25fae8de)

gio-x

There have been 4 commits to gio-x since the last newsletter.

Non-breaking changes:

Mearaj Bhagad:

  • notify/android: update sendNotification to support Android 12(SDK 31) or higher. As per android official docs, it is required to provide the mutability flag for PendingIntent, which should be either PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_IMMUTABLE. Docs recommends using PendingIntent.FLAG_IMMUTABLE, and hence for simplification we are using PendingIntent.FLAG_IMMUTABLE. Allowing the api user to select the flag requires little more changes, hence left for later (9f76c90)
  • explorer: update ChooseFile WASM documentation. (f9e5afd)

Chris Waldon:

  • richtext: fix byte/rune offset mixup. This commit correctly converts a subslice operation to use byte offsets instead of rune offsets, fixing the output for non- ASCII data. Thanks to ~fabien for identifying the problem and suggesting a good fix! (1135178)

Andy Balholm:

  • stroke: use github.com/andybalholm/stroke. I had to adjust test thresholds to make the tests pass, because the output isn’t pixel-perfect identical to the old implementation, but there is no visible difference between the two (other than for TesttDashedPathFlatCapZNoPath, which I deleted because the new implementation has different behavior for invalid dash patterns). (f419638)

gio-example

A couple of small changes went into the examples repository this month:

Chris Waldon:

  • deps,7gui/*,life,gophers: update gio and global keyboard shortcut example. This commit updates to the latest gio and adapts all of the global keyboard shortcut handling examples to the recent changes in Gio’s keyboard event processing. (3f0fb59)
  • deps: require gogio using tools.go. This ensures gogio is available to build examples, and it helps lock the version of gogio used to be compatible with the version of Gio used. (b74c795)

gioui.org

We had a handful of small updates to the website as well:

Chris Waldon:

  • architecture: document how list handles large input. (28a0089)
  • content: document minimum supported android sdk version. (bf788e0)

Elias Naur:

  • cmd/giouiorg: add new gioui.org/cmd reference. (aa5d39c)

gio-cmd

The cmd repository is all-new:

https://git.sr.ht/~eliasnaur/gio-cmd

Elias Naur:

  • all: initial import from gio main repository. (6826ef0)