GTK support for GNOME design patterns

Hi all,

For some time, I’ve been aware of issues around how GNOME’s UI design patterns are supported by the platform. These include:

  • Ambiguity regarding which design patterns are recommended.
  • When we do recommend patterns, or use them in our designs, they’re not always easy for app develeopers to implement.
  • It’s not always clear how each design pattern should be implemented.
  • It’s often hard for us designers to understand the limitations and constraints of each pattern.

This has various negative consequences. In the worst cases, the patterns are:

  • A lot of work for app developers
  • Inconsistent in appearance and behaviour
  • Implemented in a superficial manner
  • Difficult to maintain and update

Us designers bear a lot of responsibility for this situation, and I want us to do a much better job of both keeping within the bounds of the platform and creating a compelling designer/developer experience around it.

One obvious answer to the issues I’ve described is to review our design patterns to ensure that they are fully supported (and if they’re not, adjusting accordingly). This is an exercise that I’m already working on, but will need help from GTK developers.

There are some other issues that I’m less sure how to address, but which probably need discussion (this doesn’t necessarily have to happen here):

  1. Stability expectations for the design patterns, since I think we probably do want to iterate on a fair number of them.
  2. How we can differentiate between recommended and non-recommended patterns. Is it just a matter of design documentation, or do we need to do more?
  3. How to make the platform consumable by GNOME designers: for example, if there is tooling, documentation or examples that would allow us to use GTK for prototyping or mockups.

This post is mostly to let people know that this is something I’d like to work trhough in the near future, but of course any thoughts would be welcome.

Allan

8 Likes

One thing I’ve been thinking about is if we can provide “patterns” within Builder. We could extend our “New File” feature to contain templates of these patterns with a rudimentary implementation. It can create the composite widget, backing models, etc. It’d also allow us to deprecate them quickly or update them to new designs without breaking apps (because they are expand only). The downside is updating existing apps to the new patterns, but that might not be such a big issue if developers can C&P with a new design.

3 Likes

From the perspective of GTK as the toolkit, there have been various issues with making this process smooth, too. I’ll just use this post for the issues that I’ve seen, so this will be full of problems with no solutions. You have been warned! :wink:

  • Design patterns evolve faster than the toolkit

This is a problem in multiple ways. The one thing is that designs evolve faster than GTK major versions. When GTK 3 came out, the suggested way to do notifications was GtkInfoBar which are very unused today. Header bars have evolved into split header bars and GtkHeaderBar can’t deal with that at all.

But an even larger problem is that GTK often aims to support features even longer than that to provide a smooth porting path for applications written for previous versions of the toolkit. And that means GTK3 still supports GtkStatusbar for notifications and we still ship support for toolbars.

  • The toolkit wants to support a broader range of designs

There are more users of GTK than Gnome. This is meant both vertically in that other platforms such as XFCE or elementary use GTK (I’ll also list Windows and OS X here for completeness) as well as horizontally where GTK wants to be an attractive toolkit for applications such as Libreoffice, Inkscape or the Gimp. And while there is some overlap between Gnome’s design patterns and those use cases, there is often also quite substantial disagreement about things (two examples that come to mind right now are about if ~/Desktop should be featured prominently in the filechooser and how big the minimum button size should be).

  • development methodology is different

Due to GTK’s longer lifetime, expectations of bindability and so on, it takes a very conservative appraoch to development and exposing new features. This is very different from libraries like libgd, libegg, dazzle, GDL or libhandy which can play a lot more fast and loose with how they evolve. In particular, those libraries are often maintained by the developers of the applications they were originally made for, so they can respond way faster to any happenings in those applications’ development.

  • outside developers only look at GTK

From my experience, application developers who are not involved or experienced with the Gnome community who want to develop applications will only consider what GTK ships for their application development, they will not be aware of any extra libraries that may have already solved their problem.
A large reason I’ve been given for why people don’t look at other libraries is that portability (both to other desktops as well as to Windows) and they feel external libraries would make that harder.

1 Like

To expand this single point further: the usual answer is that people should bundle the copy of GTK they rely on—which is somewhat possible with Flatpak and recommended but fairly complicated to do on Windows and macOS. Unfortunately, on Linux, Window, and macOS we rely on what distributors provide, when they decide to provide it, and however they decide to update it. Sure, the GNOME platform runtime releases every 6 months, but:

  • Flatpak does not have deep penetration on Linux, and app maintainers still use whatever version of GTK is shipped on their long term support release
  • MSYS2 on Windows gets updated fairly quickly, but you get to keep both the pieces when something breaks, so app developers only update when strictly necessary
  • Homebrew and macports on macOS are super conservative because they still try to support architectures and OS releases that Apple ceased to support; this means they end up shipping weird configurations, or missing features to ensure the maximum coverage

So, in practice, what GTK delivers every 6 months may not be used by anybody for the following 12 months, at which point neither the toolkit maintainers nor the designers have received enough feedback to validate design or API. Hence, the conservative approach of the “rule of three”: in order to add something, at least three users must show up already using, or willing to port to, the same design/API.

2 Likes

The flip side of developers wanting stability and long-term updates is, of course, that we need GTK apps to be attractive to users: if we freeze our apps for years they start to look old-fashioned and uninteresting.

There needs to be some balance between the two opposing requirements (stability on the one hand and the ability to refresh and update our UI on the other), or some ability to reconcile both demands.

