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:STRING,BOOLEAN
VOID:STRING,INT,STRING
VOID:STRING,STRING

View file

@ -24,6 +24,20 @@
#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);
}
}

View 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__ */

View 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),

View 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" */