diff --git a/src/notify/event.c b/src/notify/event.c
index 740301d..7f8b488 100644
--- a/src/notify/event.c
+++ b/src/notify/event.c
@@ -24,6 +24,7 @@
 #include <audacious/drct.h>
 #include <audacious/i18n.h>
 #include <audacious/playlist.h>
+#include <audacious/misc.h>
 #include <libaudcore/hook.h>
 #include <libaudgui/libaudgui-gtk.h>
 
@@ -31,22 +32,12 @@
 #include "event.h"
 #include "osd.h"
 
-static gchar * last_title = NULL, * last_message = NULL;
-
-static void clear (void)
-{
-    g_free (last_title);
-    last_title = NULL;
-    g_free (last_message);
-    last_message = NULL;
-}
-
-static void update (void * unused, void * explicit)
+static void update (void * unused, void * notif)
 {
     if (! aud_drct_get_playing () || ! aud_drct_get_ready ())
     {
-        if (GPOINTER_TO_INT (explicit))
-            osd_show (_("Stopped"), _("Audacious is not playing."), NULL, NULL);
+        if (aud_get_bool ("notify", "actions"))
+            osd_show (_("Stopped"), _("Audacious is not playing."), NULL, notif);
 
         return;
     }
@@ -70,46 +61,54 @@ static void update (void * unused, void * explicit)
     else
         message = g_strdup ("");
 
-    if (! GPOINTER_TO_INT (explicit) && last_title && last_message && ! strcmp
-     (title, last_title) && ! strcmp (message, last_message))
-    {
-        g_free (message);
-        goto FREE;
-    }
-
-    GdkPixbuf * pb = audgui_pixbuf_for_current ();
-    if (pb)
-        audgui_pixbuf_scale_within (& pb, 96);
+    gchar *coverfile = NULL;
+    gchar *filename = aud_playlist_entry_get_filename(list,entry);
+    gchar *coverfileuri = aud_art_request_file(filename);
 
-    osd_show (title, message, "audio-x-generic", pb);
+    if (coverfileuri){
+        if(g_str_has_prefix (coverfileuri, "file://"))
+            coverfile = g_uri_unescape_string(coverfileuri + 7,"");
+        else
+            coverfile = g_uri_unescape_string(coverfileuri,"");
+        }
 
-    if (pb)
-        g_object_unref (pb);
+    osd_show (title, message, coverfile, notif);
 
-    clear ();
-    last_title = g_strdup (title);
-    last_message = message;
+    if (filename)
+        str_unref (filename);
+    if (coverfile)
+        g_free (coverfile);
 
-FREE:
+    if(message)
+        g_free(message);
     str_unref (title);
     str_unref (artist);
     str_unref (album);
 }
 
-void event_init (void)
+static void update_explicit (void * unused, void * notif)
+{
+    if (! aud_drct_get_playing () || ! aud_drct_get_ready ())
+        osd_show (_("Stopped"), _("Audacious is not playing."), NULL, notif);
+    else
+        update(unused, notif);
+    return;
+}
+
+void event_init (void* notif)
 {
-    update (NULL, GINT_TO_POINTER (FALSE));
-    hook_associate ("aosd toggle", (HookFunction) update, GINT_TO_POINTER (TRUE));
-    hook_associate ("playback ready", (HookFunction) update, GINT_TO_POINTER (FALSE));
-    hook_associate ("playlist update", (HookFunction) update, GINT_TO_POINTER (FALSE));
-    hook_associate ("playback stop", (HookFunction) clear, NULL);
+    hook_associate ("aosd toggle", (HookFunction) update_explicit, notif);
+    hook_associate ("playback ready", (HookFunction) update, notif);
+    hook_associate ("playlist update", (HookFunction) update, notif);
+    hook_associate ("playback pause", (HookFunction) update, notif);
+    hook_associate ("playback unpause", (HookFunction) update, notif);
 }
 
 void event_uninit (void)
 {
-    hook_dissociate ("aosd toggle", (HookFunction) update);
+    hook_dissociate ("aosd toggle", (HookFunction) update_explicit);
     hook_dissociate ("playback ready", (HookFunction) update);
     hook_dissociate ("playlist update", (HookFunction) update);
-    hook_dissociate ("playback stop", (HookFunction) clear);
-    clear ();
+    hook_dissociate ("playback pause", (HookFunction) update);
+    hook_dissociate ("playback unpause", (HookFunction) update);
 }
