pcb-rnd knowledge pool


GTK4 rant: API doc

gtk4r_doc by Tibor 'Igor2' Palinkas on 2021-12-02

Tags: insight, gtk4, rant, doc, API

node source



Abstract: Gtk4 API documentation is a good example on why doxygen-like "doc generated from source" systems are not too useful.

  This rant is part of a series.

The API documentation is mostly generated from source code comments. It sounds like a good idea: documentation coupled with code, so if the code changes, the doc is changed too.

... unless it's not. If a programmer won't go and edit the documentation in a separate file, he won't edit it in the same file. But the more common problem with this approach is "alibi documentation": when a lot of text is generated and saved as doc, but it's just noise and doesn't contain any useful information, or at least not anything that is not immediately clear from the .h file.


I generally dislike this idea, and gtk4 demonstrates my points well. To work around a gtk4 bug, I ended up using raw gdk events instead of gtk gestures. To do that, the widget needs a so called event controller object put on it. There are different event controllers, for raw gdk events the one is called legacy event controller Note how the documentation doesn't explain what sort of events it would deliver, where it is in the big picture. It mentions you shouldn't use it, but it doesn't say why, what consequences it may have to use this instead of gestures.

Next step from that page is checking the signal it will emit so you can write the signal handler: the legacy event . It doesn't tell much more than the function declaration and 2 lines of comment would, but at least has links to the next piece of information to fetch, which is: what is GdkEvent and how to extract event data from it.

The most trivial info to get is the x,y coordinate of the click, which can be queried using the gdk_event_get_position() call. The documentation doesn't tell much. It mentions the returned coordinates are "event surface relative", which really means they are in the coordinate system of the surface. But what a surface is and how is it related to your widget you have put the event handler on? No hint on this. Instead, long, redundant text explaining the same thing for x then again for y, which would both be trivial with zero words. What is not clear is why the function returns a boolean - now that would be interesting to explain, but no luck.

So let's say from some other source you understand what a surface is. A surface is the "drawing area" of a window. You figure you need to translate surface coordinates to widget coordinates. Figuring the keyword ("translate"), is absolutely not trivial, but once you have it, you can search the doc and find what you need: gtk_widget_translate_coordinates() .

Most of this page is just alibi doc, explaining that src_x is the X coordinate in src... The only two snippet of useful information are the common ancestor requirement and the return value. But this is really just one info: if the whole page had only the return value explanation, it would have covered all new information I've learned from reading the page.

But wait, this translates between two widgets, and not a surface and a widget. There's no pointer on any of these pages about how to do this. The solution is: there's a virtual root gtk widget for every surface and that widget is ancestor for any widget within the surface. So you need to query the root widget starting from your widget because it will happen to be exactly as big as your surface is. The call for that is gtk_widget_get_root() .

This page is a typical example of alibi documentation. It is explaining that gtk_widget_get_root(widget) will get the root of widget! What a surprise. At least it tells how corner cases work, which is good, most of the above calls didn't mention that. But it tells you twice that NULL can be returned while it tells nothing about what the root widget is. So you click on the Widget link, maybe the Widget class will explain - nope, it doesn't. But fortunately at the return value GtkRoot is a link, let's visit that, that surely explains!

Well, sort of. It explains a lot of things, but no connection or reference to surface at all. Remember, many recursions earlier our original problem we were trying to solve was simply translating surface coords to widget coords...

So all these window-surface-root-widget relations are things that can not be found in any of the above docs. Instead of explaining that "get_root will get root" or that "src_y is source y", such insight would be more useful. But that's much harder to write and can not be extracted from code automatically. So instead half of the doc is just autogenerated, longer version of "double x".