GTK 4 and subclassing

I’m struggling a bit with a GTK 4 migration, currently my topic is subclassing.

On Custom widgets in GTK 4 – Introduction – GTK Development Blog you can read:

The general direction of our API changes has been to emphasize delegation over subclassing. One of the motivations for this is to make writing your own widgets easier and less error-prone. As a consequence, you will see a lot more auxiliary objects that take over aspects of functionality from core widget classes. And many widgets are now final classes – deriving directly from GtkWidget is expected.

Frankly I don’t understand why it’s easier to write your own widgets if you can’t build on top of existing ones. I have a widget derived from GtkScrolledWindow, the important part is of course its content, a waveform in this case. In GTK 4 this is a final type. I understand I have to take my content, add scrollbars myself and do all the things that make up a GtkScrolledWindow. That’s much more error-prone than before. – Or should I derive from GtkWidget and add a GtkScrolledWindow as a child?

I also have a custom GtkAssistant. Nothing fancy, GtkAssistant is just a template for all the content of my assistant. Like it’s a common pattern for preference dialogs to subclass GtkDialog or GtkWindow as MyNamespacePreferences. Or almost every app has its MyNamespaceWindow derived from GtkApplicationWindow. Why is it bad to subclass GtkAssistant in the same way? Is there an advantage in maintaining GTK or is better for users – or maybe even both, but why?

Generally speaking, yes: if you want to have your own class, with your own children, then it’s recommended to create your own widget and use GtkBuilder templates to create the composite UI you want.

Because GtkAssistant is a very, very specific type of window, with a lot of assumptions baked into it, unlike GtkWindow and GtkApplicationWindow, or GtkDialog. You may also notice that GtkMessageDialog is not derivable.

The appropriate way to use GtkAssistant—even in GTK3—is to have specific subclasses for each of the pages inside it, instead of a subclass of the top level container. You’re not going to change the behaviour of the Assistant, so there’s no point in creating your own type for it.

Of course, since taking a “final” class and making it derivable is not an ABI break, we can make make some widget classes derivable once again, depending on the amount of requests we get. Since the other way around is not possible without an ABI break, we preferred to start from an appropriate clean slate.

As I said, though, the general approach we recommend is to create your own widget types by starting from a base class and using composite widgets, instead of deriving from a complex widget. This is why we made GtkWidget easier to derive from, compared to GTK2 and GTK3.

The advantage for toolkit maintainers is that the internals of complex widgets stay constrained within the widget, instead of being encoded into the API without possibility of change. This allows us to keep the toolkit API and ABI compatible for longer, and reduces the amount of potential regressions introduced by complex changes.

The advantage for application developers is that they won’t have surprises if a complex widget changes.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.