intltool and po/LINGUAS

Rodney: my suggestions for intltool were not intended as an attack. I just don’t really see much benefit in intltool providing its own po/Makefile.in.in file.

The primary difference between the intltool po/Makefile.in.in and the version provided by gettext or glib is that it calls intltool-update rather than xgettext to update the PO template, so that strings get correctly extracted from files types like desktop entries, Bonobo component registration files, or various other XML files.

The current method intltool uses to get intltool-update called (providing its own po/Makefile.in.in) is a lot better than the previous method (maintaining patches for the po/Makefile.in.in files from various versions of gettext and then deciding which one to apply), however it can make it difficult to take advantage of new gettext features (the po/LINGUAS file being the most recent example). If it was possible for intltool-update to be called without any modification to the po/Makefile.in.in file that gettext installs then this sort of problem wouldn’t occur.

The standard po/Makefile.in.in uses the makefile variable $(XGETTEXT) as the program to extract translations for the PO template. If intltool had a program (or a mode for one of the existing programs) that was command line argument compatible with xgettext, then all that would be necessary would be to redefine $(XGETTEXT) to the appropriate value. Since $(XGETTEXT) is set through a simple autoconf substitution, this should be very easy to do from intltool’s M4 autoconf macro.

po/LINGUAS

One issue that was meantioned as a Gnome Goal was to switch packages to use a po/LINGUAS file.

The idea makes sense — translators only need to edit a simple text file to add a new translation to an application, rather than having to modify the configure.in/configure.ac file without breaking things. Unfortunately, the suggested way of supporting this is a pretty big hack. A better long term solution would be to use the upstream gettext macros and po/Makefile.in.in infrastructure.

For a Gnome module that doesn’t use intltool, the following steps should work.

  1. Make sure the module is being built with Automake 1.8 or 1.9. If it isn’t, upgrade to 1.9.
  2. Create an m4 subdirectory in your project if it doesn’t exist, add it in CVS and then create and add a m4/.cvsignore file (there are a number of files that will get created here by gettext that you don’t want to check into CVS).
  3. Mark the m4 subdirectory as the macro dir in the configure.ac file:
    AC_CONFIG_MACRO_DIR([m4])
    

    And make sure that the macro dir gets checked if the makefile reruns aclocal:

    AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \${ACLOCAL_FLAGS}"])
    
  4. If you aren’t using the gnome-common autogen.sh script, you will also need to make sure that aclocal is called with “-I m4“. If you are using the gnome-common script, then this will happen automatically.
  5. Remove the AM_GLIB_GNU_GETTEXT call from configure.ac and replace it with:
    AM_GNU_GETTEXT([external])
    AM_GNU_GETTEXT_VERSION([0.14.1])
    
  6. If you aren’t using the gnome-common autogen.sh script, change the call to glib-gettextize to autopoint, and make sure it gets run before aclocal (again, unneeded if you are using the gnome-common script).
  7. Now rerun autogen.sh so that autopoint gets run. This should result in a number of files getting created under m4, and some new files under po.
  8. Copy po/Makevars.template to po/Makevars and customise the variables. You might want to set DOMAIN to $(GETTEXT_PACKAGE) rather than $(PACKAGE). Add this new file in CVS.
  9. Update po/LINGUAS from the ALL_LINGUAS variable in configure.ac, and then remove the ALL_LINGUAS definition. Add po/LINGUAS to CVS.
  10. Finally update m4/.cvsignore and po/.cvsignore to ignore the new generated files.

As I said at the start, this change is only appropriate for apps not using intltool, since intltool overwrites the po/Makefile.in.in file with an incomaptible version.

To get things working with intltool, I believe it would make most sense to modify intltool as follows:

  • Make intltool provide some commands that are command line argument compatible with xgettext and msgmerge.
  • Make IT_PROG_INTLTOOL alter XGETTEXT and MSGMERGE with the appropriate intltool functions.
  • Don’t overwrite po/Makefile.in.in.
  • If additional makefile rules are needed in the po subdirectory, install a po/Rules-intltool file containing them. The gettext M4 macros will include them into the resulting Makefile.

