Artikel getaggt mit gobject-introspection

libxklavier is now introspectable

On my 8 hour train ride to Budapest last Sunday I finally worked on making libxklavier introspectable. Thanks to Sergey’s fast review the code now landed in trunk. I sent a couple of refinements to the bug report still, but those are mostly just icing on the cake, the main functionality of getting and setting keyboard layouts is working nicely now (see the example script).

Tags: , , , , ,

Improved PyGI documentation

As a followup action to my recent Talk about PyGI I now re-used my notes to provide some real wiki documentation.

It would be great if you could add package name info for Fedora/SUSE/etc., and perhaps add more example links for porting different kinds of software! Please also let me know if you have suggestions how to improve the structure of the page.

Tags: , , , , , , , ,

PyGTK is dead, long live PyGI! – App Developer Week Talk

On next Monday this cycle’s Ubuntu Application Developer Week classes will start.

The topic that kept me busy most in this cycle was Python gobject-introspection, and porting pygtk2 apps to PyGI (see my initial steps and my report from the PyGI hackfest.)

To spread the love, there will be two talks about this next week: On Monday 17:00 UTC the very Tomeu Vizoso himself will explain what gobject-introspection (“GI”) is, why we need it, and how library developers use it to ship a good and useful GI binding (“typelib”) for application developers. I will then follow up on Tuesday 16:00 UTC about the app developer side, in particular how to use the GI typelibs in Python, and how to port PyGTK2 applications to PyGI.

For the most part these sessions are distribution neutral (we don’t have any special sauce for this in Debian/Ubuntu, it all happened right upstream :-) ); only a very small fraction of it (where I explain package names, etc.) will be specific to Debian/Ubuntu, but shouldn’t be hard to apply to other distributions as well.

So please feel invited to join, and bombard us with questions!

Tags: , , , , , , ,

Na zdraví PyGI!

(Update: Link to Tomeu’s blog post, repost for planet.gnome.org)

Last week I was in Prague to attend the GNOME/Python 2011 Hackfest for gobject-introspection, to which Tomeu Vizoso kindly invited me after I started working with PyGI some months ago. It happened at a place called brmlab which was quite the right environment for a bunch of 9 hackers: Some comfy couches and chairs, soldering irons, lots of old TV tubes, chips, and other electronics, a big Pirate flag, really good Wifi, plenty of Club Mate and Coke supplies, and not putting unnecessary effort into mundane things like wallpapers.

It was really nice to get to know the upstream experts John (J5) Palmieri and Tomeu Vizoso (check out Tomeu’s blog post for his summary and some really nice photos). When sitting together in a room, fully focussing on this area for a full week, it’s so much easier to just ask them about something and getting things done and into upstream than on IRC or bugzilla, where you don’t know each other personally. I certainly learned a lot this week (and not only how great Czech beer tastes :-) )!

So what did I do?

Application porting

After already having ported four Ubuntu PyGTK applications to GI before (apport, jockey, aptdaemon, and language-selector),
my main goal and occupation during this week was to start porting a bigger PyGTK application. I picked system-config-printer, as it’s two magnitudes bigger than the previous projects, exercises quite a lot more of the GTK GI bindings, and thus also exposes a lot more GTK annotation and pygobject bugs. This resulted in a new pygi s-c-p branch which has the first 100 rounds of “test, break, fix” iterations. It now at least starts, and you can do a number of things with it, but a lot of functionality is still broken.

As a kind of “finger exercise” and also to check for how well pygi-convert works for small projects now, I also ported computer-janitor. This went really well (I had it working after about 30 minutes), and also led me to finally fixing the unicode vs. str mess for GtkTreeView that you got so far with Python 2.x.

pygobject and GTK fixes

Porting system-config-printer and computer-janitor uncovered a lot of opportunities to improve pygi-convert.sh, a big “perl -e” kind of script to do the mechanical grunt work of the porting process. It doesn’t fix up changed signatures (such as adding missing arguments which were default arguments in PyGTK, or the ubiquitous “user_data” argument for signal handlers), but at least it gets a lot of namespaces, method, and constant names right.

I also fixed three annotation fixes in GTK+. We also collaboratively reviewed and tested Pavel’s annotation branch which helped to fix tons of problems, especially after Steve Frécinaux’s excellent reference leak fix, so if you play around with current pygobject git head, you really also have to use the current GTK+ git head.

Speaking of which, if you want to port applications and always stay on top of the pygobject/GTK development without having to clutter your package system with “make install”s of those, it works very well to have this in your ~/.bashrc:

export GI_TYPELIB_PATH=$HOME/projects/gtk/gtk:$HOME/projects/gtk/gdk
export PYTHONPATH=$HOME/projects/pygobject

Better GVariant/GDBus support

The GNOME world is moving from the old dbus-glib python bindings to GDBus, which is integrated into GLib. However, dbus-python exposed a really nice and convenient way of doing D-Bus calls, while using GDBus from Python was hideously complicated, especially for nontrivial arguments with empty or nested arrays:

from gi.repository import Gio, GLib
from gi._gi import variant_type_from_string

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

