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:
parent
5a64656847
commit
70a9d29ea6
5 changed files with 158 additions and 21 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
|
@ -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
|
||||||
|
@ -969,26 +971,18 @@ 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");
|
|
||||||
if (program != NULL)
|
|
||||||
{
|
{
|
||||||
gchar* msg = g_strdup_printf (
|
gchar* msg = g_strdup_printf (
|
||||||
_("The file <b>%s</b> has been downloaded."),
|
_("The file <b>%s</b> has been downloaded."),
|
||||||
webkit_download_get_suggested_filename (download));
|
webkit_download_get_suggested_filename (download));
|
||||||
gchar* msgq = g_shell_quote (msg);
|
|
||||||
gchar* titleq = g_shell_quote (_("Transfer completed"));
|
g_signal_emit (browser, signals[SEND_NOTIFICATION], 0,
|
||||||
gchar* command = g_strconcat (titleq, " ", msgq, NULL);
|
_("Transfer completed"), msg);
|
||||||
|
|
||||||
g_free (msg);
|
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),
|
||||||
|
|
|
@ -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" */
|
||||||
|
|
Loading…
Reference in a new issue