Hacking by Walkingice: 2010/09

2010/09/04

NotifyOSD Dispute

You might googled this article with the same reason I had. Days ago I updated my Ubuntu9.04 to Ubuntu10.04 and really enjoy it. There are sort of things annoy me - the notification at the corner displays TOO LONG.

To put the question simply: You  cannot change the displaying period of notification.

I use Rhythmbox to listen music, the new version of Rhythmbox at Ubuntu10.04 is sweet because it displays a notification once it finish playing a song and starting next one. This feature is very like Amarok just did, I like it excepts the displaying period is too long.

Most of guys like to coding and listening music at the same time. When the notification coming, you say "Ok, I got it" and back to your original work. 10 seconds passed then the notification disappears, and grab your attention AGAIN : "Hey, I am leaving, bye bye"

Gosh!

It is very like SMS and Phone Call. When you get a SMS message, your mobile just beep for one second. But phone calling keeps shouting until 30 seconds pass or pick up your phone.

Oh, you cannot even close the notification by clicking it.

According to my experience of using Amarok, a user can tweak the period to fit his own requirement. But I cannot find any option in Rhythmbox. I guess the main developers of Rhythmbox are too busy to do that, send a patch to them might be a good idea.

Building Rhythmbox is pretty easy, just checkout the source code then type
./autogen.sh --enable-libnotify --prefix=/tmp/mybuild # I want to install to /tmp/mybuild
make
make install
Actually, the notification mechanism was implemented by plug-in. See rhythmbox/plugins/status-icon/rb-status-icon-plugin.c
static void do_notify (RBStatusIconPlugin *plugin,
           guint timeout,
           const char *primary,
           const char *secondary,
           GdkPixbuf *pixbuf,
           gboolean show_action) 
{
        .....
        notify_notification_set_timeout (plugin->priv->notification, timeout);
        ....... 
}


The function makes the notification and it also set timeout. But, whatever I did to the variables timeout, the notification always displays 10 seconds.

I doubt there is a bug at libnotify so I checkout the source. the function notify_notification_show at libnotify/notification.c did send an notification with expect timeout to dbus. The command notify-send did as well. Actually, even if you write a small script to send notification request with expect timeout to dbus, you still got 10 seconds notification.
    #!/usr/bin/env python 
    import dbus
    item = ('org.freedesktop.Notifications')
    path = ('/org/freedesktop/Notifications')
    interface = ('org.freedesktop.Notifications')
    time = 2000 # 2second
    bus = dbus.SessionBus()
    notif = bus.get_object(item, path)
    notify = dbus.Interface(notif, interface)
    notify.Notify('blah', 0, '', 'Ouch', '2 seconds,please', '', '', time) 


Rhythmbox is ok, libnotify is ok. What thing is go wrong? Take a look of the source code of NotifyOSD. See notify-osd-0.9.29/src/default.c

    /* these values are interpreted as milliseconds-measurements and do comply to  * the visual guide for jaunty-notifications */ 
    #define DEFAULT_FADE_IN_TIMEOUT      250 
    #define DEFAULT_FADE_OUT_TIMEOUT     1000 
    #define DEFAULT_ON_SCREEN_TIMEOUT    10000 

    ...... 
            property_on_screen_timeout = g_param_spec_int (
                                    "on-screen-timeout",
                                    "on-screen-timeout",
                                    "Timeout for bubble on screen in milliseconds",
                                    0,
                                    10000,
                                    DEFAULT_ON_SCREEN_TIMEOUT,
                                    G_PARAM_CONSTRUCT |
                                    G_PARAM_READWRITE |
                                    G_PARAM_STATIC_STRINGS);
            g_object_class_install_property (gobject_class,
                                             PROP_ON_SCREEN_TIMEOUT,
                                             property_on_screen_timeout);


And then see function stack_notify_handler at stack.c
    if (bubble_get_id (bubble) == FORCED_SHUTDOWN_THRESHOLD)
            g_timeout_add (defaults_get_on_screen_timeout (self->defaults),
                           _arm_forced_quit,
                           (gpointer) self);



As you see, NotifyOSD defines a default on-screen-time to 10 seconds and use it at handling notification. But Why? take a look of this [design specification for Notify OSD]. It said "All other hints, and all other parameters (including expire_timeout) should be ignored."

Well, there is a huge discussion at [Launchpad Bug Tracker (#390508)]. I read the whole thread. Ouch, thats pretty tough for me, a non-native English speaker. (But I still did, now you know how much I care about this issue.) Matthew Paul Thomas [said]

      the timeout parameter is for application developers, not end users. We think we can set more consistent and reliable durations for users automatically than diverse application developers ever could manually.

That really pissed off many developers :-P.

First, why 10 seconds? Why not 9.5 second, 10.5 second or 3.14159265358 seconds? Does they really did a research and find THE BEST NUMBER?(I do believe it should be 42) We don't know, we just got the answer: 10.

Ok, 10 is fine. Displays a notification in 10 seconds by default is fine. But why can't an end user change 10 seconds to another number? Is that a bad idea? That is not for developer, that is for end user.

Those developers went to there and complained because they really care about what they are using. Many end users don't complain because they don't know how to complain but not they think the design is good. Every developer who ever designed a UI agrees that making a good interface is so hard therefore making mistake is just so easy.
Providing a good default settings and a option to customize is always a better way.

Unfortunately, Ubuntu has its right to set period to any seconds it want because that is Open Source. I agree but disappointed. John Lee mentioned [How to use notification-daemon to instead of notify osd], I will replace it and say bye bye to NotifyOSD. Moreover, you can use [patched NotifyOSD]