diff --git a/src/notify/notify.c b/src/notify/notify.c
index c394bb3..9625886 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -23,6 +23,8 @@
 #include <audacious/i18n.h>
 #include <audacious/plugin.h>
 #include <audacious/debug.h>
+#include <audacious/preferences.h>
+#include <audacious/misc.h>
 
 #include "config.h"
 #include "event.h"
@@ -32,20 +34,39 @@ gboolean plugin_init (void);
 void plugin_cleanup (void);
 
 static const char plugin_about[] =
- N_("Based on libnotify-aosd by Maximilian Bogner:\n"
-    "http://www.mbogner.de/projects/libnotify-aosd/\n\n"
-    "Copyright (C) 2010 Maximilian Bogner\n"
-    "Copyright (C) 2011 John Lindgren\n\n"
-    "This plugin is free software: you can redistribute it and/or modify "
-    "it under the terms of the GNU General Public License as published by "
-    "the Free Software Foundation, either version 3 of the License, or "
-    "(at your option) any later version.\n\n"
-    "This plugin is distributed in the hope that it will be useful, "
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of "
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
-    "GNU General Public License for more details.\n\n"
-    "You should have received a copy of the GNU General Public License "
-    "along with this program.  If not, see <http://www.gnu.org/licenses/>.");
+ "Based on libnotify-aosd by Maximilian Bogner:\n"
+ "http://www.mbogner.de/projects/libnotify-aosd/\n\n"
+ "Copyright (C) 2010 Maximilian Bogner\n"
+ "Copyright (C) 2011 John Lindgren\n\n"
+ "This plugin is free software: you can redistribute it and/or modify "
+ "it under the terms of the GNU General Public License as published by "
+ "the Free Software Foundation, either version 3 of the License, or "
+ "(at your option) any later version.\n\n"
+ "This plugin is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
+ "GNU General Public License for more details.\n\n"
+ "You should have received a copy of the GNU General Public License "
+ "along with this program.  If not, see <http://www.gnu.org/licenses/>.";
+
+static const char * const notify_defaults[] = {
+ "actions", "TRUE",
+ "silent", "FALSE",
+ NULL};
+
+
+static const PreferencesWidget notify_widgets[] = {
+ {WIDGET_CHK_BTN, N_("Activate controls inside of the notification"),
+ .cfg_type = VALUE_BOOLEAN, .csect = "notify", .cname = "actions"},
+ {WIDGET_CHK_BTN, N_("Silent mode (don't show the notification if activated"),
+ .cfg_type = VALUE_BOOLEAN, .csect = "notify", .cname = "silent"},
+};
+
+static const PluginPreferences notify_prefs = {
+ .widgets = notify_widgets,
+ .n_widgets = G_N_ELEMENTS (notify_widgets)};
+
+
 
 AUD_GENERAL_PLUGIN
 (
@@ -53,6 +74,7 @@ AUD_GENERAL_PLUGIN
     .domain = PACKAGE,
     .about_text = plugin_about,
     .init = plugin_init,
+    .prefs = & notify_prefs,
     .cleanup = plugin_cleanup
 )
 
