
Gotk3: GTK3 the Go way - djpressplay
https://blog.conformal.com/gotk3-gtk3-the-go-way/
======
georgemcbay
Glad to see some more work being done on UI frameworks in Go, though I doubt
this will end the splintered nature of all the different (mostly half-baked,
honestly) options.

I've personally been using a Qt5.1/QML based solution with a Go/CGO based QML
plugin that acts as a bridge between QML and backend Go code. It doesn't try
to export much of Qt to Go, it basically expects you to write the UI logic in
QML/QtQuick and then just use Go for the underlying app logic, using the QML
plugin bridge to allow Go code to call QML functions and vice-versa. In
practice this works somewhat like writing a Go server that manages an HTML UI
for doing browser-based UIs with a web-based RPC system, except I can write
the UI code in QML which I find much preferable to HTML/JavaScript (variable
binding Just Works, no need for frameworks like Angular, no need to mess with
CSS, can efficiently pass around binary data in byte arrays easily, etc).

Currently my solution isn't even half-baked, I've been implementing it to
serve a specific app, and it currently has some dependencies that force it to
be Windows only (these could be trivially removed, but doing so isn't
important for my app). I may share the code for this sometime in the future
after it has matured a bit more, though there's really not that much to it.

~~~
asb
I'd also love to see some source to get an idea of how this works and what the
binding code you end up writing looks like.

------
quacker
Slightly off topic, but something I've been curious about. Go decided on
garbage collection to manage memory. Why do so few languages offer something
like C++'s RAII?[1]

In C++, when you define a class, you define the constructor(s) and the
destructor. Then the destructor is called whenever the object goes out of
scope. Easy. This is the gist of RAII. Furthermore, in C++, a default
destructor is automatically generated for you, which will ensure all the
objects members are destructed with your object,[2] so you can avoid even
worrying about the destructor.

Yeah, it's not as simple as GC, but it seems like a great compromise between
manual memory management and garbage collection.

[1]:
[http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial...](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)

[2]: Provided no members are dynamically allocated. If you allocate an array
in your constructor, for example, you need to free it in the destructor. You
need to define a destructor to free dynamically-allocated memory, or to do
other cleanup.

~~~
pcwalton
Preferring RAII over garbage collection is the decision that Rust made.

Probably the reason that more languages don't use RAII for memory management
is safety. C++, even with RAII, is not safe—you can violate memory safety with
certain uses of references and iterators. Rust has to go to great lengths
(lifetimes and the borrow check—things that have only been in the research
landscape) to make this safe.

~~~
jrick
I'm actually a huge fan of Rust's memory model and wished Go had something
similar, since it's faster to use smart pointers, and less calls to the
garbage collector are required. I also love how rust uses three different
kinds of pointers depending on how the memory is managed, and although it adds
some complexity, it gives more semantic value to the data you are working
with.

Unfortunately for me, the rust compiler is written in rust, so I would have to
adventure to grab a Linux and try my hand at a cross compile before I can play
with it on my OpenBSD box.

~~~
kivikakk
Or just install it on a Linux VM!

------
yebyen
I am on ubuntu raring with the packaged golang and I can't compile your
example code, copied directly out of _Sample Use_.

    
    
      kbarrett@vernon-linux:~/go-work/gotk$ go version
      go version go1.0.2
      kbarrett@vernon-linux:~/go-work/gotk$ go build
      # github.com/conformal/gotk3/glib
      glib.go:380[/tmp/go-build210667265/github.com/conformal/gotk3/glib/_obj/glib.cgo1.go:370]: function ends without a return statement
      glib.go:743[/tmp/go-build210667265/github.com/conformal/gotk3/glib/_obj/glib.cgo1.go:741]: function ends without a return statement
    

function ends without a return statement. If this is a problem with my version
of go, I will try and fetch the latest head from git. I am interested!

sudo go get github.com/conformal/gotk3/gtk -- gives the same error.

~~~
jevinskie
Yes. I think that syntax became legal in 1.1.

~~~
yebyen
I see, ubuntu's go is very old. You can tell I'm not doing this stuff every
day. (It's obviously because I'm on a release from April...)

I'm going to try it on FreeBSD.

~~~
yebyen
(That worked.)

