Newsletter, July 2024
Many Bugfixes and Reactive UI

This newsletter brings you v0.7.1 of Gio and associated repos. The minor version was incremented due to a very small breaking API change in the scroll gesture. The changes since v0.6.0 are mostly bugfixes within the windowing and event processing code.

Since the past newsletter, Plato Team has released the reactive database streaming code that powers their Gio applications into skel, a set of Gio application-building technologies maintained by Jack Mordaunt and me. This allows building SQLite-backed GUIs atop Gio with reactive data in the UI that automatically changes when the underlying database records change. You can check out the API for reactive streaming here and a simple example of a database-backed counter displayed in a UI here.

Sponsorship

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

Supporting the whole team:

Supporting a maintainer:

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

Since Gio v0.6.0, many folks have stress-tested our app.Window abstraction, reported bugs, and tested fixes. The result is a more robust window abstraction with a clearer lifecycle.

You may notice that no newsletter was written for v0.7.0. This was because we tagged the commit, then discovered some bugs that needed resolution prior to encouraging folks to update.

API Change: gesture.Scroll

gesture.Scroll now accepts two gesture.ScrollRange instead of an image.Rectangle. This prevents a pathological case in which rectangles with zero area did not behave correctly.

Where you previously called:

scroll.Update(
	gtx.Metric,
	gtx.Source,
	gtx.Now,
	gesture.Horizontal,
	image.Rectangle{
		Min: image.Point{X:-100, Y: -10},
		Max: image.Point{X:100, Y: 10},
	},
)

Now write:

scroll.Update(
	gtx.Metric,
	gtx.Source,
	gtx.Now,
	gesture.Horizontal,
	pointer.ScrollRange{Min: -100, Max: 100},
	pointer.ScrollRange{Min: -10, Max: 10},
)

Breaking Changes by Author

