What do you mean by "specialist knowledge"? GObject interfaces are a fundamental part of GObject (and GLib in general), just like signals.
Perhaps you're more fluent with signals, but GObject interfaces is *far* from "specialist knowledge" if you're working on a glib application anyway.
To make a core feature plugin-replacable you have to change Geany anyway. Using either singals or interfaces requires knowledge about the GObject fundamentals.
signals are heavy weight because: - multiple options exist: connecting before, after, with object data (or without), with closure (or without). selecting the right one isn't always trivial. - from follows that dispatching is complex (especially with potentially multiple handlers), whereas interfaces boil down to a single vtable lookup much like C++ virtual functions. - glib has lots of extra code to handle blocked or recursive signals - connecting via string, which requires runtime look ups in various hash tables - you always have extra code that connects, in addition to the callback itself - passing arbitrary data to the callback is nasty, most of the time you need to malloc per-callback data structures
In addition they are tricky to use because: - most errors can only be observed at runtime (or even later), like connecting in an inappropriate function or connecting to the wrong signal (no compile time diagnostics support) - sutiable function signatures are not readily available, since the type of callback function isn't declared anyway
Signals are really meant for event-based programming. It can be used for extensibility purposes too, yes, but they are really overpowered for the task. Interfaces are much more lightweight and easier to use correctly (IMO).
BTW: We have the classbuilder plugin for setting up GObjects, it could be extended for interfaces.