Saturday, 1 June 2013

Proposal for a GUI Toolkit for Go

The Situation

This isn't a unique topic. It's come up in the mailing list before.

Let’s face it, while Go is a general purpose programming language it is ultimately a systems language. It was designed to be concurrent. It was designed to write servers. It was designed to provide a back-end to other services. It does those things pretty well. There is, therefore, an area where Go is lacking and that’s as an application programming language.

This isn't because Go as a language isn't suited it to but that it's standard library doesn't include a crucial component: a UI toolkit. A few people have blamed Google (which makes no sense because Go is not actually a Google project) and the Go developers for this but honestly, it's not their problem. It's not what Go was designed to do nor are the current devs experts in UI design.

Who’s responsible then?


To be honest, there have been a few attempts already, each with their own merits, but I think all these solutions still fall short of an ideal GUI for Go. So, let me tell you why I think this.

What We Have and Why They Don’t Work

1. GTK+ or another UI Toolkit Wrapper

The easiest, most obvious choice is to create a wrapper for an existing UI Toolkit because of cgo and SWIG. GTK+ fits the bill and mattn has begun this work already. However, there's a problem. For one, GTK+ is C-based. No matter how well the wrapper is designed I don't think it will every feel very Go-like. The toolkit itself is a beast, too. It has thousands of function signatures in it’s API and will take a fairly large concerted effort to completely implement it. More importantly, however, I don’t think this is the right choice and I'll tell you why.

Using GTK+ means that users will need to install it if they don’t have it already. For Linux users, this usually isn't a problem but what about Windows and Mac users? Now we have a problem. I’m a firm believer that you shouldn't force users to install things onto their computer just to run your application unless it's absolutely necessary; and, it makes the installation process more complicated. There is, of course, a solution by including the GTK+ source into the dev tree but we're not talking something like sqlite3 where this can be done easily. GTK+ is massive and I just don't see this as being a feasible solution.

2. GoWut or another HTML Server

I think GoWut is a great idea with what I think is one glaring flaw: it’s a web server. For a single user application, it doesn't feel right. For one, the server doesn't shut down after you’re done using it. Yes, this could be considered a feature because it would reduce load-time of future invocations and you can have user sessions but to me it’s a problem. As an end-user, I don’t want a terminal hanging open with a server running in it. I certainly don’t want all my applications each running it’s own server hogging up my resources, just waiting to be accessed again. I'm sure you could have a 'quit' button to shut down the server but that just doesn't feel right.

3. Go UIK

A native UI Toolkit designed to work like an idiomatic Go library from the start? Sounds awesome! The problem? It’s not done, yet. It’s still in the early design stages but certainly something I’m going to watch for. I think this project has a lot of promise and I look forward to seeing how it turns out. Another issue might that it is going to use a custom widget design rather than a look and feel native to the OS. If, however, it looks pretty enough I’m sure I can overlook that.

4. GoWebkit

Now we’re talking. This to me feels like a more natural solution than a wrapper for another Toolkit. Open a basic application window with webkit embedded in it? Fantastic! This solution comes very close to the mark with one glaring issue: it uses GTK+ as a back-end. The other issue is that it's not a UI. You will have to have some HTML and CSS skills to actually create anything with it and I don't think that provides a very unified solution.

The Solution

Webkit + Native UI Backend + HTML + CSS + (YA/X)ML

Existing technologies mixed together to provide a hybrid result. I think we need a UI Toolkit that uses the OS’s native windowing mechanism (Win API for Windows, Cocoa for Mac, X, GTK+ or Qt for Linux), maybe using John’s WDE library, an embedded webkit renderer, with an API akin to any traditional UI Toolkit complete with event handling. It should allow for customizable CSS elements and, the icing on top, a markup language UI layout design utilizing something like XML. feels like I've just described Android’s UI toolkit...

Of course, this needs some rationale.

1. Native UI Backend - Go is multi-platform. A UI toolkit should be as multi-platform as possible and not require end-users install additional toolkits onto their system. Many application designers will want to control window sizing and else-wise have control over them, like having modal windows. Javascript could provide some of this behavior as well.

2. Webkit - Creating a custom toolkit from scratch, including widgets and all the rest is a colossal undertaking. Qt, GTK+, Win API and Cocoa took an incredible, collective effort to create. Webkit would allow us to circumvent this effort by using a UI that already exists: HTML5 and Javascript. Is this an ideal solution? Maybe not but it’s a reasonable solution that wouldn't require the herculean effort to create a full UI from scratch.

3. HTML + CSS - I think GoWut has a good idea here. Default widgets and creation mechanism so devs don’t have to write HTML and CSS if they aren't skilled in those areas. There is a request in another toolkit's issue tracker requesting ‘nicer’ CSS style to be used by default which I think is a good idea. All a dev would have to do to make their UI unique or make some minor alterations is edit the existing CSS. Or better yet, have an override system in place so that the built-in CSS wouldn't need to be altered. I think adding a custom CSS file shouldn't require injecting an html string with a link element as it does with GoWut but rather a simple API call of SetCSSFile() for a much more elegant and less error prone solution.

4. XML or some other markup language - Android uses this mechanism and so does GTK with GtkBuilder/Glade. I think the reason for this is twofold: a) a UI can be quickly generated by hand without cluttering up the application itself with hordes of API calls for creating widgets; and b) it allows for the use of visual GUI creation tools for building UI’s, akin to Qt’s QtCreater or GTK+’s aforementioned Glade. Like Qt and GTK+, I’m not sure this should be the sole method of building an application UI but rather a complementary one to a standard API. I suggest XML only because I know it's used in existing solutions like Glade/GtkBuilder and Android.

Is this the best solution? Good question!

Conventional languages for writing applications seem to rely on either an existing native toolkit (Tk for TCL, Swing/JavaFX for Java, GTK+ for C or Qt for C++) or a language wrapper for a non-native toolkit. However, most of those tools are either language specific (Swing/JavaFX) or are encumbered by methods for handling situations native to their own languages that don’t play nice with Go (concurrency/threading). There might be ways to overcome these limitations but there you have it.

There are a lot of existing resources for HTML and CSS. I think it would be far easier to find someone proficient in these technologies to help in such an endeavor than it would be to work on some of the other solutions. As a further plus, most of the groundwork has already been done. By combining something like wde for a backend and webkit to render pages then we already have the canvas on which we can paint. By adding in elements of gowut on top, minus the server aspect of it, we essentially have the end product. Add in a dash of CSS to pretty things up, XML for widget creation and layout and we’re done. Sounds easy huh?

Probably isn’t but I think it’s easier than the other solutions with a better end result. It would feel more idiomatic to Go, build on existing technologies, and make for an easy transition for a wide audience (those who are already familiar with HTML, XML and CSS).

I'd love to see some input.