Creating desktop notifications
Posted by Steve on Sun 18 Jun 2006 at 10:20
There are several times when you'll be writing a script, or a program, which needs to communicate with the desktop user and here we'll look at two of the more modern approaches.
On Screen Display
On-Screen display basically means that text is displayed over the top of your existing desktop - literally in your display, without a popup window of any type.
This might be familiar to you if you've used the xmms-osd-plugin plugin for XMMS.
Using the xosd-bin package it is very simple to send text to the screen:
droot@lappy:~# apt-get install xosd-bin Reading package lists... Done Building dependency tree... Done The following extra packages will be installed: libxosd2
Once installed you can show text by running the osd_cat command with some text to display:
skx@lappy:~$ echo -e "Test Message from Steve\nTesting more" | osd_cat
If all goes well you should see your message on your root window in the top-left corner of your screen.
The position of the message, and the colour/font used can both be modified. Here is what I tend use:
echo "Test" | osd_cat --font='-b&h-lucida-medium-r-normal-*-34-*-*-*-p-*-iso10646-1' \ --color=green \ --pos=top \ --align=right \ --offset=50 \ --indent=50
The advantage of the xosd-bin package is that it is very simple to create a notification message without any real programming. The downside is that the message can't be dismissed early - or be interacted with by the user.
If you want your user to be able to cancel/respond to the message then you'll need something else. Something like the notification daemon.
notification-daemon
There is a new program which is intended to become the standard notification mediator which handles the display of popups and user interaction.
root@lappy:~# apt-get install libnotify1 notification-daemon dbus
(Once installed you should probably logout + login again so that the dbus daemon is setup by your session manager.)
If you want to use the notification facilities in your code you'll need to install the libnotify-dev package which contains the appropriate header files and a shared library to link against. You will also need the GTK headers and the GLib development files. Altogether these are quite a hefty download:
apt-get install libgtk2.0-dev libglib2.0-dev libnotify-dev
Once you've installed the requirements you can compile the following sample program (actually taken from the libnotify source package):
#include <libnotify/notify.h> #include <stdio.h> #include <unistd.h> int main(int argc, char * argv[] ) { NotifyNotification *n; notify_init("Basics"); n = notify_notification_new ("Summary", "This is the message that we want to display", NULL, NULL); notify_notification_set_timeout (n, 5000); // 5 seconds if (!notify_notification_show (n, NULL)) { fprintf(stderr, "failed to send notification\n"); return 1; } g_object_unref(G_OBJECT(n)); return 0; }
Compile it by running:
skx@lappy:~$ gcc `pkg-config --cflags gtk+-2.0`\ `pkg-config --cflags glib-2.0` \ test-basic.c -lnotify -o test-basic
Once compiled execute it by running:
skx@lappy:~$ ./test-basic
All being well an attractive notification dialog should popup and disappear after five seconds - or when you click it.
If you are interested in compiling, or testing, the system without installing the large build-dependencies you can cheat and use runtime-loading! The following code does that:
/* * Dynamic loading + use of the libnotify library. * * Steve * -- * http://www.steve.org.uk/ */ #include <stdlib.h> #include <stdio.h> #include <dlfcn.h> int main( int argc, char *argv[] ) { /* Library + notification handles */ void *handle, *n; /* signatures of functions we're going to invoke dynamically. */ typedef void (*notify_init_t)(char *); typedef void *(*notify_notification_new_t)( char *, char *, char *, char *); typedef void (*notify_notification_set_timeout_t)( void *, int ); typedef void (*notify_notification_show_t)(void *, char *); /* open the library */ handle= dlopen("libnotify.so.1", RTLD_LAZY); if ( handle == NULL ) { printf("Failed to open library\n" ); return 1; } /* Find the notify_init function and invoke it. */ notify_init_t init = (notify_init_t)dlsym(handle, "notify_init"); if ( init == NULL ) { printf("Library function not found: notify_init\n"); dlclose( handle ); return 1; } init("Basics"); /* Find the notify_notification_new function, and invoke it. */ notify_notification_new_t nnn = (notify_notification_new_t)dlsym(handle, "notify_notification_new"); if ( nnn == NULL ) { printf("Library function not found: notify_notification_new\n"); dlclose( handle ); return 1; } n = nnn("Test subject", "Test body with <b>bold</b>, and <i>italic</i>!", NULL, NULL); /* Find the notify_notification_set_timeout function and invoke it. */ notify_notification_set_timeout_t nnst = (notify_notification_set_timeout_t)dlsym(handle, "notify_notification_set_timeout"); if ( nnst == NULL ) { printf("Library function not found: notify_notification_set_timeout\n"); dlclose( handle ); return 1; } /* invoke function, 3 second timeout. */ nnst(n, 3000 ); /* Finally shpow the notification. */ notify_notification_show_t show = (notify_notification_show_t)dlsym(handle, "notify_notification_show"); if ( init == NULL ) { printf("Library function not found: notify_notification_show\n"); dlclose( handle ); return 1; } /* invoke function, passing value of integer as a parameter */ show(n, NULL ); /* close the library and exit*/ dlclose(handle ); return 0; }
You can compile this with:
skx@lappy:~$ gcc dynamic.c -o dynamic -ldl skx@lappy:~$ ./dynamic
This program could be easily adapted to read the message, and title, from command line arguments, but as a simple sample it has probably already done its job.
Note:
To use this program you'll still need to install the notification daemon, dbus, and etc. But you dont need to install the GTK, Glib, and LibNotify development packages - note that you probably should, this is just a simple hack which works only until the API changes.
转载自:https://debian-administration.org/article/407/Creating_desktop_notifications