Sorry not to be clear, DEFINING new GObjects is what is not so common, its no longer even in Glib.
I don't understand that. GObject is part of GLib. GLib makes heavy use of GObjects and interfaces.
How do you need any GObject knowledge to emit signals? eg https://github.com/geany/geany/blob/master/src/document.c#L711
That's just emitting. That doesn't show defining the signal (see geanyobject.c), or the modifications required to a given feature to be replacable or extensible through a signal (or other means).
Calling an interface is equally a one liner (with added compile time checks): `my_interface_method(object);`
I admit that defining an interfaces requires some boilerplate. Signal definitions also require boilerplate, but less of it. Both can be automated with classbuilder or even snippets (both shipped with Geany itself). Part of the interface boilerplate is clear function signature declaration that allow for compile time checks, though.