[Geany-devel] GObject, new plugin interface ....

Lex Trotman elextr at xxxxx
Thu Mar 17 08:17:21 UTC 2011

On 17 March 2011 17:56, Matthew Brush <mbrush at codebrainz.ca> wrote:
> On 03/16/11 22:25, Lex Trotman wrote:
>> Hi Matthew and All,
>> @Matthew, I've looked at your dbus repo.  I might not have understood
>> how you were relating it to this, but to me it looks like you are just
>> using the old plugin interface, rather than anything to do with a new
>> interface.
> It's very bare still, but there are some things going on which fall into
> line with the GObject interface.  The only real reason it's been
> referred to is that it 1) provides a GObject wrapper/C API around the
> current plugin API emitting signals from the right objects, using real
> properties, etc, 2) (will) provide a shared library that bindings/clients
> can link to, and 3) provides process isolation.  Other than those ideas it's
> so incomplete/new as to not be too relevant.  I'm actually not really
> planning on working on it until after there's a new GObject interface to
> Geany, since afterwards, it would be just a matter of inheriting from a few
> classes and tacking on GDBus stuff.

Makes sense.

> Unfortunately, there is some context around this which has been discussed
> around the geany-vala-binding, that a lot of which wasn't on a ML.  It's
> very easy to summarize some of the ideas I've had/heard so far:
>  - The geany-vala-binding should be sort of a "raw" wrapper around
>    the existing plugin API, providing simple access from Vala code.

Not sure about wrapping the existing plugin interface, see below

>  - There needs to be a GObject wrapper around a lot of the
>    existing stuff where it makes sense, since a lot of it is
>    sorta OOP in design.  This could use Vala to generate all of
>    necessary boiler-plate GObject C code and allow doing things
>    like ABCs and interfaces without gobs of (hand-written) code.

Well anything to avoid writing GObject code in C has my vote :-).  My
only comment is that my (limited) look at the Vala docs seems to be
lacking in documenting how to wrap existing C interfaces that don't
introspect properly. Eg  I couldn't find what goes in [CCode...].
Might be just my searching of course :-)

>  - Signals for the plugins need to be emitted from the
>    appropriate objects. rather than the current central
>    GeanyGObject which is has all the signals.  An example would
>    be that the "saved" signal should be on a Document object.

Totally agree, but this is where using the existing plugin interface
is deficient, very few signals are provided.  But core will have to be
changed to emit more.  I don't really see that as a problem, adding
emits in appropriate places should be no problem, but it does imply
that then core can see the GObjects so it can emit on them, again I
don't think the existing plugin interface provides much support for
making things in the plugin visible to core.  Also when to create and
delete the GObjects.

>  - The API should enforce read/write access on the objects
>    via properties/accessors.  The current API just exposes raw
>    struct members, certain ones which, when set would result
>    in strange behaviour in Geany.  The current API does have some
>    getters/and setters though they aren't really consistent.  For
>    an example of how the Vala binding is wrapping this
>    inconsistent access, see [1].  The point of the DBus binding
>    directly wrapping the Vala binding was to make it a true
>    GObject API, where the Vala binding just provides a window to
>    the existing raw C code (more or less).

Yes, I expect that there will need to be a Vala binding of whatever
parts of core are needed so that the GObject implementations can use

>  - Libpeas[2] should be used as the actual plugin finder/loader.  It's
>    a GObject/GLib library designed specifically for finding plugins
>    in different languages, loading their interpreter, and doing
>    stuff like activation/deactivation.  It seems Gedit is using this
>    as well as several other popular GNOME-ish programs.

Looks like it might be helpful, how easy it might be to get it to work
alongside the existing plugin manager (so we get one UI) I don't know.
 Remember we don't want to chop existing plugins off.

>  - There is a huge namespace clash with the current plugin API, in
>    order to use sensible prefixes and class names.  Nothing in the
>    new interface can be prefixed with Geany, geany or GEANY, which
>    of course would be the sensible prefix for an API.  The new
>    interface would have to use something like GeanyLib or LibGeany
>    or whatever, and then in the language bindings the namespace
>    could be whatever (except in Vala where there will still be
>    collisions).

Hmmm, yes, geany_interface etc. I'm sure we'll argue our way to some
agreement eventually :-)

> I think that roughly sums up the discussion I've heard so far that may or
> may not have been on this ML.
> Why all the discussion around Vala[3]?  It's just *really* nice for
> generating GObject C APIs, like GOB2 on steroids.  It can output C files so
> that users are not require to have the valac compiler installed, it also can

Users not needing Vala is very important so this is all good.

> output C header that can be installed like headers are with any other
> library for use by C code.  My personal opinion is that it would be ideal to
> use Vala for the new GObject interface, at the very least to get something
> working, and then possibly port it bit by bit into hand-crafted C (though
> valac's C is pretty clean considering).

Lets try not to have premature optimisation :-)

