That approach isn't too surprising when the Go framework is, like this one, a Go wrapper on top of existing C code. And quite a lot of Go frameworks are that.
However, even ignoring the CGO-based frameworks, there's nothing wrong with mostly using Go as if it were C with closures (and garbage collection, and interfaces, and optional implicit typing and reflection), that's how most Go code looks, even in the standard library. Channels/CSP are great if you need to easily pass data among concurrent goroutines, but not all code neatly fits into that model nor benefits from concurrent execution.
One of the early mistakes most newbie Go programmers make (and I did this myself as well) is overusing channels, just because "hey, channels are super cool"!
You are not considering that most Go UI frameworks are twenty years of C/C++ and a couple months of Go. Naturally anything trying to do significant reinvention is not going to be as far along.
I use channels all the time in actual code using gotk3. Unfortunately, it means using glib.IdleAdd() a lot (because GTK is not thread safe), but it works.
People just lean to their comfort. I am an Erlanger -- so I tend towards channels. As people start doing more concurrently and the problems get more complex, dividing work among simple actors (or microservers depending how you break it up) becomes a great way of keeping complexity under control.