vb = GLib.VariantBuilder()
vb.init(variant_type_from_string('r'))
vb.add_value(GLib.Variant('s', 'test'))
vb.add_value(GLib.Variant('u', 1))
vb.add_value(GLib.Variant('s', 'gtk-ok'))
vb.add_value(GLib.Variant('s', 'Hello World!'))
vb.add_value(GLib.Variant('s', 'Subtext'))
# add an empty array
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('as'))
vb.add_value(eavb.end())
# add an empty dict
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('a{sv}'))
vb.add_value(eavb.end())
vb.add_value(GLib.Variant('i', 10000))
args = vb.end()

result = notify.call_sync('Notify', args, 0, -1, None)
id = result.get_child_value(0).get_uint32()
print id

So I went to making the GLib.Variant constructor work properly with nested types and boxed variants, adding Pythonic GVariant iterators and indexing (so that you can treat GVariant dictionaries/arrays/tuples just like their Python equivalents), and finally a Variant.unpack() method for converting the return value of a D-Bus call back into a native Python data type. This looks a lot friendlier now:

from gi.repository import Gio, GLib

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

args = GLib.Variant('(susssasa{sv}i)', ('test', 1, 'gtk-ok', 'Hello World!',
    'Subtext', [], {}, 10000))
result = notify.call_sync('Notify', args, 0, -1, None)
id = result.unpack()[0]
print id

I also prepared another patch in GNOME#640181 which will provide the icing on the cake, i. e. handle the variant building/unpacking transparently and make the explicit call_sync() unnecessary:

from gi.repository import Gio, GLib

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

result = notify.Notify('(susssasa{sv}i)', 'test', 1, 'gtk-ok', 'Hello World!',
            'Subtext', [], {}, 10000)
print result[0]

I hope that I can get this reviewed and land this soon.

Thanks to our sponsors!

Many thanks to the GNOME Foundation and Collabora for sponsoring this event!

Tags: , , , , , , , , , ,

GTK 3.0/GIR application porting: Successes and problems

GNOME 3.0 and Ubuntu Natty are currently undergoing a major architectural shift from GTK 2.0 to 3.0. Part of this is that the previous set of manually maintained language bindings, such as PyGTK, are being deprecated in favor of GObject Introspection, a really cool technology!

For us this means that we have to port all our PyGTK applications from PyGTK 2 to gobject-introspection and GTK 3.0 at the same time. I started with that for my own projects (Apport and Jockey) a few days ago, and along the way encountered a number of problems. They are being fixed (particular thanks to the quick responsiveness of John Palmieri!), so I guess after a few of those iterations, porting should actually become straight forward and solid.

So now I’m proud to announce Apport 1.16 which is now fully working with GTK 3.0 and pygobject-introspection. I just uploaded it to Ubuntu Natty, where it can get some wider testing. I also have a pygi/GTK3.0 branch for Jockey, which is also mostly working now, but it’s blocked on the availability of a GIR for AppIndicator. Once that lands, I’ll release and upload the Jockey as well.

For other people working on porting, these are the bugs and problems I’ve encountered:

  • [pygobject] GtkMessageDialog constructors did not work at all. This was fixed in pygobject 2.27, so it works fine in Natty, but there is little to no chance of making these work in Ubuntu 10.10.
  • [pygobject] Gtk.init_check() crashes (upstream bug). It’s not strictly necessary, though, just avoids crashes (and crash reports) when calling it without a $DISPLAY. I’ll put that back once that gets fixed.
  • [pygobject] You can’t pass unicode objects as method arguments or property values (upstream bug). Method arguments were recently fixed in upstream git head, and I backported it to the Natty package, so these work now. Property values are still outstanding. The workaround for both is to convert unicode values to bytes with .encode('UTF-8') everywhere.
  • [pygobject] pygi-convert.sh is a great help which automates most of the mechanical rewriting work and thus gets you 90% of the porting done automatically. It’s currently missing MessageDialog constants, and is a bit inconvenient to call. I sent two patches upstream (upstream bug) which improve this.
  • [GIR availability] libnotify did not build a GIR yet (upstream bug). This was fixed in upstream git head with some contributions of mine, and I uploaded it to Natty. This works quite well now, although add_action() crashes on passing the callback. This is still to be investigated.
  • [GIR availability] There is no Application Indicator GIR, as already mentioned. Our DX team and Ken VanDine are working on this, so this should get fixed soon.
  • [GTK] Many dialogs now scale in a very ugly manner: Instead of resizing the contents, the dialog just grows huge outer padding. This is due to a change of the default “fill” property, and apparently is not fully understood yet (upstream bug). As a workaround I explicitly added the fill property to the top-level GTKBox in my GTKBuilder .ui files. (Note that this happens in C as well, it’s not a GI specific bug.)
  • [GTK] Building GtkRadioButton groups is currently a bit inconvenient and requires special-casing for the first group member, due to some missing annotations. I sent a patch upstream which fixes that (upstream bug).
  • [GTK] After initial porting, a lot of my dialogs got way too narrow with wrapped labels and text, because GTK 3 changed the behaviour and handling of widget and window sizes. This is intended, not a bug, but it does require some adaptions in the GtkBuilder files and also in the code. The GTK 2 → 3 migration guide has a section about it.

Despite those, I’m impressed how well gobject-introspection already works. It was relatively painless for me to generate a GIR from a libnotify (thanks to the annotations already being mostly correct for building the documentation) and use it from Python. In another couple of months this will be rock solid, and porting our bigger pygtk projects like ubiquity and software-center will hopefully become feasible.

Tags: , , , , , , , , , ,