]> spindle.queued.net Git - midori/commitdiff
Add midori_app_send_notification() to easily send notifications
authorEnrico Tröger <enrico.troeger@uvena.de>
Sat, 9 May 2009 13:55:10 +0000 (15:55 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sat, 9 May 2009 13:55:10 +0000 (15:55 +0200)
Sending such messages is either done by using libnotify if
available. Otherwise the program "notify-send" is used.

midori/marshal.list
midori/midori-app.c
midori/midori-app.h
midori/midori-browser.c
midori/midori-preferences.c

index 825f9730064a17e6d40eb85b65054da7adc04353..5ca263beb369d2b0b081a03b7d0d31680bf0a1e7 100644 (file)
@@ -4,3 +4,4 @@ VOID:BOOLEAN,STRING
 VOID:OBJECT,ENUM
 VOID:STRING,BOOLEAN
 VOID:STRING,INT,STRING
+VOID:STRING,STRING
index f79a307cfbcc1bf2ed6835f28af80f1edf9cd3cf..f70a046971c12e96e1dabdd3ff4ca3d7d733a935 100644 (file)
     #include <unique/unique.h>
 #endif
 
+typedef struct _NotifyNotification NotifyNotification;
+
+typedef struct
+{
+    gboolean            (*init)               (const gchar* app_name);
+    void                (*uninit)             (void);
+    NotifyNotification* (*notification_new)   (const gchar* summary,
+                                               const gchar* body,
+                                               const gchar* icon,
+                                               GtkWidget*   attach);
+    gboolean            (*notification_show)  (NotifyNotification* notification,
+                                               GError**            error);
+} LibNotifyFuncs;
+
 struct _MidoriApp
 {
     GObject parent_instance;
@@ -41,6 +55,11 @@ struct _MidoriApp
     KatzeArray* browsers;
 
     gpointer instance;
+
+    /* libnotify handling */
+    gchar*         program_notify_send;
+    GModule*       libnotify_module;
+    LibNotifyFuncs libnotify_funcs;
 };
 
 struct _MidoriAppClass
@@ -89,6 +108,9 @@ static guint signals[LAST_SIGNAL];
 static void
 midori_app_finalize (GObject* object);
 
+static void
+midori_app_init_libnotify (MidoriApp* app);
+
 static void
 midori_app_set_property (GObject*      object,
                          guint         prop_id,
@@ -165,6 +187,8 @@ _midori_app_add_browser (MidoriApp*     app,
         "signal::destroy", midori_browser_destroy_cb, app,
         "signal::quit", midori_browser_quit_cb, app,
         NULL);
+    g_signal_connect_swapped (browser, "send-notification",
+        G_CALLBACK (midori_app_send_notification), app);
 
     katze_array_add_item (app->browsers, browser);
 
@@ -486,6 +510,8 @@ midori_app_init (MidoriApp* app)
     app->browsers = katze_array_new (MIDORI_TYPE_BROWSER);
 
     app->instance = NULL;
+
+    midori_app_init_libnotify (app);
 }
 
 static void
@@ -506,6 +532,13 @@ midori_app_finalize (GObject* object)
 
     katze_object_assign (app->instance, NULL);
 
+    if (app->libnotify_module)
+    {
+        app->libnotify_funcs.uninit ();
+        g_module_close (app->libnotify_module);
+    }
+    katze_object_assign (app->program_notify_send, NULL);
+
     G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
 }
 
@@ -808,3 +841,86 @@ midori_app_quit (MidoriApp* app)
 
     g_signal_emit (app, signals[QUIT], 0);
 }
+
+static void
+midori_app_init_libnotify (MidoriApp* app)
+{
+    gint i;
+    const gchar* sonames[] = { "libnotify.so", "libnotify.so.1", NULL };
+
+    for (i = 0; sonames[i] != NULL && app->libnotify_module == NULL; i++ )
+    {
+        app->libnotify_module = g_module_open (sonames[i], G_MODULE_BIND_LOCAL);
+    }
+
+    if (app->libnotify_module != NULL)
+    {
+        g_module_symbol (app->libnotify_module, "notify_init",
+            (void*) &(app->libnotify_funcs.init));
+        g_module_symbol (app->libnotify_module, "notify_uninit",
+            (void*) &(app->libnotify_funcs.uninit));
+        g_module_symbol (app->libnotify_module, "notify_notification_new",
+            (void*) &(app->libnotify_funcs.notification_new));
+        g_module_symbol (app->libnotify_module, "notify_notification_show",
+            (void*) &(app->libnotify_funcs.notification_show));
+
+        /* init libnotify */
+        if (!app->libnotify_funcs.init || !app->libnotify_funcs.init ("midori"))
+        {
+             g_module_close (app->libnotify_module);
+             app->libnotify_module = NULL;
+        }
+    }
+
+    app->program_notify_send = g_find_program_in_path ("notify-send");
+}
+
+/**
+ * midori_app_send_notification:
+ * @app: a #MidoriApp
+ * @title: title of the notification
+ * @message: text of the notification, or NULL
+ *
+ * Send #message to the notification daemon to display it.
+ * This is done by using libnotify if available or by using the program
+ * "notify-send" as a fallback.
+ *
+ * There is no guarantee that the message have been sent and displayed, as
+ * neither libnotify nor "notify-send" might be available or the
+ * notification daemon might not be running.
+ *
+ * Since 0.1.7
+ **/
+void
+midori_app_send_notification (MidoriApp*   app,
+                              const gchar* title,
+                              const gchar* message)
+{
+    gboolean sent = FALSE;
+
+    g_return_if_fail (MIDORI_IS_APP (app));
+    g_return_if_fail (title);
+
+    if (app->libnotify_module)
+    {
+        NotifyNotification* n;
+
+        n = app->libnotify_funcs.notification_new (title, message, "midori", NULL);
+        sent = app->libnotify_funcs.notification_show (n, NULL);
+        g_object_unref (n);
+    }
+    /* Fall back to the command line program "notify-send" */
+    if (!sent && app->program_notify_send)
+    {
+        gchar* msgq = g_shell_quote (message);
+        gchar* titleq = g_shell_quote (title);
+        gchar* command = g_strdup_printf ("%s -i midori %s %s",
+            app->program_notify_send, titleq, msgq);
+
+        g_spawn_command_line_async (command, NULL);
+
+        g_free (titleq);
+        g_free (msgq);
+        g_free (command);
+    }
+}
index a2f197e908f7c55d6d19c958047e57c4c899c887..7b06ba30544c2392c2d71578373ca1c9a027a59c 100644 (file)
@@ -64,6 +64,11 @@ midori_app_create_browser         (MidoriApp*         app);
 void
 midori_app_quit                   (MidoriApp*         app);
 