~~~
brunoqc
If you want the latest Go version on Ubuntu :
[http://blog.labix.org/2013/06/15/in-flight-deb-packages-
of-g...](http://blog.labix.org/2013/06/15/in-flight-deb-packages-of-go)

~~~
georgemcbay
You can also just build tip on your own locally. Go has virtually no hard
dependencies other than gcc (and mercurial to get the repo, unless you pull
the code some other way).

    
    
      hg clone http://code.google.com/p/go
      cd go/src
      ./make.bash
    

(or ./all.bash if you want to run all the unit tests)

Same holds true even on Windows if you have a local gcc like MinGW (the only
notable difference is you'll execute make.bat instead of make.bash if you're
in a Windows cmd shell instead of bash).

~~~
dougbarrett
Google also distributes binaries for Linux, for me all I do is unzip the file
and set up my .profile to look for go in the path it was exported in..I set
this up on a per-user basis but it works fine for me.

------
acomjean
I was kinda meh on Go (reminded me of my days in the Ada code), but making
native GTK Apps seem really interesting to me. Will have to check this out.

~~~
dysoco
I'd say both Go and Ada are much nicer than C and C++ though :P

------
joeshaw
No mention of goroutines or concurrency in the post. Is it addressed by the
project at all? I can't imagine that the GTK main loop will deal well with
being cooperatively scheduled -- the UI would block any time another goroutine
ran on the same OS thread.

Ideally the GTK main loop would run in its own OS thread, and there would need
to be a way to ensure that no GTK calls happen in other goroutines. Other
(threaded) environments tend to handle this by deferring via a one-off "idle"
function that is scheduled and run by the GTK main loop for things like that.

~~~
jrick
We do try to deal with concurrency and goroutines as much as we can. I'd
recommend taking a look at the (rather simple) goroutine example as part of
the gtk package. Unfortunately though, as you said, GTK is not thread safe
(calling GTK from multiple threads was deprecated as of the last release I
believe) and calls must be made using glib.IdleAdd() to run the functions in
GTK's main loop context.

------
pionar
Does anyone else think we need a new open-source widget toolkit? Qt, GTK, and
what else is there? Those guys are old. I've done both, and WPF, and WPF is
just so much better. I wish there was an open-source toolkit that didn't just
suck.

~~~
coldtea
Yes, most are old and tiered. But another problem is, there is not a
company/organization or even language community to take on such a big
endeavour.

I'd like to see a C based toolkit, that's made specifically for wrapping it up
for other languages (in C++, Ruby, Python, Go etc) and has niceties to help
with this.

~~~
matthiasv
> I'd like to see a C based toolkit, that's made specifically for wrapping it
> up for other languages (in C++, Ruby, Python, Go etc) and has niceties to
> help with this.

This is exactly, why GTK+ and essentially the whole GNOME stack is now
introspected with GObjectIntrospection. So, there you have it.

------
sesteel
How is this different than this? [https://github.com/norisatir/go-
gtk3](https://github.com/norisatir/go-gtk3)

They also set finalizers.

~~~
jrick
In short, we weren't aware of the project.

I just gave it a try now, but the code will not compile on my dev box
(OpenBSD, go tip). Even after making some minor fixes (I fixed an #include
directive, removed a call to a deprecated function, etc.) there appear to be
some serious issues (one error I got mentioned the size of an array being
negative).

It appears this code has not been updated in a year, and we wished to target a
recent GTK version (3.8, to be precise) with our bindings. Had we known about
the project, we probably would have considered submitted patches to fix its
issue and bring it up to date with newer dependencies, but even then, I feel
that it would be almost as much or perhaps even more to fix and verify an
unfamiliar and broken code base than rolling our own.

But I'm glad to see this project seems to be doing memory management in a Go-
like manner.

~~~
sesteel
Just to be clear, this isn't my project, but it has been working fine for me
for awhile now, but I am probably not exercising the same pathways as you.
Anyway, I have written additional bindings for the Gtk Docking Library and the
Syntax Highlighter against this project. Everything compiles, runs, and works
well.

It is a little frustrating as it is one of the first projects that comes up
when searching for "go" and "gtk3" on Google. So, it is is an alternative to
what you are doing I guess.

~~~
jrick
Actually, some of my coworkers had tried it previously and couldn't get it
working either. I just didn't know they had tried it, and they didn't ask me
to play around with it to try and get it in shape (this may have been before I
started working full time with Conformal).

So this was just me not being aware of it, but others of us at Conformal were,
and due to the above issues we decided to do our own.

------
prodigal_erik
Are channels and CSP failing as the favored design approach? I keep seeing
frameworks that just seem to use Go as if it were C with closures.

~~~
georgemcbay
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"!

------
bratsche
Nice! Have this queued up to look at after work. :)

------
jlgreco
Hmm, does the name "GTK" mean "Gnu Tk"? I thought this was "Go Tk" for a
moment when I read the title.

~~~
zandorg
GIMP toolkit, as in the graphic package.

~~~
mortdeus
it is gimp isnt it.

------
dysoco
I was thinking of writing a small aplication, originally I was going to use
Python... but might as well try this. Thanks.

------
gophering
Just tested on win7 and everything works great! Really nice work.

