Putting KNotify to work

This is an article/tutorial on using KNotify, the notifications framework in KDE. We'll look at basic usage of KNotify for modifying the types of events you receive. We'll then look at a more advanced technique, using DCOP, useful for script writers in particular.

KNotify is a very useful part of the KDE framework. It manages all kinds of notifications from different applications that choose to use it. Notifications occur when an application alerts you to an event - very commonly a message box, or a sound, or a flashing task bar entry. The beauty of KDE is that you are no longer left to the whim of the programmer - you can modify what you get.

Using KNotify

Some applications will allow you to configure their own notifications via their 'Settings' menu. All notifications can be configured through the KDE control center - it's under 'Sound and Multimedia' (yep, those modules really need sorting out!).

Notification module in KDE Control Center

Your first use of this might be to turn off those annoying message boxes! There are many events where it's just not urgent (to you, anyway), so you might want to change the popup to a 'passive' one, that doesn't interrupt your work - you need to select "More options" to see this choice. As you can see there are various builtin ways of being notified: play a sound, show a message box (optionally a passive one), log to a file, or mark the taskbar entry - and you can have any combination for any event.

But that is just the beginning, as you can also execute any command from a KNotify event. The possibilities here are endless, especially with KDE's DCOP system. To make the most of this, you'll need to able to write simple scripts, or modify other people's, depending on what you want to do.

One useful example is Ryan Patterson's Buddy Pounce script for Kopete. You can execute this from Kopete's "User goes online" notification to get functionality like the "Buddy Pounce" in Gaim.

Other uses depend on what notifications and what DCOP interfaces are availble. KMail has a "New Mail" notification - you could use it to do something more useful when you get new mail - there is one example of this at the end of this article. If KMail's dcop interface were more advanced, allowing you to query the contents of e-mails, for example, you could have an action that depended on who had sent you the mail. Let's see what the KMail developers give us in the future!

Scripting KNotify with DCOP

Another use for KNotify is for displaying information quickly to the user from scripts. It is possible to use the 'kdialog' command, but there are several advantages of using KNotify:

  • Speed - in my experience kdialog takes a noticeable time to start. Since KNotify is running all the time, the only delay is the time to respond a DCOP command, which is almost no time at all.
  • Actions - all the KNotify actions are available to you, not just visual ones, and you can use them all at once.

(On the other hand, there are lots of things you can do with kdialog that you can't using the method given below).

To find out what commands you can use, we use dcop from the command line:

$ dcop knotify
qt
KDebug
MainApplication-Interface
Notify (default)
knotify

It turns out that the 'default' interface is the one we need. Let's see what functions it offers:

$ dcop knotify default
QCStringList interfaces()
QCStringList functions()
void notify(QString event,QString fromApp,QString text,QString sound,QString file,int present,int level)
void notify(QString event,QString fromApp,QString text,QString sound,QString file,int present,int level,int winId)
void notify(QString event,QString fromApp,QString text,QString sound,QString file,int present,int level,int winId,int eventId)
void reconfigure()
void setVolume(int volume)

The first 'notify' function is the one we need, as we don't need to specify the 'winId' or 'eventId'.

Here is an explanation of the other arguments - this is found experimentally, so someone might correct me on these (I could always go and look up the documentation, I suppose :-) :

  • QString event: text description of the event - you can set it to what you want in this case

  • QString fromApp: the application that is generating the event - you can set it to what you want in this case

  • QString text: the message to show the user

  • QString sound: the sound file to play

  • QString file: the file to log to

  • int present: this is an integer that tells KNotify what kind of notication to do, as below:

    1 - play sound
    2 - show message box
    4 - log to file
    8 - print message to standard error
    16 - show 'passive' message box

    You can specify more than one at once - simply add together the numbers for the events you require.

  • int level: I haven't discovered what this does yet - setting it to 0 seems to work!

Let's put all that together in a DCOP call. If you want to miss out 'sound' or 'text' then you need to use '' to indicate an empty argument.

Type this at a command prompt:

$ dcop knotify default notify eventname appname 'Hello world!' '' '' 2 0

If you got a message box with "Hello world!", then it's working!

Putting it together

Application of this will really depend on your needs, and your imagination. Here is a simple demo that uses KNotify in both the ways described above. We'll write a simple script that uses DCOP to find out how many unread messages are in your KMail inbox. We'll use 'dcop knotify...' to display a message. Then, we'll adjust the KMail 'New mail' notification event so it executes our script. Result: we've replaced the simple message KMail normally gives with a more informative one!

First we need to get at the folder that is your inbox:

$ dcop kmail default
...
QStringList folderList()
DCOPRef getFolder(QString vpath)
...

Those two functions look useful! Let's try them:

$ dcop kmail default folderList
/drafts
/inbox
/outbox
/sent-mail
/trash
...
$ dcop kmail default getFolder /inbox
DCOPRef(kmail,FolderIface)

It has returned a DCOPRef, which is a way of referring to a DCOP object. To use it on the command line, we'll use 'command substitution' using the $(...) construct. If you haven't seen it before, this simply replaces $(command) with the output of command. Using the command line below, we can get a list of functions the DCOP object gives us:

$ dcop $(dcop kmail default getFolder /inbox)
QCStringList interfaces()
QCStringList functions()
QString path()
bool usesCustomIcons()
QString normalIconPath()
QString unreadIconPath()
int messages()
int unreadMessages()
int unreadRecursiveMessages()
$ dcop $(dcop kmail default getFolder /inbox) unreadMessages
3

As you see I have 3 unread messages! Now, we need to use a 'dcop knotify ...' call as above, along with another nested command substitution:

$ dcop knotify default notify newmail newmailscript "New mail: $(dcop $(dcop kmail default getFolder /inbox) unreadMessages) unread message(s)" '' '' 2 0

Two more steps for you to do at home:

  • put this in a script,
  • set up the "New mail" notification to execute your script.

And you're done! That's all for now.

Links

Related articles:

Comments

No comments posted

This article is closed for comments.