Add midori_app_send_notification() to easily send notifications

Sending such messages is either done by using libnotify if
available. Otherwise the program "notify-send" is used.
This commit is contained in:
Enrico Tröger 2009-05-09 15:55:10 +02:00 committed by Christian Dywan
parent 5a64656847
commit 70a9d29ea6
5 changed files with 158 additions and 21 deletions

View file

@ -4,3 +4,4 @@ VOID:BOOLEAN,STRING
VOID:OBJECT,ENUM VOID:OBJECT,ENUM
VOID:STRING,BOOLEAN VOID:STRING,BOOLEAN
VOID:STRING,INT,STRING VOID:STRING,INT,STRING
VOID:STRING,STRING

View file

@ -24,6 +24,20 @@
#include <unique/unique.h> #include <unique/unique.h>
#endif #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 struct _MidoriApp
{ {
GObject parent_instance; GObject parent_instance;
@ -41,6 +55,11 @@ struct _MidoriApp
KatzeArray* browsers; KatzeArray* browsers;
gpointer instance; gpointer instance;
/* libnotify handling */
gchar* program_notify_send;
GModule* libnotify_module;
LibNotifyFuncs libnotify_funcs;
}; };
struct _MidoriAppClass struct _MidoriAppClass
@ -89,6 +108,9 @@ static guint signals[LAST_SIGNAL];
static void static void
midori_app_finalize (GObject* object); midori_app_finalize (GObject* object);
static void
midori_app_init_libnotify (MidoriApp* app);
static void static void
midori_app_set_property (GObject* object, midori_app_set_property (GObject* object,
guint prop_id, guint prop_id,
@ -165,6 +187,8 @@ _midori_app_add_browser (MidoriApp* app,
"signal::destroy", midori_browser_destroy_cb, app, "signal::destroy", midori_browser_destroy_cb, app,
"signal::quit", midori_browser_quit_cb, app, "signal::quit", midori_browser_quit_cb, app,
NULL); NULL);
g_signal_connect_swapped (browser, "send-notification",
G_CALLBACK (midori_app_send_notification), app);
katze_array_add_item (app->browsers, browser); 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->browsers = katze_array_new (MIDORI_TYPE_BROWSER);
app->instance = NULL; app->instance = NULL;
midori_app_init_libnotify (app);
} }
static void static void
@ -506,6 +532,13 @@ midori_app_finalize (GObject* object)
katze_object_assign (app->instance, NULL); 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); 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); 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);
}
}

View file

@ -64,6 +64,11 @@ midori_app_create_browser (MidoriApp* app);
void void
midori_app_quit (MidoriApp* app); midori_app_quit (MidoriApp* app);
void
midori_app_send_notification (MidoriApp* app,
const gchar* title,
const gchar* message);
G_END_DECLS G_END_DECLS
#endif /* __MIDORI_APP_H__ */ #endif /* __MIDORI_APP_H__ */

View file

@ -26,6 +26,7 @@
#include "gtkiconentry.h" #include "gtkiconentry.h"
#include "compat.h" #include "compat.h"
#include "marshal.h"
#include "sokoke.h" #include "sokoke.h"
#include <glib/gi18n.h> #include <glib/gi18n.h>
@ -126,6 +127,7 @@ enum
ACTIVATE_ACTION, ACTIVATE_ACTION,
CONTEXT_READY, CONTEXT_READY,
ADD_DOWNLOAD, ADD_DOWNLOAD,
SEND_NOTIFICATION,
QUIT, QUIT,
LAST_SIGNAL LAST_SIGNAL
@ -970,25 +972,17 @@ midori_browser_download_notify_status_cb (WebKitDownload* download,
if (browser->settings && katze_object_get_boolean ( if (browser->settings && katze_object_get_boolean (
browser->settings, "notify-transfer-completed")) browser->settings, "notify-transfer-completed"))
{ {
gchar* program = g_find_program_in_path ("notify-send"); gchar* msg = g_strdup_printf (
if (program != NULL) _("The file <b>%s</b> has been downloaded."),
{ webkit_download_get_suggested_filename (download));
gchar* msg = g_strdup_printf (
_("The file <b>%s</b> has been downloaded."), g_signal_emit (browser, signals[SEND_NOTIFICATION], 0,
webkit_download_get_suggested_filename (download)); _("Transfer completed"), msg);
gchar* msgq = g_shell_quote (msg);
gchar* titleq = g_shell_quote (_("Transfer completed")); g_free (msg);
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);
}
} }
}
break; break;
}
case WEBKIT_DOWNLOAD_STATUS_CANCELLED: case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
case WEBKIT_DOWNLOAD_STATUS_ERROR: case WEBKIT_DOWNLOAD_STATUS_ERROR:
icon = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU); 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_NONE, 1,
G_TYPE_OBJECT); 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 ( signals[QUIT] = g_signal_new (
"quit", "quit",
G_TYPE_FROM_CLASS (class), G_TYPE_FROM_CLASS (class),

View file

@ -327,7 +327,6 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
GtkWidget* entry; GtkWidget* entry;
GtkWidget* hbox; GtkWidget* hbox;
gint icon_width, icon_height; gint icon_width, icon_height;
gchar* program;
g_return_if_fail (MIDORI_IS_PREFERENCES (preferences)); g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings)); 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); gtk_widget_set_sensitive (label, FALSE);
INDENTED_ADD (label, 0, 1, 1, 2); INDENTED_ADD (label, 0, 1, 1, 2);
button = katze_property_proxy (settings, "notify-transfer-completed", NULL); button = katze_property_proxy (settings, "notify-transfer-completed", NULL);
if (!((program = g_find_program_in_path ("notify-send")))) /* FIXME: Disable the option if notifications presumably cannot be sent
gtk_widget_set_sensitive (button, FALSE); gtk_widget_set_sensitive (button, FALSE); */
g_free (program);
SPANNED_ADD (button, 1, 2, 1, 2); SPANNED_ADD (button, 1, 2, 1, 2);
/* Page "Appearance" */ /* Page "Appearance" */