@@ -61,11 +83,13 @@ short plugin_active = 0;
 gboolean plugin_init (void)
 {
     AUDDBG("started!\n");
-    if(!osd_init()) {
+    aud_config_set_defaults ("notify", notify_defaults);
+    void* notif = osd_init();
+    if(!notif) {
         AUDDBG("osd_init failed!\n");
         return FALSE;
     }
-    event_init();
+    event_init(notif);
 
     plugin_active = 1;
     return TRUE;
diff --git a/src/notify/osd.c b/src/notify/osd.c
index 1097bcc..ff31114 100644
--- a/src/notify/osd.c
+++ b/src/notify/osd.c
@@ -18,57 +18,173 @@
  */
 
 #include <glib.h>
+#include <libaudcore/hook.h>
 #include <audacious/debug.h>
+#include <audacious/i18n.h>
+#include <audacious/drct.h>
+#include <audacious/misc.h>
 #include <libnotify/notify.h>
-
 #include "osd.h"
 
-NotifyNotification *notification = NULL;
-
-gboolean osd_init() {
-    notification = NULL;
-    return notify_init ("Audacious");
-}
-
-void osd_uninit (void)
+static void clean (void * unused, void * notif)
 {
+    NotifyNotification *notification = (NotifyNotification *) notif;
     if (notification)
     {
+        GError *error = NULL;
+        if (notify_notification_close (notification, &error) == FALSE)
+            AUDDBG("%s!\n", error->message);
         g_object_unref (notification);
-        notification = NULL;
     }
 
     notify_uninit();
 }
 
-void osd_closed_handler(NotifyNotification *notification2, gpointer data) {
-    if(notification != NULL) {
-        g_object_unref(notification);
-        notification = NULL;
-        AUDDBG("notification unrefed!\n");
+void* osd_init() {
+    if (notify_is_initted())
+        return NULL;
+    if (notify_init("Audacious"))
+    {
+        NotifyNotification *notif = notify_notification_new("Notification", NULL, NULL);
+
+        hook_associate ("notify shutdown", (HookFunction) clean, notif);
+
+        notify_notification_set_urgency (notif, NOTIFY_URGENCY_LOW);
+        notify_notification_set_hint (notif, "desktop-entry", g_variant_new_string ("audacious"));
+
+        GList *server_caps;
+        server_caps = notify_get_server_caps ();
+        if (g_list_find_custom (server_caps, "actions", (GCompareFunc)g_strcmp0))
+        {
+            if (g_list_find_custom (server_caps, "action-icons", (GCompareFunc)g_strcmp0))
+                notify_notification_set_hint (notif, "action-icons", g_variant_new_boolean (TRUE));
+        }
+        g_list_free_full(server_caps, g_free);
+        return notif;
     }
+    
+    return NULL;
+}
+
+void osd_uninit (void)
+{
+    hook_call("notify shutdown", NULL);
+    hook_dissociate ("notify shutdown", (HookFunction) clean);
 }
 
-void osd_show (const gchar * title, const gchar * _message, const gchar * icon,
- GdkPixbuf * pb)
+
+static void
+goprevious (NotifyNotification *notification,
+            const char *action,
+            gpointer user_data)
 {
+    aud_drct_pl_prev();
+}
+
+static void
+gonext (NotifyNotification *notification,
+        const char *action,
+        gpointer user_data)
+{
+    aud_drct_pl_next();
+}
+
+static void
+show_audacious (NotifyNotification *notification,
+        const char *action,
+        gpointer user_data)
+{
+    aud_interface_show(TRUE);
+}
+
+static void
+playpause (NotifyNotification *notification,
+           const char *action,
+           gpointer user_data)
+{
+    if(aud_drct_get_playing())
+    {aud_drct_pause();}
+    else
+    {aud_drct_play();}
+}
+
+
+void osd_show (const gchar * title, const gchar * _message, const gchar * coverfile, void *notif)
+{
+    NotifyNotification *notification = (NotifyNotification *) notif;
     gchar * message = g_markup_escape_text (_message, -1);
     GError *error = NULL;
 
-    if(notification == NULL) {
-        notification = notify_notification_new(title, message, pb == NULL ? icon : NULL);
-        g_signal_connect(notification, "closed", G_CALLBACK(osd_closed_handler), NULL);
-        AUDDBG("new osd created! (notification=%p)\n", (void *) notification);
-    } else {
-        if(notify_notification_update(notification, title, message, pb == NULL ? icon : NULL)) {
-            AUDDBG("old osd updated! (notification=%p)\n", (void *) notification);
-        } else {
-            AUDDBG("could not update old osd! (notification=%p)\n", (void *) notification);
+    if(notify_notification_update(notification, title, message, "audacious")) {
+        AUDDBG("Osd updated!\n");
+     } else {
+         AUDDBG("Could not update osd!\n");
+    }
+
+
+    GList *server_caps;
+    server_caps = notify_get_server_caps ();
+    if (g_list_find_custom (server_caps, "actions", (GCompareFunc)g_strcmp0))
+    {
+        gboolean playing = FALSE;
+        if (aud_drct_get_playing()) {playing = !aud_drct_get_paused();}
+
+        notify_notification_clear_actions (notification);
+
+        if(aud_get_bool ("notify", "actions")){
+            notify_notification_add_action (notification,
+                        "media-skip-backward",
+                        N_("Previous"),
+                        (NotifyActionCallback) goprevious,
+                        NULL,
+                        NULL);
+
+            notify_notification_add_action (notification,
+                            playing ? "media-playback-pause" : "media-playback-start",
+                            playing ? N_("Pause") : N_("Play"),
+                            (NotifyActionCallback) playpause,
+                            NULL,
+                            NULL);
+
+            notify_notification_add_action (notification,
+                        "media-skip-forward",
+                        N_("Next"),
+                        (NotifyActionCallback) gonext,
+                        NULL,
+                        NULL);
+
+            notify_notification_add_action (notification,
+                        "default",
+                        N_("Afficher Audacious"),
+                        (NotifyActionCallback) show_audacious,
+                        NULL,
+                        NULL);
+            notify_notification_set_timeout(notification, 1);
         }
     }
 
-    if(pb != NULL)
-        notify_notification_set_icon_from_pixbuf(notification, pb);
+    if(aud_get_bool ("notify", "silent"))
+        notify_notification_set_hint (notif, "transient", g_variant_new_boolean (TRUE));
+    else
+        notify_notification_set_hint (notif, "transient", g_variant_new_boolean (FALSE));
+
+    if (g_list_find_custom (server_caps, "persistence", (GCompareFunc)g_strcmp0))
+        {
+            AUDDBG("Notification server supports persistence\n");
+            if (aud_get_bool ("notify", "actions"))
+                notify_notification_set_hint (notif, "resident", g_variant_new_boolean (TRUE));
+            else
+                notify_notification_set_hint (notif, "resident", g_variant_new_boolean (FALSE));
+        }
+
+    g_list_free_full(server_caps, g_free);
+
+
+
+    if (coverfile)
+        notify_notification_set_hint_string (notification, "image_path", coverfile);
+    else
+        notify_notification_set_hint_string (notification, "image_path", "");
 
     if(!notify_notification_show(notification, &error))
         AUDDBG("%s!\n", error->message);
diff --git a/src/notify/osd.h b/src/notify/osd.h
index 51867eb..6aeacae 100644
--- a/src/notify/osd.h
+++ b/src/notify/osd.h
@@ -21,7 +21,7 @@
 #include <libnotify/notify.h>
 
 // Prototypes
-gboolean osd_init();
+void* osd_init();
 void osd_uninit();
 void osd_closed_handler(NotifyNotification *notification2, gpointer data);
-void osd_show(const gchar *title, const gchar *message, const gchar *icon, GdkPixbuf *pb);
+void osd_show(const gchar *title, const gchar *message, const gchar *coverfile, void *notification);