+void
+midori_app_send_notification      (MidoriApp*         app,
+                                   const gchar*       title,
+                                   const gchar*       message);
+
 G_END_DECLS
 
 #endif /* __MIDORI_APP_H__ */
index 662f692049e3963dfbddcca1d36602d867731e84..9f3184031c2fd8369b6280dd352f7754317ebd84 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "gtkiconentry.h"
 #include "compat.h"
+#include "marshal.h"
 #include "sokoke.h"
 
 #include <glib/gi18n.h>
@@ -126,6 +127,7 @@ enum
     ACTIVATE_ACTION,
     CONTEXT_READY,
     ADD_DOWNLOAD,
+    SEND_NOTIFICATION,
     QUIT,
 
     LAST_SIGNAL
@@ -970,25 +972,17 @@ midori_browser_download_notify_status_cb (WebKitDownload* download,
             if (browser->settings && katze_object_get_boolean (
                 browser->settings, "notify-transfer-completed"))
             {
-                gchar* program = g_find_program_in_path ("notify-send");
-                if (program != NULL)
-                {
-                    gchar* msg = g_strdup_printf (
-                        _("The file <b>%s</b> has been downloaded."),
-                        webkit_download_get_suggested_filename (download));
-                    gchar* msgq = g_shell_quote (msg);
-                    gchar* titleq = g_shell_quote (_("Transfer completed"));
-                    gchar* command = g_strconcat (titleq, " ", msgq, NULL);
-                    g_free (msg);
-                    g_free (titleq);
-                    g_free (msgq);
-                    sokoke_spawn_program ("notify-send -i midori %s", command, FALSE);
-                    g_free (command);
-                    g_free (program);
-                }
+                gchar* msg = g_strdup_printf (
+                    _("The file <b>%s</b> has been downloaded."),
+                    webkit_download_get_suggested_filename (download));
+
+                g_signal_emit (browser, signals[SEND_NOTIFICATION], 0,
+                    _("Transfer completed"), msg);
+
+                g_free (msg);
             }
-        }
             break;
+        }
         case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
         case WEBKIT_DOWNLOAD_STATUS_ERROR:
             icon = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU);
@@ -1411,6 +1405,29 @@ midori_browser_class_init (MidoriBrowserClass* class)
         G_TYPE_NONE, 1,
         G_TYPE_OBJECT);
 
+    /**
+     * MidoriBrowser::send-notification:
+     * @browser: the object on which the signal is emitted
+     * @title: the title for the notification
+     * @message: the message for the notification
+     *
+     * Emitted when a browser wants to display a notification message,
+     * e.g. when a download has been completed.
+     *
+     * Since: 0.1.7
+     */
+    signals[SEND_NOTIFICATION] = g_signal_new (
+        "send-notification",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        0,
+        0,
+        NULL,
+        midori_cclosure_marshal_VOID__STRING_STRING,
+        G_TYPE_NONE, 2,
+        G_TYPE_STRING,
+        G_TYPE_STRING);
+
     signals[QUIT] = g_signal_new (
         "quit",
         G_TYPE_FROM_CLASS (class),
index 2d5fed3131ba5abb09e35fec3a6486a7bfe5579b..3ce064fe5c554cbb4a73037095d1f4ccbe13910a 100644 (file)
@@ -327,7 +327,6 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
     GtkWidget* entry;
     GtkWidget* hbox;
     gint icon_width, icon_height;
-    gchar* program;
 
     g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
     g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
@@ -433,9 +432,8 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
     gtk_widget_set_sensitive (label, FALSE);
     INDENTED_ADD (label, 0, 1, 1, 2);
     button = katze_property_proxy (settings, "notify-transfer-completed", NULL);
-    if (!((program = g_find_program_in_path ("notify-send"))))
-        gtk_widget_set_sensitive (button, FALSE);
-    g_free (program);
+    /* FIXME: Disable the option if notifications presumably cannot be sent
+      gtk_widget_set_sensitive (button, FALSE); */
     SPANNED_ADD (button, 1, 2, 1, 2);
 
     /* Page "Appearance" */