Elias Naur:

  • io/pointer: [API] split scroll bounds into two separate axes. A single image.Rectangle for the scroll bounds introduced a subtle issue with zero area rectangles (see #572). To avoid that and similar issues, split the bounds into two separate one-dimensional ranges. ee6cdec6

Non-Breaking Changes by Author

Elias Naur:

  • gpu: remove unused parameter. 477bd5c7
  • gpu: ensure opacity layers are rendered with correct pixel formats. FBOs and window framebuffers generally have different pixel formats, and so require separate pipeline configurations. 109226b7
  • gpu: fix viewport arguments for opacity layers. Fixes: #574 98d3a2eb
  • go.mod: bump minimum Go to 1.21. 42ef3476
  • .builds: bump builders to Go 1.22. 61b603d5
  • app: [macOS] ensure the Window is initialized before Run functions. Don’t call eventLoop.FlushEvents which in turn applies Options and executes Run functions before the window is fully initialized. 5083a233
  • app: [Windows] ensure the Window is initialized before Run functions. Like the previous commit for macOS, this defers event processing until after the Window is ready. 971b01d8
  • app: [X11] don’t send events after DestroyEvent. Before this change, a FrameEvent may be delivered after DestroyEvent, leading to a panic. Destroy the X11 window immediately thus ensuring no events can be delivered after destroy. ed288613
  • app: [Wayland] don’t send events after DestroyEvent. Like a previous commit for X11, this change ensures no events are sent after DestroyEvent. cf9f2bbf
  • app: [Wayland] suppress spurious ConfigEvents. As reported By Larry Clapp, Wayland would send a ConfigEvent with every FrameEvent when fallback client side decorations are enabled. This is because Window would call the driver Option and Perform methods even when they’re empty. e8c73bcb
  • app: [X11] add missing check for destroyed window. Fixes: #577 ba1e34e5
  • app: [X11] don’t recreate EGL surface during resize. According to #565 X11 GPU drivers don’t deal well with recreation of EGL surfaces. 691adf4e
  • app: defer window creation until Window.Event is called. We’re moving towards making Window.Event, and in the future, Window.Events create the window and drive the event loop to completion. In that model, the other Window methods shouldn’t create the window. a394b330
  • Revert "app: [Windows] ensure the Window is initalized before Run functions”. This reverts commit 971b01d836291105ee3dd15b7956e0b6c78756cb because Option and Run no longer creates the window. f6e33914
  • Revert "app: [macOS] ensure the Window is initalized before Run functions”. This reverts commit 5083a2330176f99b23d219b870c3dafdd354ce18 because Option and Run no longer create the window. b8821875
  • app: fix typos. 46cc311d
  • app: [macOS] panic if Main is not called from the main goroutine. 175e1344
  • app: [iOS] add support for buildmode exe. Up until now, the iOS part has relied on a tool such as gogio to synthesize a main function. This change adds support for running directly in exe mode, while retaining support for embedded Gio in C programs. e6da07a8
  • io/input: remove unused field. 56177c55
  • app: [macOS] ignore focus changes not meant for the Gio view. e878dbc5
  • widget: show software keyboard when a writable Editor is clicked. Extracted from https://github.com/gioui/gio/pull/138 by Inkeliz. 38fca9ae
  • .builds: increase file descriptor limit for Android’s sdkmanager. 026d3f9d
  • io/input: improve documentation, code. 706940ff
  • io/input: deliver all observed events before deferring the rest. Even when a command defers event delivery to the next frame, the already observed events must still be delivered in the current frame. This matters for pointer events that hit more than one event handler. 8fb6d3da
  • app: reset Window when DestroyEvent is received. Fixes: #595 42357a29
  • app: ignore Invalidate for Windows not yet created. While here, don’t overflow the Windows event queue. 3f671afe
  • app: use empty frame when FrameEvent.Frame isn’t called. 74ccc9c2
  • app: [macOS] fix ANGLE rendering. c900d58f
  • app: ensure Invalidate can be invoked when window is closing. This commit ensures that it is safe to invoke Invalidate() from another goroutine while a Gio window may be in the process of closing. It can be difficult to prevent this from happening, as window handles can easily be managed by a type that doesn’t know the exact moment of window close (it might be waiting on the window event loop to return, but that hasn’t happened yet). Without this change, the nil window driver results in a panic in this situation. 86349775
  • app: [Windows] suppress double-click behaviour for custom decorations. Fixes: #600 82cbb7b8
  • Revert "app: [Windows] suppress double-click behaviour for custom decorations”. 9018c071

Chris Waldon:

  • app: queue system actions before first call to Event(). This commit ensures that attempting to perform a system window action prior to the first call to Event() does not panic. It adopts a similar strategy to handling Option() prior to the first call to Event(): make a slice of the arguments and apply them during window initialization. 5542aac7
  • app: add cross-platform empty view event detection. Custom rendering applications need to be prepared to handle empty view events, as an empty view event is sent during window shutdown. However, the current implementation requires applications to write a platform-specific helper function for each supported platform in order to check whether a received view event is empty. This commit provides a safe, convenient, cross-platform method that applications can use to detect this special view event and respond to it. 4a1b4c26
  • app: [Wayland] prevent recursive scroll event processing. This commit zeroes the accumulated scroll distance on the window before invoking the event delivery code, since the event delivery code is able to call back into the scroll processing. Prior to this change, the callback could re-processing the scroll delta while magnifying it by a factor of 10. 6c19821a

Walter Werner Schneider:

  • internal/stroke: fix normal vector size. With this change the GPU renderer now properly handles the cases when the stroke width equals the stroke length where the normal vector is the same size as the original vector. 82422342
  • widget: add more editor shortcuts. 7a9ce519
  • material: improve progress indicator layout. Fixes: #570 0deb7b3e

Egon Elbre:

  • op/clip: add note about Path.End. 3b5148a6
  • go.mod: update golang.org/x dependencies. 7293fa8a

inkeliz:

  • pointer: fix documentation. Previously it uses event.Op{}, but such struct don’t exists anymore. Instead, it have a function with the same name. 1151eac0

Jack Mordaunt:

  • internal/gl: [Windows] allow GetProgramInfoLog to return nothing. If GetProgrami returns 0 we will panic because a zero-sized buffer indexed at zero will OOB panic: “runtime error: index out of range [0] with length 0”. 24b0c2a4

gioui.org/x@v0.7.1

X received updates for compatibility with upstream, bugfixes for the textfield and richtext, and multi-file opening on Windows.

Changes by Author

Chris Waldon:

  • explorer: [Android,iOS,macOS] fix view event handling. This commit fixes a build-time issue from the conversion of app.ViewEvent to an interface on these platforms. 9abe3b4
  • component: fix textfield animation state. This commit fixes a state bug in the textfield. If the textfield had text set and received focus on the first frame, it would accidentally skip over the logic that would transition the label into a header. While here, I eliminated several expensive calls to Editor.Len(). cbb21e2
  • outlay: update grid to new scroll API. This commit makes the Grid layout compatible with the new ScrollRange API on gesture.Scroll upstream. e22d4e7
  • go.*: update to Gio v0.7.0. a77f90e
  • go.*: update to Gio v0.7.1. df60cdc

Lajos Koszti:

  • explorer: add multi-file import for Windows. Intorduce the ability to import multiple files at once on Windows. 3152c15

Jefemy:

  • richtext: fix pressing event not being set to false due to early return. 481dd95

gioui.org/example@v0.7.1

Example was updated to compatibility with core and x v0.7.1. I also updated the opengl example to provide a simpler example of integrating Gio with an external renderer, and Egon fixed a windowing bug in the multiwindow example.

Changes by Author

Chris Waldon:

  • go.*: update to gio-x v0.6.1 for explorer bugfix. 4ca03a6
  • go.*: update gio and gio-x to v0.7.0. 8544e97
  • opengl: [Wayland] properly resize only the wl_egl_window. Previously we recreated the entire context in order to resize this one type, which was horribly inefficient on Wayland and deeply wasteful on other platforms also. 5f3af3c
  • opengl: [macOS] fix build. ec3ad4c
  • opengl: [Windows] fix build. 75ef8c6

Egon Elbre:

  • multiwindow: fix livelock in NewWindow. 4aa16fb

gioui.org/cmd@v0.7.1

Cmd gained some new build options for iOS and Android and was updated with the latest Gio.

Changes by Author

Elias Naur:

  • go.*,gogio: update to Gio 0.6.0. c9121dc
  • gogio: use buildmode exe directly instead of a Objective-C main function. Using buildmode exe directly is faster to build, avoids the runMain linker mode hack, and leaves more control to Gio instead of gogio’s synthetic main function. ddde16a

Chris Waldon:

  • go.*: update to Gio v0.7.0. d0d7f84
  • go.*: update to Gio v0.7.1. eb9fbc7

zhengrui:

  • gogio: [Android] add -targetsdk flag to specify the target SDK level. Fixes: #582 6465f30

giouiorg

Egon made a bunch of small improvements to the website and documentation. Thanks Egon!

Changes by Author

Egon Elbre:

  • include/files,content/doc: update to v0.6.0. 2132c27
  • go.mod: update example dependency to v0.6.1. 4ffdf41
  • content/doc/architecture/color.md: fix pre-multiplication note. Most commands use color.NRGBA, which corresponds to non-alpha-premultiplied colors. Internally it does convert to alpha-premultiplied linear colors. 3115c88
  • doc/showcase: add Anvil editor. c94e251
  • doc/showcase: remove tailscale. 82bb541
  • doc/showcase: add Chapar. ad75f64

End

Thanks for reading!

Chris Waldon