Regarding patterns that aren’t yet in GTK, I’d personally be OK with having a place to keep them that isn’t GTK. However, what I don’t want is to be recommending and widely using patterns that don’t have good technical support. So, if we have somewhere to keep widgets outside of GTK, then I’d want anything that’s added to be properly reviewed, maintained and documented.

This doesn’t resolve the question of what we can do with widgets that are already part of GTK, but maybe that’s something we can have a better discussion about once we’ve reviewed our existing patterns.

I’ve started work on the review here: https://wiki.gnome.org/Design/Whiteboards/DesignPatternReview

We should probably set up a call to talk it over…

The toolkit wants to support a broader range of designs

As an external developer i will always prefer create an applications that maximized the number of design-patterns where my application looks like ok. Because this will warranty that my application can look like ok in most of places. Also I will select the toolkit that will maximized that metric. In most of cases this means a toolkit that can create a very-very basic visual representation of my applications concepts. Because a very basic representation, in most of cases means a very commond representation.

A toolkit that constantly drop a design patter to use another new design patter, will not be selected by me, because will minimized the platforms where my applications will looks like ok.

I think that If a toolkit like Gtk want to be selected by more peoples, will need to ensure that things will be rendereds in base with the specif desing pattern of the platforms where the application is running. I think that is the best way possible and is what firefox is doing (rendering his features with base on the platform).

But yes, render the widgets with base on the specific platform desing pattern will be a very enormeus work to do by the application developers or also by the toolkit, if some how this type of things can be done fully internally to a toolkit.

So finally, to me have a toolkit with this abilities will be impossible and instead what will occurs with GTK is that we will have a toolkit that constantly is adding and dropping things with base on the design-patterns of an specific plaform (GNOME). Then to me this will reduce the possibility to ensure that my application will be displayed in a non GNOME platform acoording to his design-patterns and then will force me to select andother more standard toolkit or also continued the usage of an older version of Gtk while this other “supported” platforms also update his design-patterns to a more similar to the new one that GNONE now has (something that to me will be also impossible that will occurs some day).

Sounds like what Elementary OS does with Granite .

As someone who has lived through libegg, libgd, and written libdazzle, I would suggest very much against doing what I did with libdazzle (and Granite does for that matter) which is to create a shared library installable on the system. I’d heavily push towards using a subproject and statically linked library only.

Especially since we’re basically all on the Meson train and using subprojects is easy peasy.

3 Likes

I’d heavily push towards using a subproject and statically linked library only.

Out of curiosity, could you expand on why a shared lib is a bad idea here?

Distributions don’t really like it when you break ABI. And these sort of fast moving (by distribution lifetimes) design iteration almost necessitates that. Doubly so when you are doing things in coordination with new Gtk releases.

1 Like

Ah okay, so the lib can move as fast as app development does. I always thought the copy-paste approach of egg and gd was pretty terrible, but if updating the lib can be handled by a combo of git submodules and built as a meson subproject then it could be a goer.

It would certainly be useful for app development to have a library that implements current GNOME UX patterns.

1 Like

One of the problems with the static lib approach (other than the obvious: bugfixes can’t propagate automatically) is that it really complicates matters for apps that use language bindings. Maybe it’s fine for Gtkmm apps because you can just mix everything together, but for GJS or PyGObject apps it would add a lot of complexity.

1 Like

Bug fixes are taken care of by developing the library into a shared Git repository and using a Meson sub-project coupled with a Git sub-module.

Applications written in languages that require bindings to the C API can—and already do—build the library as a shared object and install it into a private location; they can also build the introspection data and install it into the same private prefix.

The equivalent of this for C applications is a static library, because C applications do not dlopen() their dependencies like language bindings normally do.

Building the C library as a shared object is an extra hoop to jump through for languages with dynamic bindings, whereas they just work with a pre-installed shared library with GIR data.

1 Like

Somebody has to build the shared library and the introspection data, and then install it.

See above the point that @chergert made about ABI stability in a fast moving library.

Somebody has to build the shared library and the introspection data, and then install it.

Of course, but ideally this would be done once by the distribution, not by every project written in Ruby, Python, or JavaScript.

See above the point that @chergert made about ABI stability in a fast moving library.

Distributions do have ways of dealing with ABI changes, as long as they are announced.

1 Like

Except they don’t. Few people would know this better than myself wrt GTK-based extension libraries that regularly have to bump GTK requirements because the bug fix is there, only to have distributions willfully stay behind.

This would be great :smiley:

One thing I’ve been thinking about is if we can provide “patterns” within Builder. We could extend our “New File” feature to contain templates of these patterns with a rudimentary implementation. It can create the composite widget, backing models, etc. It’d also allow us to deprecate them quickly or update them to new designs without breaking apps (because they are expand only). The downside is updating existing apps to the new patterns, but that might not be such a big issue if developers can C&P with a new design.

A short update on this!

We had a call between the GNOME designers and GTK developers a little while ago. During that call we discussed the general issue, as well as a couple of the design patterns, which we’ve subsequently done some more design work on.

I think the next steps are probably:

  • Development work to support the list patterns, including feedback to the designers if any aspects of the designs aren’t feasible
  • Development work on some initial changes to popover menus. This will need to be followed by a round of usability testing and design work.
  • Technical and design review of the other patterns where we lack support: in-app notifications, split headerbars, option lists, fullscreen, selection mode…

If anyone wants to know more, everything is documented on the wiki.