Search Here

Sunday, March 8, 2015

Notify to your user in Linux - GNotification

Hello Readers,

In the last post, I was referring to GNotification. Here is the dedicated post of my experiments with GNotification APIs with Perl.


Notification - A pop up message to show the quick details about what is going in the application. Usually in both linux and windows, The notifications are shown in lower right corner (system tray) of the desktop. In Linux GNOME desktop, its usually upper right corner.

Linux KDE desktop notification looks something like this,



Note: The notification appearance may vary based on the theme that you set in your desktop.

In Windows OS, Desktop notification looks something like this,



I was looking for a good way to notify from my perl application to user in Linux. In windows os, There is only one way to do. Call windows APIs yourself. But we are in free world, Linux, We have more than one way to do.

1. GNotification - Notification APIs provided by GNOME and tightly coupled for GTK applications but not hard to use in any applications even command line application. The main advantage of the GNotification APIs is its a persistence notification. Even after the system crash / reboot user will see the notification until they respond to it.

GNotification can also create notifications like questions that user can respond.

2. Libnotify - Notification APIs provided by GNOME. Very simple to use and its kind of standalone api set not tightened up with GTK. Simple and less powerfull.

We will use the GNotification API with Perl application with the help of our best foreign library interaction perl module - FFI::Platypus.
 
GNotification Way of Working is,

1. Create a new GTK application and gets its application ID

2. Register the application

3. Create Notifications

4. Set the Notification parameters

5. Show the Notifications to the user

6. Clean up everything.

Note: If you write a native GTK application, Step #1, #2 is not necessary because its implicit.

Ok. Enough talking, Here is the code.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#!perl
#Description: Create GNOME Desktop notifications using GNOME libgio library and FFI::Platypus
#Refer: https://developer.gnome.org/gio/2.42/gio-GNotification.html
#Author: Bakkiaraj Murugesan
use strict;
use warnings;
use FFI::Platypus;
use FFI::Platypus::Declare;
use FFI::CheckLib;
use Data::Dumper;

$|++;
my $ffiObj = "";

print "\n Perl FFI::Platypus Gnome Notification Example";
#Find the lib
my $libPath =  find_lib( lib => '*', verify => sub { $_[0] =~ /^gio-2\.[0-9]+/ },libpath=>'/usr/lib64' );
my $gobjectLibPath = find_lib(lib=>'*',verify => sub { $_[0] =~ /^gobject-2\.[0-9]+/ },libpath=>'/usr/lib64');
my $glibLibPath = find_lib(lib=>'*',verify =>sub { $_[0] =~m/^glib-2\.\d+/;},libpath=>'/usr/lib64');

#Find the library Paths
print "\n Found libgio-2.0 in :", $libPath;
print "\n Found libgobject-2.0 in :", $gobjectLibPath;
print "\n Found libglib-2.0 in :", $glibLibPath;

#Create FFI::Platypus object
$ffiObj = FFI::Platypus->new();
$ffiObj->lang('C'); #FFI supports more than C language
$ffiObj->lib($libPath);

my $ffiObj1 = FFI::Platypus->new();
$ffiObj1->lang('C'); #FFI supports more than C language
$ffiObj1->lib($gobjectLibPath);

my $ffiObj2 = FFI::Platypus->new();
$ffiObj2->lang('C'); #FFI supports more than C language
$ffiObj2->lib($glibLibPath);

#Create gapplication
#g_application_new (const gchar *application_id,GApplicationFlags flags);
$ffiObj->attach('g_application_new',['string','int'],'opaque');

#Check application ID is valid 
$ffiObj->attach('g_application_id_is_valid',['string'],'int');
#Set GApplication Name
my $appName = 'perl.ffi.platypus.gnome.notify.example';
print "\n App Name $appName is valid? ",g_application_id_is_valid($appName); 
#G_APPLICATION_FLAGS_NONE is 0
my $GApplicationPrt = g_application_new ($appName,0);

#Register the application
#gboolean g_application_register (GApplication *application, GCancellable *cancellable, GError **error);
$ffiObj->attach('g_application_register',['opaque','opaque','opaque'],'int');
#GCancellable *g_cancellable_new (void);
#$ffiObj->attach('g_cancellable_new',['void'],'void');
#my $GCancellablePtr = g_cancellable_new();
print "\n Application Registration ID:", g_application_register($GApplicationPrt,undef,undef);

print "\n Send Welcome notification";
#Create GNotification                        
#GNotification *g_notification_new (const gchar *title);
$ffiObj->attach('g_notification_new',['string'],'opaque');
my $GNotificationPtr = g_notification_new('Welcome');

#void g_notification_set_body (GNotification *notification, const gchar *body);
$ffiObj->attach('g_notification_set_body',['opaque','string'],'void');

g_notification_set_body ($GNotificationPtr, "Welcome to GNotifications using perl + FFI::Platypus...");

#void g_application_send_notification (GApplication *application, const gchar *id, GNotification *notification);
$ffiObj->attach('g_application_send_notification',['opaque','string','opaque'],'void');
g_application_send_notification($GApplicationPrt,'perl.ffi.platypus.gnome.notify.welcome',$GNotificationPtr);

print "\n Send Urgent notification";
#void g_notification_set_urgent (GNotification *notification, gboolean urgent);
$ffiObj->attach('g_notification_set_priority',['opaque','int'],'void');
$GNotificationPtr = g_notification_new('Urgent');
g_notification_set_body ($GNotificationPtr, "This is Urgent Notification. Have a look at me!");
g_notification_set_priority($GNotificationPtr,2);
g_application_send_notification($GApplicationPrt,'perl.ffi.platypus.gnome.notify.urgent',$GNotificationPtr);

print "\n Notification with Buttons";
$GNotificationPtr = g_notification_new('Wanna Coffee?');
g_notification_set_body ($GNotificationPtr, "Would you like to drink Coffee?");

                 
#void g_notification_add_button (GNotification *notification,const gchar *label,const gchar *detailed_action);
$ffiObj->attach('g_notification_add_button',['opaque','string','string'],'void');
g_notification_add_button ($GNotificationPtr, "Ok. Sure", "app.ok");


g_application_send_notification($GApplicationPrt,'perl.ffi.platypus.gnome.notify.coffee',$GNotificationPtr);
                        
print "\n Clean Up everything";
#Do clean up
#void g_object_unref (gpointer object);
$ffiObj1->attach('g_object_unref',['opaque'],'void');
g_object_unref ($GNotificationPtr);
g_object_unref ($GApplicationPrt);

print "\n Ta Ta from PID:", $$;
print "\n Note: GNotification is persitant, Even after this application quit, System reboots, Notification will be there until user acknowledge it.";
#All is Well Bye
exit 0;


Here is the stdout looks like,


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 Perl FFI::Platypus Gnome Notification Example
 Found libgio-2.0 in :/usr/lib64/libgio-2.0.so.0.4200.2
 Found libgobject-2.0 in :/usr/lib64/libgobject-2.0.so.0.4200.2
 Found libglib-2.0 in :/usr/lib64/libglib-2.0.so.0.4200.2
 App Name perl.ffi.platypus.gnome.notify.example is valid? 1
 Application Registration ID:1
 Send Welcome notification
 Send Urgent notification
 Notification with Buttons
 Clean Up everything
 Ta Ta from PID:3768
 Note: GNotification is persitant, Even after this application quit, System reboots, Notification will be there until user acknowledge it.

Here is the screen shot of the notifications generated by the above code,


Conclusion. Notify your user with as much as meaningful information. Do not make them to think that your application is not responding and doing something crap !!.

Bye.



No comments:

Post a Comment