Ekiga

I’ve been testing out Ekiga recently, and so far the experience has been a bit hit and miss.

  • Firewall traversal has been unreliable. Some numbers (like the SIPPhone echo test) work great. In some cases, no traffic has gotten through (where both parties were behind Linux firewalls). In other cases, voice gets through in one direction but not the other. Robert Collins has some instructions on setting up siproxd which might solve all this though, so I’ll have to try that.
  • The default display for the main window is a URI entry box and a dial pad. It would make much more sense to display the user’s list of contacts here instead (which are currently in a separate window). I rarely enter phone numbers on my mobile phone, instead using the address book. I expect that most VoIP users would be the same, provided that using the address book is convenient.
  • Related to the previous point: the Ekiga.net registration service seems to know who is online and who is not. It would be nice if this information could be displayed next to the contacts.
  • Ekiga supports multiple sound cards. It was a simple matter of selecting “Logitech USB Headset” as the input and output device on the audio devices page of the preferences to get it to use my headset. Now I hear the ring on my desktop’s speakers, but can use the headset for calls.
  • It is cool that Ekiga supports video calls, but I have no video camera on my computer. Even though I disabled video support in the preferences, there is still a lot of knobs and whistles in the UI related to video.

Even though there are still a few warts, Ekiga shows a lot of promise. As more organisations provide SIP gateways become available (such as the UWA gateway), this software will become more important as a way of avoiding expensive phone charges as well as a way of talking to friends/colleagues.

Firefox Ligature Bug Followup

Thought I’d post a followup on my previous post since it generated a bit of interest. First a quick summary:

  • It is not an Ubuntu Dapper specific bug. With the appropriate combination of fonts and pango versions, it will exhibit itself on other Pango-enabled Firefox builds (it was verified on the Fedora build too).
  • It is not a DejaVu bug, although it is one of the few fonts to exhibit the problem. The simple fact is that not many fonts provide ligature glyphs and include the required OpenType tables for them to be used.
  • It isn’t a Pango bug. The ligatures are handled correctly in normal GTK applications on Dapper. The bug only occurs with Pango >= 1.12, but that is because older versions did not make use of the OpenType tables in the “basic” shaper (used for latin scripts like english).
  • The bug only occurs in the Pango backend, but then the non-Pango renderer doesn’t even support ligatures. Furthermore, there are a number of languages that can’t be displayed correctly with the non-Pango renderer so it is not very appealing.

The firefox bug is only triggered in the slow, manual glyph positioning code path of the text renderer. This only gets invoked if you have non-default letter or word spacing (such as justified text). In this mode, the width of the normal glyph of the first character in the ligature seems to be used for positioning which results in the overlapping text.

It seems that the bug may be fixed in the Firefox 1.6 series, but if that fix can’t be backported easily in time for Dapper, it might be easier to switch to a different default font that doesn’t contain the ligatures (such as Bitstream Vera). That would certainly reduce the chance of the bug occurring.

Annoying Firefox Bug

Ran into an annoying Firefox bug after upgrading to Ubuntu Dapper. It seems to affect rendering of ligatures.

At this point, I am not sure if it is an Ubuntu specific bug. The current conditions I know of to trigger the bug are:

  • Firefox 1.5 (I am using the 1.5.dfsg+1.5.0.1-1ubuntu10 package).
  • Pango rendering enabled (the default for Ubuntu).
  • The web page must use a font that contains ligatures and use those ligatures. Since the “DejaVu Sans” includes ligatures and is the default “sans serif” font in Dapper, this is true for a lot of websites.
  • The text must be justified (e.g. use the “text-align: justify” CSS rule).

If you view a site where these conditions are met with an affected Firefox build, you will see the bug: ligature glyphs will be used to render character sequences like “ffi“, but only the advance of the first character’s normal glyph is used before drawing the next glyph. This results in overlapping glyphs

It also results in a weird effect when selecting text, since the ligatures get broken appart if the selection begins or ends in the middle of the ligature, causing the text to jump around.

