2
* * Copyright (C) 2008-2011 Ali <aliov@xfce.org>
4
* Licensed under the GNU General Public License Version 2
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
41
#include <libxfce4util/libxfce4util.h>
43
#include <libnotify/notify.h>
45
#include "xfpm-common.h"
46
#include "xfpm-notify.h"
47
#include "xfpm-dbus-monitor.h"
49
static void xfpm_notify_finalize (GObject *object);
51
static NotifyNotification * xfpm_notify_new_notification_internal (const gchar *title,
53
const gchar *icon_name,
55
XfpmNotifyUrgency urgency,
56
GtkStatusIcon *icon) G_GNUC_MALLOC;
58
#define XFPM_NOTIFY_GET_PRIVATE(o) \
59
(G_TYPE_INSTANCE_GET_PRIVATE((o), XFPM_TYPE_NOTIFY, XfpmNotifyPrivate))
61
struct XfpmNotifyPrivate
63
XfpmDBusMonitor *monitor;
65
NotifyNotification *notification;
66
NotifyNotification *critical;
71
gboolean supports_actions;
72
gboolean supports_sync; /*For x-canonical-private-synchronous */
82
G_DEFINE_TYPE(XfpmNotify, xfpm_notify, G_TYPE_OBJECT)
85
xfpm_notify_get_server_caps (XfpmNotify *notify)
88
notify->priv->supports_actions = FALSE;
89
notify->priv->supports_sync = FALSE;
91
caps = notify_get_server_caps ();
95
if (g_list_find_custom (caps, "x-canonical-private-synchronous", (GCompareFunc) g_strcmp0) != NULL)
96
notify->priv->supports_sync = TRUE;
98
if (g_list_find_custom (caps, "actions", (GCompareFunc) g_strcmp0) != NULL)
99
notify->priv->supports_actions = TRUE;
101
g_list_foreach(caps, (GFunc)g_free, NULL);
107
xfpm_notify_check_server (XfpmDBusMonitor *monitor,
113
if ( !g_strcmp0 (service_name, "org.freedesktop.Notifications") && on_session && connected )
114
xfpm_notify_get_server_caps (notify);
117
static void xfpm_notify_get_property (GObject *object,
124
notify = XFPM_NOTIFY (object);
129
g_value_set_boolean (value, notify->priv->supports_actions);
132
g_value_set_boolean (value, notify->priv->supports_sync);
135
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
141
xfpm_notify_class_init (XfpmNotifyClass *klass)
143
GObjectClass *object_class = G_OBJECT_CLASS (klass);
145
object_class->finalize = xfpm_notify_finalize;
146
object_class->get_property = xfpm_notify_get_property;
148
g_object_class_install_property (object_class,
150
g_param_spec_boolean ("actions",
155
g_object_class_install_property (object_class,
157
g_param_spec_boolean ("sync",
162
g_type_class_add_private (klass, sizeof (XfpmNotifyPrivate));
166
xfpm_notify_init (XfpmNotify *notify)
168
notify->priv = XFPM_NOTIFY_GET_PRIVATE (notify);
170
notify->priv->notification = NULL;
171
notify->priv->critical = NULL;
173
notify->priv->critical_id = 0;
174
notify->priv->notify_id = 0;
176
notify->priv->monitor = xfpm_dbus_monitor_new ();
177
xfpm_dbus_monitor_add_service (notify->priv->monitor, DBUS_BUS_SESSION, "org.freedesktop.Notifications");
178
g_signal_connect (notify->priv->monitor, "service-connection-changed",
179
G_CALLBACK (xfpm_notify_check_server), notify);
181
xfpm_notify_get_server_caps (notify);
185
xfpm_notify_finalize (GObject *object)
189
notify = XFPM_NOTIFY (object);
191
xfpm_notify_close_normal (notify);
192
xfpm_notify_close_critical (notify);
194
G_OBJECT_CLASS (xfpm_notify_parent_class)->finalize(object);
198
xfpm_notify_set_notification_icon (NotifyNotification *n, const gchar *icon_name )
200
GdkPixbuf *pix = xfpm_icon_load (icon_name, 48);
204
notify_notification_set_icon_from_pixbuf (n,
206
g_object_unref ( G_OBJECT(pix));
211
static NotifyNotification *
212
xfpm_notify_new_notification_internal (const gchar *title, const gchar *message,
213
const gchar *icon_name, guint timeout,
214
XfpmNotifyUrgency urgency, GtkStatusIcon *icon)
216
NotifyNotification *n;
218
#ifdef NOTIFY_CHECK_VERSION
219
#if NOTIFY_CHECK_VERSION (0, 7, 0)
220
n = notify_notification_new (title, message, NULL);
222
n = notify_notification_new (title, message, NULL, NULL);
225
n = notify_notification_new (title, message, NULL, NULL);
230
xfpm_notify_set_notification_icon (n, icon_name);
232
#ifdef NOTIFY_CHECK_VERSION
233
#if !NOTIFY_CHECK_VERSION (0, 7, 0)
235
notify_notification_attach_to_status_icon (n, icon);
239
notify_notification_attach_to_status_icon (n, icon);
242
notify_notification_set_urgency (n, (NotifyUrgency)urgency);
245
notify_notification_set_timeout (n, timeout);
251
xfpm_notify_closed_cb (NotifyNotification *n, XfpmNotify *notify)
253
notify->priv->notification = NULL;
254
g_object_unref (G_OBJECT (n));
258
xfpm_notify_close_critical_cb (NotifyNotification *n, XfpmNotify *notify)
260
notify->priv->critical = NULL;
261
g_object_unref (G_OBJECT (n));
265
xfpm_notify_show (NotifyNotification *n)
267
notify_notification_show (n, NULL);
272
xfpm_notify_close_notification (XfpmNotify *notify )
274
if (notify->priv->notify_id != 0)
276
g_source_remove (notify->priv->notify_id);
277
notify->priv->notify_id = 0;
280
if ( notify->priv->notification )
282
if (!notify_notification_close (notify->priv->notification, NULL))
283
g_warning ("Failed to close notification\n");
285
g_object_unref (G_OBJECT(notify->priv->notification) );
286
notify->priv->notification = NULL;
291
xfpm_notify_new (void)
293
static gpointer xfpm_notify_object = NULL;
295
if ( xfpm_notify_object != NULL )
297
g_object_ref (xfpm_notify_object);
301
xfpm_notify_object = g_object_new (XFPM_TYPE_NOTIFY, NULL);
302
g_object_add_weak_pointer (xfpm_notify_object, &xfpm_notify_object);
304
return XFPM_NOTIFY (xfpm_notify_object);
307
void xfpm_notify_show_notification (XfpmNotify *notify, const gchar *title,
308
const gchar *text, const gchar *icon_name,
309
gint timeout, gboolean simple,
310
XfpmNotifyUrgency urgency, GtkStatusIcon *icon)
312
NotifyNotification *n;
315
xfpm_notify_close_notification (notify);
317
n = xfpm_notify_new_notification_internal (title,
322
xfpm_notify_present_notification (notify, n, simple);
325
NotifyNotification *xfpm_notify_new_notification (XfpmNotify *notify,
328
const gchar *icon_name,
330
XfpmNotifyUrgency urgency,
333
NotifyNotification *n = xfpm_notify_new_notification_internal (title,
340
void xfpm_notify_add_action_to_notification (XfpmNotify *notify, NotifyNotification *n,
341
const gchar *id, const gchar *action_label,
342
NotifyActionCallback callback, gpointer data)
344
g_return_if_fail (XFPM_IS_NOTIFY(notify));
346
notify_notification_add_action (n, id, action_label,
347
(NotifyActionCallback)callback,
352
void xfpm_notify_present_notification (XfpmNotify *notify, NotifyNotification *n, gboolean simple)
354
g_return_if_fail (XFPM_IS_NOTIFY(notify));
357
xfpm_notify_close_notification (notify);
361
g_signal_connect (G_OBJECT(n),"closed",
362
G_CALLBACK(xfpm_notify_closed_cb), notify);
363
notify->priv->notification = n;
366
notify->priv->notify_id = g_idle_add ((GSourceFunc) xfpm_notify_show, n);
369
void xfpm_notify_critical (XfpmNotify *notify, NotifyNotification *n)
371
g_return_if_fail (XFPM_IS_NOTIFY (notify));
373
xfpm_notify_close_critical (notify);
375
notify->priv->critical = n;
377
g_signal_connect (G_OBJECT (n), "closed",
378
G_CALLBACK (xfpm_notify_close_critical_cb), notify);
380
notify->priv->critical_id = g_idle_add ((GSourceFunc) xfpm_notify_show, n);
383
void xfpm_notify_close_critical (XfpmNotify *notify)
385
g_return_if_fail (XFPM_IS_NOTIFY (notify));
388
if (notify->priv->critical_id != 0)
390
g_source_remove (notify->priv->critical_id);
391
notify->priv->critical_id = 0;
394
if ( notify->priv->critical )
396
if (!notify_notification_close (notify->priv->critical, NULL))
397
g_warning ("Failed to close notification\n");
399
g_object_unref (G_OBJECT(notify->priv->critical) );
400
notify->priv->critical = NULL;
404
void xfpm_notify_close_normal (XfpmNotify *notify)
406
g_return_if_fail (XFPM_IS_NOTIFY (notify));
408
xfpm_notify_close_notification (notify);