Terminal Emulation - Fun with a Go GUI

Part of my effort to maintain the Data General 32-bit minicomputer legacy has included writing free, open-source terminal emulators for the DASHER-series character terminals. I now have three such emulators: DasherQ - written in C++ and Qt - the original, maintained; DasherJ - written in Java and JavaFX - kinda deprecated; DasherG - written in Go using the Go-GTK GUI package - the latest incarnation.

Although functionally very similar (all provide serial and telnet access, DASHER commands, and DASHER function key handling), each has its pros and cons.

DasherQ relies on the Qt library, which is truly multi-platform and it runs just fine on Windows, Raspbian and many desktop Linuxes. The drawbacks (from my point of view) are code complexity and keeping up with changes in Qt - twice in the relatively short lifetime of DasherQ it has suffered bit-rot due to changes in Qt. As I delve deeper into Go I also find that I am less inclined to maintain C++ code.

DasherJ was really a port of DasherQ written to revive my flagging Java and learn the (then new) JavaFX. It works and is fairly performant, but I found some of the JavaFX abstractions quite strange and non-intuitive to use.

DasherG

As I am gradually moving most of my DG-related code over to Go, it seemed to make sense to try porting DasherQ/J to the language, so DasherG was conceived.

There were two major factors to consider prior to the port and I don't consider either of them finally resolved at the moment.

GUI Library

At the time of writing there is no 'official' GUI package for Go, and - as far as I know - none of the many available libraries are particularly recommended by the Go authors. There is a good list of the main available libraries here at Awesome Go.

Some of them use Qt and I tried two of those; as far as I recall it was a royal pain to set up the development environments for these, and build/debugging/deployment times were a bit grim. IIRC one of them tried really hard to force me into writing OO Go, so that went somewhat against the grain with me.

I didn't fancy learning any of the JavaScript-based variants, and the attempts at a native library looked really interesting, but one was deprecated and the other non-maintained (as of late 2017).

So, after several false starts, I settled (for the time being) on Go-GTK. The lead author states that Go-GTK is a work-in-progress but there is “enough to run general application[s]” - in my opinion he is right. As GTK was originally written in and for the C language, and does not take an obsessively object-oriented approach to GUI creation - so it seems to me to be a good candidate for a Go GUI.

I have found Go-GTK relatively straightforward to use. All my GUI code is in one source file and should I ever decide to change toolkit I don't think it would be a massive effort to rework just that code. GTK is (by modern standards) a relatively lightweight library and I was pleasantly surprised how little GUI code was needed for the application.

The main issues I encountered during development were with GTK's very strict threading expectations and idiomatic use of Go's goroutines clashing a little. One just has to be really meticulous about ensuring that anything at all GUI-related happens on the main (GTK) thread.

I hope that Go-GTK flourishes, but I am not overly worried about the prospect of changing to another library if one becomes dominant or very well supported in the Go universe.

Serial Library

I was surprised to find relatively poor support for serial I/O with Go. There are a handful of packages (including one by an eminent gopher) out there, but most are overly simplistic for interfacing with legacy hardware. Again, I tried out a few options and have settled on one: go-serial. It is not perfect, but I chose it as it is actively maintained and provides most of the features I need. The one thing I still need is the ability to send a serial BREAK signal, so I have raised an issue for that and we will have to wait and see.

Conclusion

At the beginning of 2018 writing a standalone desktop GUI application in Go is certainly possible although possibly not wise if you are developing an mission-critical or standalone application.

Comments

Popular posts from this blog

Writing Better Go: Code or Data?

Lessons Learnt: Porting an application from Go to Ada