aboutsummaryrefslogtreecommitdiffstats
path: root/src/empathy-chat-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/empathy-chat-window.c')
-rw-r--r--src/empathy-chat-window.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 0ce90ac4a..2f9d59641 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -33,6 +33,7 @@
#include <gdk/gdkkeysyms.h>
#include <glade/glade.h>
#include <glib/gi18n.h>
+#include <libnotify/notification.h>
#include <telepathy-glib/util.h>
#include <libmissioncontrol/mission-control.h>
@@ -70,6 +71,7 @@ typedef struct {
EmpathyChatroomManager *chatroom_manager;
GtkWidget *dialog;
GtkWidget *notebook;
+ NotifyNotification *notification;
/* Menu items. */
GtkWidget *menu_conv_clear;
@@ -833,6 +835,79 @@ chat_window_set_urgency_hint (EmpathyChatWindow *window,
gtk_window_set_urgency_hint (GTK_WINDOW (priv->dialog), urgent);
}
+static gboolean
+notification_closed_idle_cb (EmpathyChatWindow *window)
+{
+ EmpathyChatWindowPriv *priv = GET_PRIV (window);
+
+ gtk_widget_grab_focus (priv->dialog);
+
+ return FALSE;
+}
+
+static void
+chat_window_notification_closed_cb (NotifyNotification *notify,
+ EmpathyChatWindow *window)
+{
+ EmpathyChatWindowPriv *priv = GET_PRIV (window);
+ int reason;
+
+ reason = notify_notification_get_closed_reason (notify);
+
+ if (priv->notification) {
+ g_object_unref (priv->notification);
+ priv->notification = NULL;
+ }
+
+ if (reason == 2) {
+ g_idle_add ((GSourceFunc) notification_closed_idle_cb, window);
+ }
+}
+
+static void
+show_or_update_notification (EmpathyMessage *message,
+ EmpathyChatWindow *window)
+{
+ EmpathyContact *sender;
+ char *header;
+ const char *body;
+ GdkPixbuf *pixbuf;
+ EmpathyChatWindowPriv *priv = GET_PRIV (window);
+
+ if (!empathy_notification_should_show (TRUE)) {
+ return;
+ }
+
+ sender = empathy_message_get_sender (message);
+ header = g_strdup_printf (_("New message from %s"),
+ empathy_contact_get_name (sender));
+ body = empathy_message_get_body (message);
+ pixbuf = empathy_pixbuf_avatar_from_contact_scaled (sender, 48, 48);
+ if (pixbuf == NULL) {
+ /* we use INVALID here so we fall pack to 48px */
+ pixbuf = empathy_pixbuf_from_icon_name (EMPATHY_IMAGE_NEW_MESSAGE,
+ GTK_ICON_SIZE_INVALID);
+ }
+
+ if (priv->notification != NULL) {
+ notify_notification_update (priv->notification,
+ header, body, NULL);
+ notify_notification_set_icon_from_pixbuf (priv->notification, pixbuf);
+ } else {
+ priv->notification = notify_notification_new (header, body, NULL, priv->dialog);
+ notify_notification_set_timeout (priv->notification, NOTIFY_EXPIRES_DEFAULT);
+ notify_notification_set_icon_from_pixbuf (priv->notification, pixbuf);
+
+ g_signal_connect (priv->notification, "closed",
+ G_CALLBACK (chat_window_notification_closed_cb), window);
+ }
+
+ notify_notification_show (priv->notification, NULL);
+
+ g_object_unref (pixbuf);
+ g_free (header);
+}
+
static void
chat_window_new_message_cb (EmpathyChat *chat,
EmpathyMessage *message,
@@ -866,6 +941,10 @@ chat_window_new_message_cb (EmpathyChat *chat,
}
}
+ if (!has_focus) {
+ show_or_update_notification (message, window);
+ }
+
if (has_focus && priv->current_chat == chat) {
return;
}
@@ -1163,6 +1242,12 @@ chat_window_finalize (GObject *object)
g_source_remove (priv->save_geometry_id);
}
+ if (priv->notification != NULL) {
+ notify_notification_close (priv->notification, NULL);
+ g_object_unref (priv->notification);
+ priv->notification = NULL;
+ }
+
chat_windows = g_list_remove (chat_windows, window);
gtk_widget_destroy (priv->dialog);