I wonder if this bug affects the Firefox packages in any other distributions, or is an Ubuntu only problem?

Re: Lazy loading

Emmanuel: if you are using a language like Python, you can let the language keep track of your state machine for something like that:

def load_items(treeview, liststore, items):
    for obj in items:
        liststore.append((obj.get_foo(),
                          obj.get_bar(),
                          obj.get_baz()))
        yield True
    treeview.set_model(liststore)
    yield False

def lazy_load_items(treeview, liststore, items):
    gobject.idle_add(load_items(treeview, liststore, item).next)

Here, load_items() is a generator that will iterate over a sequence like [True, True, ..., True, False]. The next() method is used to get the next value from the iterator. When used as an idle function with this particular generator, it results in one item being added to the list store per idle call til we get to the end of the generator body where the “yield False” statement results in the idle function being removed.

For a lot of algorithms, this removes the need to design and debug a state machine equivalent. Of course, it is possible to do similar things in C but that’s even more obscure :).

pygpgme 0.1 released

Back in January I started working on a new Python wrapper for the GPGME library. I recently put out the first release:

http://cheeseshop.python.org/pypi/pygpgme/0.1

This library allows you to encrypt, decrypt, sign and verify messages in the OpenPGP format, using gpg as the backend. In general, it stays fairly close to the C API with the following changes:

  • Represent C structures as Python classes where appropriate (e.g. contexts, keys, etc). Operations on those data types are converted to methods.
  • The gpgme_data_t type is not exposed directly. Instead, any Python object that looks like a file object can be passed (including StringIO objects).
  • In cases where there are gpgme_op_XXXX() and gpgme_op_XXXX_result() function pairs, these have been replaced by a single gpgme.Context.XXXX() method. Errors are returned in the exception where appropriate.
  • No explicit memory management. As expected for a Python module, memory management is automatic.

The module also releases the global interpreter lock over calls that fork gpg subprocesses. This should make the module multithread friendly.

This code is being used inside Launchpad to verify incoming email and help manage users’ PGP public keys.

In other news, gnome-gpg 0.4 made it into dapper, so users of the next Ubuntu release can see the improvements.

London

I’ve been in London for a bit over a week now at the Launchpad sprint. We’ve been staying in a hotel near the Excel exhibition centre in Docklands, which has a nice view of the docs and you can see the planes landing at the airport out the windows of the conference rooms.

I met up with James Bromberger (one of the two main organisers of linux.conf.au 2003) on Thursday, which is the first time I’ve seen him since he left for the UK after the conference.

There has been a lot of interesting stuff going on so far, some of which is already live on the production site now. Expect to see better integration with the bzr branch management features in the future.

Gnome Logo on Slashdot

Recently, Jeff brought up the issue of the use of the old Gnome logo on Slashdot. The reasoning being that since we decided to switch to the new logo as our mark back in 2002, it would be nice if they used that mark to represent stories about us.

Unfortunately this request was shot down by Rob Malda, because the logo is “either ugly or B&W (read:Dull)”.

Not to be discouraged, I had a go at revamping the logo to meet Slashdot’s high standards. After all, if they were going to switch to the new logo, they would have done so when we first asked. The result is below:

This is based on an earlier design, but I think the drop shadow really completes the image. Iain managed to come up with a variant suitable for use on the games sub-site.

Gnome-gpg 0.4.0 Released

I put out a new release of gnome-gpg containing the fixes I mentioned previously.

The internal changes are fairly extensive, but the user interface remains pretty much the same. The main differences are:

  • If you enter an incorrect passphrase, the password prompt will be displayed again, the same as when gpg is invoked normally.
  • If an incorrect passphrase is stored in the keyring (e.g. if you changed your key’s passphrase), the passphrase prompt will be displayed. Previously you would need to use the --forget-passphrase option to tell gnome-gpg to ignore the passphrase in the keyring.
  • The passphrase dialog is now set as a transient for the terminal that spawned it, using the same algorithm as zenity. This means that the passphrase dialog pops up on the same workspace as the terminal, and can’t be obscured by the terminal.