A Subtilty in Overlaying Notification Windows on Maemo

Sat, 05 Nov 2011 12:15:59 -0400
hacking, maemo

I was recently hunting down a slightly annoying usability bug in Khweeteur, a Twitter / identi.ca client: Khweeteur can notify the user when there are new status updates, however, it wasn't overlaying the notification window on the application window, like the email client does. I spent some time investigating the problem: the fix is easy, but non-obvious, so I'm recording it here.

A notification window overlays the window whose WM_CLASS property matches the specified desktop entry (and is correctly configured in /etc/hildon-desktop/notification-groups.conf). Khweeteur was doing the following:

import dbus

bus = dbus.SystemBus()
notify = bus.get_object('org.freedesktop.Notifications',
                        '/org/freedesktop/Notifications')
iface = dbus.Interface(notify, 'org.freedesktop.Notifications')

id = 0
msg = 'New tweets'
count = 1
amount = 1
id = iface.Notify(
    'khweeteur',
    id,
    'khweeteur',
    msg,
    msg,
    ['default', 'call'],
    {
        'category': 'khweeteur-new-tweets',
        'desktop-entry': 'khweeteur',
        'dbus-callback-default'
            : 'net.khertan.khweeteur /net/khertan/khweeteur net.khertan.khweeteur show_now',
        'count': count,
        'amount': count,
        },
    -1,
    )

This means that the notification will overlay the window whose WM_CLASS property is khweeteur. The next step was to figure out whether Khweeteur's WM_CLASS property was indeed set to khweeteur:

$ xwininfo -root -all | grep Khweeteur
        0x3e0000d "Khweeteur: Home": ("__init__.py" "__init__.py")  800x424+0+56  +0+56
        ^ Window id                   ^ WM_CLASS (class, instance)
$ xprop -id 0x3e0000d | grep WM_CLASS
WM_CLASS(STRING) = "__init__.py", "__init__.py"

Ouch! It appears that a program's WM_CLASS is set to the name of its "binary". In this case, /usr/bin/khweeteur was just a dispatcher that executes the right command depending on the arguments. When starting the frontend, it was running a Python interpreter. Adjusting the dispatcher to not exec fixed the problem:

$ xwininfo -root -all | grep Khweeteur
     0x3e00014 "khweeteur": ("khweeteur" "Khweeteur")  400x192+0+0  +0+0
        0x3e0000d "Khweeteur: Home": ("khweeteur" "Khweeteur")  800x424+0+56  +0+56