]> git.0d.be Git - empathy.git/blob - src/empathy-status-icon.c
add answer/decline buttons in call notifications (#597124)
[empathy.git] / src / empathy-status-icon.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007-2008 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors: Xavier Claessens <xclaesse@gmail.com>
20  */
21
22 #include <config.h>
23
24 #include <string.h>
25
26 #include <glib.h>
27
28 #include <gtk/gtk.h>
29 #include <gdk/gdkkeysyms.h>
30 #include <glib/gi18n.h>
31
32 #include <libnotify/notification.h>
33 #include <libnotify/notify.h>
34
35 #include <telepathy-glib/account-manager.h>
36 #include <telepathy-glib/util.h>
37
38 #include <libempathy/empathy-gsettings.h>
39 #include <libempathy/empathy-utils.h>
40
41 #include <libempathy-gtk/empathy-presence-chooser.h>
42 #include <libempathy-gtk/empathy-ui-utils.h>
43 #include <libempathy-gtk/empathy-images.h>
44 #include <libempathy-gtk/empathy-new-message-dialog.h>
45 #include <libempathy-gtk/empathy-new-call-dialog.h>
46 #include <libempathy-gtk/empathy-notify-manager.h>
47
48 #include "empathy-accounts-dialog.h"
49 #include "empathy-status-icon.h"
50 #include "empathy-preferences.h"
51 #include "empathy-event-manager.h"
52
53 #define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
54 #include <libempathy/empathy-debug.h>
55
56 /* Number of ms to wait when blinking */
57 #define BLINK_TIMEOUT 500
58
59 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyStatusIcon)
60 typedef struct {
61         GtkStatusIcon       *icon;
62         TpAccountManager    *account_manager;
63         EmpathyNotifyManager *notify_mgr;
64         gboolean             showing_event_icon;
65         guint                blink_timeout;
66         EmpathyEventManager *event_manager;
67         EmpathyEvent        *event;
68         NotifyNotification  *notification;
69         GSettings           *gsettings_ui;
70
71         GtkWindow           *window;
72         GtkUIManager        *ui_manager;
73         GtkWidget           *popup_menu;
74         GtkAction           *show_window_item;
75         GtkAction           *new_message_item;
76         GtkAction           *status_item;
77 } EmpathyStatusIconPriv;
78
79 G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
80
81 static void
82 status_icon_notification_closed_cb (NotifyNotification *notification,
83                                     EmpathyStatusIcon  *icon)
84 {
85         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
86
87         g_object_unref (notification);
88
89         if (priv->notification == notification) {
90                 priv->notification = NULL;
91         }
92
93         if (!priv->event) {
94                 return;
95         }
96
97         /* inhibit other updates for this event */
98         empathy_event_inhibit_updates (priv->event);
99 }
100
101 static void
102 notification_close_helper (EmpathyStatusIconPriv *priv)
103 {
104         if (priv->notification != NULL) {
105                 notify_notification_close (priv->notification, NULL);
106                 priv->notification = NULL;
107         }
108 }
109
110 static void
111 notification_approve_cb (NotifyNotification *notification,
112                         gchar              *action,
113                         EmpathyStatusIcon  *icon)
114 {
115         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
116
117         if (priv->event)
118                 empathy_event_approve (priv->event);
119 }
120
121 static void
122 notification_decline_cb (NotifyNotification *notification,
123                         gchar              *action,
124                         EmpathyStatusIcon  *icon)
125 {
126         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
127
128         if (priv->event)
129                 empathy_event_decline (priv->event);
130 }
131
132 static void
133 add_notification_actions (EmpathyStatusIcon *self,
134                           NotifyNotification *notification)
135 {
136         EmpathyStatusIconPriv *priv = GET_PRIV (self);
137
138         switch (priv->event->type) {
139                 case EMPATHY_EVENT_TYPE_CHAT:
140                         notify_notification_add_action (notification,
141                                 "respond", _("Respond"), (NotifyActionCallback) notification_approve_cb,
142                                         self, NULL);
143                         break;
144
145                 case EMPATHY_EVENT_TYPE_VOIP:
146                         notify_notification_add_action (notification,
147                                 "reject", _("Reject"), (NotifyActionCallback) notification_decline_cb,
148                                         self, NULL);
149
150                         notify_notification_add_action (notification,
151                                 "answer", _("Answer"), (NotifyActionCallback) notification_approve_cb,
152                                         self, NULL);
153                         break;
154
155                 default:
156                         break;
157         }
158 }
159
160 static void
161 status_icon_update_notification (EmpathyStatusIcon *icon)
162 {
163         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
164         GdkPixbuf *pixbuf = NULL;
165
166         if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
167                 /* always close the notification if this happens */
168                 notification_close_helper (priv);
169                 return;
170         }
171
172         if (priv->event) {
173                 gchar *message_esc = NULL;
174                 gboolean has_x_canonical_append;
175                 NotifyNotification *notification = priv->notification;
176
177                 if (priv->event->message != NULL)
178                         message_esc = g_markup_escape_text (priv->event->message, -1);
179
180                 has_x_canonical_append =
181                                 empathy_notify_manager_has_capability (priv->notify_mgr,
182                                         EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND);
183
184                 if (notification != NULL && ! has_x_canonical_append) {
185                         /* if the notification server supports x-canonical-append, it is
186                            better to not use notify_notification_update to avoid
187                            overwriting the current notification message */
188                         notify_notification_update (notification,
189                                                     priv->event->header, message_esc,
190                                                     NULL);
191                 } else {
192                         /* if the notification server supports x-canonical-append,
193                            the hint will be added, so that the message from the
194                            just created notification will be automatically appended
195                            to an existing notification with the same title.
196                            In this way the previous message will not be lost: the new
197                            message will appear below it, in the same notification */
198                         notification = notify_notification_new_with_status_icon
199                                 (priv->event->header, message_esc, NULL, priv->icon);
200
201                         if (priv->notification == NULL) {
202                                 priv->notification = notification;
203                         }
204
205                         notify_notification_set_timeout (notification,
206                                                          NOTIFY_EXPIRES_DEFAULT);
207
208                         if (has_x_canonical_append) {
209                                 notify_notification_set_hint_string (notification,
210                                         EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "");
211                         }
212
213                         if (empathy_notify_manager_has_capability (priv->notify_mgr,
214                                    EMPATHY_NOTIFY_MANAGER_CAP_ACTIONS))
215                                 add_notification_actions (icon, notification);
216
217                         g_signal_connect (notification, "closed",
218                                           G_CALLBACK (status_icon_notification_closed_cb), icon);
219                 }
220
221                 pixbuf = empathy_notify_manager_get_pixbuf_for_notification (
222                                                                    priv->notify_mgr, priv->event->contact,
223                                                                    priv->event->icon_name);
224
225                 if (pixbuf != NULL) {
226                         notify_notification_set_icon_from_pixbuf (notification, pixbuf);
227                         g_object_unref (pixbuf);
228                 }
229
230                 notify_notification_show (notification, NULL);
231
232                 g_free (message_esc);
233         } else {
234                 notification_close_helper (priv);
235         }
236 }
237
238 static void
239 status_icon_update_tooltip (EmpathyStatusIcon *icon)
240 {
241         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
242
243         if (priv->event) {
244                 gchar *tooltip = NULL;
245
246                 if (priv->event->message != NULL)
247                                 tooltip = g_markup_printf_escaped ("<i>%s</i>\n%s",
248                                                                    priv->event->header,
249                                                                    priv->event->message);
250                 else
251                                 tooltip = g_markup_printf_escaped ("<i>%s</i>",
252                                                                    priv->event->header);
253                 gtk_status_icon_set_tooltip_markup (priv->icon, tooltip);
254                 g_free (tooltip);
255         } else {
256                 TpConnectionPresenceType type;
257                 gchar *msg;
258
259                 type = tp_account_manager_get_most_available_presence (
260                         priv->account_manager, NULL, &msg);
261
262                 if (!EMP_STR_EMPTY (msg)) {
263                         gtk_status_icon_set_tooltip_text (priv->icon, msg);
264                 }
265                 else {
266                         gtk_status_icon_set_tooltip_text (priv->icon,
267                                                 empathy_presence_get_default_message (type));
268                 }
269
270                 g_free (msg);
271         }
272 }
273
274 static void
275 status_icon_update_icon (EmpathyStatusIcon *icon)
276 {
277         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
278         const gchar           *icon_name;
279
280         if (priv->event && priv->showing_event_icon) {
281                 icon_name = priv->event->icon_name;
282         } else {
283                 TpConnectionPresenceType state;
284
285                 state = tp_account_manager_get_most_available_presence (
286                         priv->account_manager, NULL, NULL);
287
288                 /* An unset presence type here doesn't make sense. Force it
289                  * to be offline. */
290                 if (state == TP_CONNECTION_PRESENCE_TYPE_UNSET) {
291                         state = TP_CONNECTION_PRESENCE_TYPE_OFFLINE;
292                 }
293
294                 icon_name = empathy_icon_name_for_presence (state);
295         }
296
297         if (icon_name != NULL)
298                 gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
299 }
300
301 static gboolean
302 status_icon_blink_timeout_cb (EmpathyStatusIcon *icon)
303 {
304         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
305
306         priv->showing_event_icon = !priv->showing_event_icon;
307         status_icon_update_icon (icon);
308
309         return TRUE;
310 }
311 static void
312 status_icon_event_added_cb (EmpathyEventManager *manager,
313                             EmpathyEvent        *event,
314                             EmpathyStatusIcon   *icon)
315 {
316         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
317
318         if (priv->event) {
319                 return;
320         }
321
322         DEBUG ("New event %p", event);
323
324         priv->event = event;
325         if (event->must_ack) {
326                 priv->showing_event_icon = TRUE;
327                 status_icon_update_icon (icon);
328                 status_icon_update_tooltip (icon);
329         }
330         status_icon_update_notification (icon);
331
332         if (!priv->blink_timeout && priv->showing_event_icon) {
333                 priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
334                                                      (GSourceFunc) status_icon_blink_timeout_cb,
335                                                      icon);
336         }
337 }
338
339 static void
340 status_icon_event_removed_cb (EmpathyEventManager *manager,
341                               EmpathyEvent        *event,
342                               EmpathyStatusIcon   *icon)
343 {
344         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
345
346         if (event != priv->event) {
347                 return;
348         }
349
350         priv->event = empathy_event_manager_get_top_event (priv->event_manager);
351
352         status_icon_update_tooltip (icon);
353         status_icon_update_icon (icon);
354
355         /* update notification anyway, as it's safe and we might have been
356          * changed presence in the meanwhile
357          */
358         status_icon_update_notification (icon);
359
360         if (!priv->event && priv->blink_timeout) {
361                 g_source_remove (priv->blink_timeout);
362                 priv->blink_timeout = 0;
363         }
364 }
365
366 static void
367 status_icon_event_updated_cb (EmpathyEventManager *manager,
368                               EmpathyEvent        *event,
369                               EmpathyStatusIcon   *icon)
370 {
371         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
372
373         if (event != priv->event) {
374                 return;
375         }
376
377         if (empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
378                 status_icon_update_notification (icon);
379         }
380
381         status_icon_update_tooltip (icon);
382 }
383
384 static void
385 status_icon_set_visibility (EmpathyStatusIcon *icon,
386                             gboolean           visible,
387                             gboolean           store)
388 {
389         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
390
391         if (store) {
392                 g_settings_set_boolean (priv->gsettings_ui,
393                                         EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
394                                         !visible);
395         }
396
397         if (!visible) {
398                 empathy_window_iconify (priv->window, priv->icon);
399         } else {
400                 empathy_window_present (GTK_WINDOW (priv->window));
401         }
402 }
403
404 static void
405 status_icon_notify_visibility_cb (GSettings   *gsettings,
406                                   const gchar *key,
407                                   gpointer     user_data)
408 {
409         EmpathyStatusIcon *icon = user_data;
410         gboolean           hidden = FALSE;
411
412         hidden = g_settings_get_boolean (gsettings, key);
413         status_icon_set_visibility (icon, !hidden, FALSE);
414 }
415
416 static void
417 status_icon_toggle_visibility (EmpathyStatusIcon *icon)
418 {
419         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
420         gboolean               visible;
421
422         visible = gtk_window_is_active (priv->window);
423         status_icon_set_visibility (icon, !visible, TRUE);
424 }
425
426 static void
427 status_icon_presence_changed_cb (EmpathyStatusIcon *icon)
428 {
429         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
430
431         status_icon_update_icon (icon);
432         status_icon_update_tooltip (icon);
433
434         if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
435                 /* dismiss the outstanding notification if present */
436
437                 if (priv->notification) {
438                         notify_notification_close (priv->notification, NULL);
439                         priv->notification = NULL;
440                 }
441         }
442 }
443
444 static gboolean
445 status_icon_delete_event_cb (GtkWidget         *widget,
446                              GdkEvent          *event,
447                              EmpathyStatusIcon *icon)
448 {
449         status_icon_set_visibility (icon, FALSE, TRUE);
450         return TRUE;
451 }
452
453 static gboolean
454 status_icon_key_press_event_cb  (GtkWidget *window,
455                                  GdkEventKey *event,
456                                  EmpathyStatusIcon *icon)
457 {
458         if (event->keyval == GDK_Escape) {
459                 status_icon_set_visibility (icon, FALSE, TRUE);
460         }
461         return FALSE;
462 }
463
464 static void
465 status_icon_activate_cb (GtkStatusIcon     *status_icon,
466                          EmpathyStatusIcon *icon)
467 {
468         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
469
470         DEBUG ("%s", priv->event ? "event" : "toggle");
471
472         if (priv->event) {
473                 empathy_event_activate (priv->event);
474         } else {
475                 status_icon_toggle_visibility (icon);
476         }
477 }
478
479 static void
480 status_icon_show_hide_window_cb (GtkToggleAction   *action,
481                                  EmpathyStatusIcon *icon)
482 {
483         gboolean visible;
484
485         visible = gtk_toggle_action_get_active (action);
486         status_icon_set_visibility (icon, visible, TRUE);
487 }
488
489 static void
490 status_icon_new_message_cb (GtkAction         *action,
491                             EmpathyStatusIcon *icon)
492 {
493         empathy_new_message_dialog_show (NULL);
494 }
495
496 static void
497 status_icon_new_call_cb (GtkAction         *action,
498                             EmpathyStatusIcon *icon)
499 {
500         empathy_new_call_dialog_show (NULL);
501 }
502
503 static void
504 status_icon_quit_cb (GtkAction         *action,
505                      EmpathyStatusIcon *icon)
506 {
507         gtk_main_quit ();
508 }
509
510 static void
511 status_icon_popup_menu_cb (GtkStatusIcon     *status_icon,
512                            guint              button,
513                            guint              activate_time,
514                            EmpathyStatusIcon *icon)
515 {
516         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
517         GtkWidget             *menu_item;
518         GtkWidget             *submenu;
519         gboolean               show;
520
521         show = empathy_window_get_is_visible (GTK_WINDOW (priv->window));
522
523         g_signal_handlers_block_by_func (priv->show_window_item,
524                                          status_icon_show_hide_window_cb,
525                                          icon);
526         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_window_item),
527                                       show);
528         g_signal_handlers_unblock_by_func (priv->show_window_item,
529                                            status_icon_show_hide_window_cb,
530                                            icon);
531
532         menu_item = gtk_ui_manager_get_widget (priv->ui_manager, "/menu/status");
533         submenu = empathy_presence_chooser_create_menu ();
534         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
535
536         gtk_menu_popup (GTK_MENU (priv->popup_menu),
537                         NULL, NULL,
538                         gtk_status_icon_position_menu,
539                         priv->icon,
540                         button,
541                         activate_time);
542 }
543
544 static void
545 status_icon_create_menu (EmpathyStatusIcon *icon)
546 {
547         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
548         GtkBuilder            *gui;
549         gchar                 *filename;
550
551         filename = empathy_file_lookup ("empathy-status-icon.ui", "src");
552         gui = empathy_builder_get_file (filename,
553                                         "ui_manager", &priv->ui_manager,
554                                         "menu", &priv->popup_menu,
555                                         "show_list", &priv->show_window_item,
556                                         "new_message", &priv->new_message_item,
557                                         "status", &priv->status_item,
558                                        NULL);
559         g_free (filename);
560
561         empathy_builder_connect (gui, icon,
562                               "show_list", "toggled", status_icon_show_hide_window_cb,
563                               "new_message", "activate", status_icon_new_message_cb,
564                               "new_call", "activate", status_icon_new_call_cb,
565                               "quit", "activate", status_icon_quit_cb,
566                               NULL);
567
568         g_object_ref (priv->ui_manager);
569         g_object_unref (gui);
570 }
571
572 static void
573 status_icon_status_changed_cb (TpAccount *account,
574                                TpConnectionStatus current,
575                                TpConnectionStatus previous,
576                                TpConnectionStatusReason reason,
577                                gchar *dbus_error_name,
578                                GHashTable *details,
579                                EmpathyStatusIcon *icon)
580 {
581         EmpathyStatusIconPriv *priv = GET_PRIV (icon);
582
583         gtk_action_set_sensitive (priv->new_message_item,
584                                   empathy_account_manager_get_accounts_connected (NULL));
585 }
586
587 static void
588 status_icon_finalize (GObject *object)
589 {
590         EmpathyStatusIconPriv *priv = GET_PRIV (object);
591
592         if (priv->blink_timeout) {
593                 g_source_remove (priv->blink_timeout);
594         }
595
596         if (priv->notification) {
597                 notify_notification_close (priv->notification, NULL);
598                 g_object_unref (priv->notification);
599                 priv->notification = NULL;
600         }
601
602         g_object_unref (priv->icon);
603         g_object_unref (priv->account_manager);
604         g_object_unref (priv->event_manager);
605         g_object_unref (priv->ui_manager);
606         g_object_unref (priv->notify_mgr);
607         g_object_unref (priv->gsettings_ui);
608         g_object_unref (priv->window);
609 }
610
611 static void
612 empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
613 {
614         GObjectClass *object_class = G_OBJECT_CLASS (klass);
615
616         object_class->finalize = status_icon_finalize;
617
618         g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
619 }
620
621 static void
622 account_manager_prepared_cb (GObject *source_object,
623                              GAsyncResult *result,
624                              gpointer user_data)
625 {
626         GList *list, *l;
627         TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
628         EmpathyStatusIcon *icon = user_data;
629         GError *error = NULL;
630
631         if (!tp_account_manager_prepare_finish (account_manager, result, &error)) {
632                 DEBUG ("Failed to prepare account manager: %s", error->message);
633                 g_error_free (error);
634                 return;
635         }
636
637         list = tp_account_manager_get_valid_accounts (account_manager);
638         for (l = list; l != NULL; l = l->next) {
639                 tp_g_signal_connect_object (l->data, "status-changed",
640                                              G_CALLBACK (status_icon_status_changed_cb),
641                                              icon, 0);
642         }
643         g_list_free (list);
644
645         status_icon_presence_changed_cb (icon);
646 }
647
648 static void
649 empathy_status_icon_init (EmpathyStatusIcon *icon)
650 {
651         EmpathyStatusIconPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (icon,
652                 EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconPriv);
653
654         icon->priv = priv;
655         priv->icon = gtk_status_icon_new ();
656         priv->account_manager = tp_account_manager_dup ();
657         priv->event_manager = empathy_event_manager_dup_singleton ();
658
659         tp_account_manager_prepare_async (priv->account_manager, NULL,
660             account_manager_prepared_cb, icon);
661
662         /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */
663         priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
664         g_signal_connect (priv->gsettings_ui,
665                           "changed::" EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
666                           G_CALLBACK (status_icon_notify_visibility_cb),
667                           icon);
668
669         status_icon_create_menu (icon);
670
671         g_signal_connect_swapped (priv->account_manager,
672                                   "most-available-presence-changed",
673                                   G_CALLBACK (status_icon_presence_changed_cb),
674                                   icon);
675         g_signal_connect (priv->event_manager, "event-added",
676                           G_CALLBACK (status_icon_event_added_cb),
677                           icon);
678         g_signal_connect (priv->event_manager, "event-removed",
679                           G_CALLBACK (status_icon_event_removed_cb),
680                           icon);
681         g_signal_connect (priv->event_manager, "event-updated",
682                           G_CALLBACK (status_icon_event_updated_cb),
683                           icon);
684         g_signal_connect (priv->icon, "activate",
685                           G_CALLBACK (status_icon_activate_cb),
686                           icon);
687         g_signal_connect (priv->icon, "popup-menu",
688                           G_CALLBACK (status_icon_popup_menu_cb),
689                           icon);
690
691         priv->notification = NULL;
692         priv->notify_mgr = empathy_notify_manager_dup_singleton ();
693 }
694
695 EmpathyStatusIcon *
696 empathy_status_icon_new (GtkWindow *window, gboolean hide_contact_list)
697 {
698         EmpathyStatusIconPriv *priv;
699         EmpathyStatusIcon     *icon;
700         gboolean               should_hide;
701
702         g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
703
704         icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
705         priv = GET_PRIV (icon);
706
707         priv->window = g_object_ref (window);
708
709         g_signal_connect_after (priv->window, "key-press-event",
710                           G_CALLBACK (status_icon_key_press_event_cb),
711                           icon);
712
713         g_signal_connect (priv->window, "delete-event",
714                           G_CALLBACK (status_icon_delete_event_cb),
715                           icon);
716
717         should_hide = g_settings_get_boolean (priv->gsettings_ui,
718                         EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN);
719
720         if (gtk_window_is_active (priv->window) == should_hide) {
721                 status_icon_set_visibility (icon, !should_hide, FALSE);
722         }
723
724         return icon;
725 }
726