Recent gtk 3.98, Nim example fails to compile

While this example

was compiling and working fine with version 3.96

it now fails to compile. The reason is that objects like GdkEvent or GskRenderNode are now treated as GObjects, which is obviously wrong. We have now

    <class name="Event"
           c:symbol-prefix="event"
           c:type="GdkEvent"
           abstract="1"
           glib:type-name="GdkEvent"
           glib:get-type="gdk_event_get_type"
           glib:fundamental="1"
           glib:ref-func="gdk_event_ref"
           glib:unref-func="gdk_event_unref">
    <class name="RenderNode"
           c:symbol-prefix="render_node"
           c:type="GskRenderNode"
           abstract="1"
           glib:type-name="GskRenderNode"
           glib:get-type="gsk_render_node_get_type"
           glib:fundamental="1"
           glib:ref-func="gsk_render_node_ref"
           glib:unref-func="gsk_render_node_unref">

Unfortuneately I have not the older gir files available, but I think something has changed so that gobject-introspection reports that structures as objects, and in the bindings code it is then processed as gobject with all the toggle_ref stuff. And that is wrong of course.

So the question is, how can we by gobject-introspection differentiate between true gobjects and these objects?

[EDIT]

Maybe

https://developer.gnome.org/gi/stable/gi-GIObjectInfo.html#g-object-info-get-fundamental

is the solution?

Obtain if the object type is of a fundamental type which is not G_TYPE_OBJECT. This is mostly for supporting GstMiniObject.

OK, I will investigate that later…

Indeed it is a bit crazy:

    <class name="BlurNode"
           c:symbol-prefix="blur_node"
           c:type="GskBlurNode"
           parent="RenderNode"
           glib:type-name="GskBlurNode"
           glib:get-type="gsk_blur_node_get_type"
           glib:fundamental="1">

So BlurNode has a parent, but is called fundamental.

But for gobject-introspection checking for fundamental may work to discriminate from true gobjects.

This is not a GObject-introspection change, but a GTK change.

The reason why GskRenderNode and GdkEvent have been restructured to be fundamental types inheriting from GTypeInstance is that they are a the top of a hierarchy of derived classes, and thus cannot be boxed types; they also have immutable instances post-construction, no properties, and no signals, and are meant to be lightweight types, which means GObject is not appropriate for them either.

A fundamental type does not imply a type that does not have a parent; it means it’s a type that is not part of the existing type hierarchy. The “parent” attribute determines if a type has a parent.

Language bindings are supposed to support fundamental types and types inheriting from GTypeInstance, like GParamSpec and all its derived types, like GParamSpecInt, or GParamSpecString, or GParamSpecObject.

OK, then my guess was right, and I can use

https://developer.gnome.org/gi/stable/gi-GIObjectInfo.html#g-object-info-get-fundamental

to test if an object IS NOT a gobject. With that test the bindings should work again, thanks.

Two remarks:

https://developer.gnome.org/gi/1.60/gi-GIObjectInfo.html

The first text line is

GIObjectInfo — Struct representing a GObject

Maybe we should change that to “Struct representing an Object”

because when get_fundamental() is true then it is not a GObject!

And for the fundamental types like GskRenderNode

https://developer.gnome.org/gi/1.60/gi-GIObjectInfo.html#g-object-info-get-unref-function

seems to return NULL all the time. Well NULL is allowed from the docs, but it is a bit sad. So we have to guess, by scanning all method names for a name containing “unref” or maybe “free”.

[EDIT]

Or to make it more clear: For types like

GskBlendNode, BorderNode, CairoNode

I get always NULL for g-object-info-get-unref-function().

That’s a bug somewhere, then, because GskRenderNode correctly annotates the ref/unref functions:

 /**
  * GskRenderNode: (ref-func gsk_render_node_ref) (unref-func gsk_render_node_unref)
  *
  * A node in the render tree.
  */

and they are defined in the XML:

     <class name="RenderNode"
            c:symbol-prefix="render_node"
            c:type="GskRenderNode"
            abstract="1"
            glib:type-name="GskRenderNode"
            glib:get-type="gsk_render_node_get_type"
            glib:fundamental="1"
            glib:ref-func="gsk_render_node_ref"
            glib:unref-func="gsk_render_node_unref">

As far as I can see in libgirepository, the ref/unref functions are correctly included in the typelib blob; and if I call g-ir-generate Gsk-4.0.typelib, the regenerated XML contains:

<class name="RenderNode"
       abstract="1"
       glib:type-name="GskRenderNode"
       glib:get-type="gsk_render_node_get_type"
       glib:fundamental="1"
       glib:unref-function="gsk_render_node_unref"
       glib:ref-function="gsk_render_node_ref">

Derived types do not have the same information repeated, just like every GObject class doesn’t have all the information of the parent inside itself.

You’re supposed to walk the hierarchy backwards until you hit the top-most type, and use the ref/unref functions there.

OK, from

    <class name="BlurNode"
           c:symbol-prefix="blur_node"
           c:type="GskBlurNode"
           parent="RenderNode"
           glib:type-name="GskBlurNode"
           glib:get-type="gsk_blur_node_get_type"
           glib:fundamental="1">

I get the feeling that I have to use parent() to get the RenderNode and then may get the unref function.

So maybe call parent() as long as thre is one in the chain, and then call unref?

[EDIT]

Thanks for your reply, I noticed that myself. RenderNode has the unref function listed, but the chielts not. So my idea to call parent(), but of course there may exist a parent of a parent again, so I have walk upwards until there is no parent any more. It is a bit work, but may work. Thanks.

OK, fine!

[EDIT]

And indeed it works fine!

One remark:

https://developer.gnome.org/gi/stable/gi-GIObjectInfo.html#g-object-info-get-parent

does not mention that it returns NULL when there is no more parent in the chain. Well we can guess that, but most gtk functions say when they can return NULL, so it would not hurt when get_parent() would tell it too.

OK, it is late here already, will continue tomorrow. Should work all fine.

Tip: if you just want to agree/+1 to something and avoid the minimum character limit, press the “like this post” button.

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