📝Gio event handling

Gio uses the Ops to subscribe to events as well.

var tag = new(bool)
var pressed = false

func doButton(ops *op.Ops, q event.Queue) {
	stack := op.Push(ops)
	defer stack.Pop()

	// this will iterate over all events that occurred since the previous frame
	for _, ev = range q.Events(tag) {
		if x, ok := ev.(pointer.Event); ok {
			switch x.Type {
			case pointer.Press:
				pressed = true
			case pointer.Release:
				pressed = false

	// Limit the area of interest to 100x100 rectangle
	pointer.Rect(image.Rect(0, 0, 100, 100)).Add(ops)
	// Subscribe for Press|Release events using tag
		Tag: tag,
		Types: pointer.Press | pointer.Release,

q.Events will return all the events that occurred since the previous frame. The zone of interest is limited by pointer.Rect.

That’s nice because it solves a couple of problems:

  • widgets uniformly receive all events since the last frame
  • widgets don’t have to boundary-check mouse position and clicks, or fight for the focus
  • less state for the gui library: don’t have to track focused widget, store last known mouse position, etc.


  • widgets should store more state (e.g., whether they are pressed or not)
  • the gui library must track all registered widgets in the last frame and do boundary checks, priorities, etc.


Want to receive my 🖋 posts as I publish them?