>> @All,
>> Having reviewed what has been said in the thread to date, there is no
>> real substance, so I think its likely that we may be talking about
>> subtly different things.  So to start the ball rolling here is an
>> initial description of what I understand as the aims of this work and
>> how I see it possibly being implemented.
>> As I see it the purpose is to define a new plugin interface to Geany
>> that exposes all the required machinery through a set of GObjects
>> which can be (semi) automatically interfaced to languages other than
>> C, allowing Geany to have plugins written in multiple languages.
> Using GObject-introspection hopefully in most places[4].

The issue with that IIUC the stable version will be for GTK-3 and
since Geany still supports GTK 2.8 its got a *way* to go before it
gets to 3 :-)

>> This new interface should provide at least the capabilities of the
>> current plugin interface.
> Agreed.
>> The way I see it being implemented, is not to change Geany's existing
>> C structures into GObjects, rather, that the GObjects provide an
>> interface to the existing C implementation and may not even map one to
>> one with the existing structures.
> This is in line with the previous discussions, especially the
> geany-vala-binding providing Vala access for the GObject wrappers to use.  I
> agree that in quite a few cases it won't (or shouldn't) map 1:1 with the old
> API.
>> This has several advantages,
>> 1. the interface is somewhat isolated from the Geany implementation,
>> allowing the implementation to evolve without causing a change in the
>> interface seen by plugins.  The current plugin interface is so thin
>> that it is easy for changes to Geany to affect the interface.
>> 2. the impact on the core implementation is minimised, so the impact
>> on anything else happening in Geany itself is smaller.
>> 3. The interface can be defined such that it is easy for plugins to
>> use, independent of the underlying implementation

I should have added that, yes this may add some overhead, but to put
it into perspective, its nothing compared to the amount of code
executed in Scintilla, GTK, X-server and graphics driver to re-display
the screen so it shouldn't be any problem.

> I studied the code in documents.{c,h} a bit just to see what it would take
> to convert a GeanyDocument into a GObject.  My observations were that it
> would a) require an almost complete re-write of that code, b) completely
> mess with the existing plugin API as well as tons of stuff in the core that
> uses GeanyDocument's and c) that it would bloat the code up so much that I
> don't think it would fit with Geany's "fast and light" philosophy.  So your
> #2 point is really important I think.

Yes, and GeanyDocument is the most obvious object, some of the others
may be cross-file.

>> I see the GObjects as simply containing pointers to one or more of the
>> Geany structures and the methods each being just a few calls to
>> existing functions that operate on these structures.
> Yep, and wrapping them up in GObject properties and signals so Gobject
> introspection can do its magic in making the higher level language bindings
> idiomatic (or I guess OOP-ish, since it's roughly the same in most languages
> I know).

Well getters and setters rather than properties, IIUC GTK is heading
towards hiding properties or at least making them read-only.

>> There will still need to be code added to the existing implementation
>> since it needs to create and destroy the GObjects as required and will
>> have to emit signals on them when required.  But this is a much less
> My initial though was a regular old Geany plugin, using the Vala binding and
> Vala output C API to provide the "glue" without even touching the existing
> core code directly.  This would at least provide a nice testbed.  Then the
> existing plugin API could just have the odd struct tweaked or function
> added, etc.

As I said above, I think we will quickly find that this isn't enough.
Also just how well does Vala operate through the indirect pointer to
function interface provided by the current plugin interface?

>> intrusive change compared to re-implementing core in GObjects.  In
>> fact it should be only additional code (albeit intertwined in the
>> existing source), so minimising the likelihood of bugs being
>> introduced into the existing Geany functionality.
> Very important indeed.
>> Since the purpose is to support multiple languages, I think that some
>> support for initialising and sharing interpretors/runtimes also needs
>> to be created.  It doesn't help someone to write Python or C# plugins
>> if they have to figure out how to interface the Python interpretor or
>> Mono runtime first.  That should be done once for each language and be
>> a loadable part of Geany.  This process should also know how to find
>> the plugins in the particular language, like Java ones in jar files,
>> Python ones in directories with __init__.py in them etc.  Sharing is
>> needed to reduce the bloat that would occur if each plugin had to have
>> a copy of the interpretor/runtime code
> This is exactly where LibPeas[2] fits in.  I've not found anything that
> would fit the bill as well as LibPeas would.  Also, if we were to add
> interpreter/runtime loaders to LibPeas, the benefits would populate across
> to other important projects like Totem, Gedit, Eog, etc. and of course vice
> versa.  Currently LibPeas only has plugin loaders for C (so probably Vala
> and Genie as well), Python and JS, but surely more can and will be added in
> the future.

Yes, BTW can you specify which Python is used? Distros are now
providing both 2 and 3 side by side.

>> Hope this gives something to think about and throw things at.
> Thanks for getting the ball rolling, I'm anxious to hear what others have to
> say.


More information about the Devel mailing list