[ekiga] Notifications: Several changes.



commit 1578788d005224511ad34476935096f659d52271
Author: Damien Sandras <dsandras beip be>
Date:   Sat Apr 21 18:19:43 2012 +0200

    Notifications: Several changes.
    
    - if the server supports persistent notifications, we rely on the engine
      notifications and do not use the (deprecated) status icon anymore,
    - removed old missed call notifications from notify.cpp
    - removed old hacks
    - if we have a status icon or persistent notifications (ie GNOME 3),
      closing the window hides it, otherwise we quit
    
    There is still some work to be done, but in general :
    - use the engine notifications and only them if persistent notifications
      are supported
    - use the engine notifications and the status icon in the other cases

 src/ekiga.cpp           |    3 +-
 src/gui/main_window.cpp |   50 +-----------------
 src/gui/notify.cpp      |  134 +++++++++++++++-------------------------------
 src/gui/notify.h        |   11 ++++
 src/gui/statusicon.cpp  |   26 +++++++++
 5 files changed, 84 insertions(+), 140 deletions(-)
---
diff --git a/src/ekiga.cpp b/src/ekiga.cpp
index a7f98fa..e32ec88 100644
--- a/src/ekiga.cpp
+++ b/src/ekiga.cpp
@@ -165,7 +165,8 @@ void GnomeMeeting::BuildGUI (Ekiga::ServiceCorePtr services)
   prefs_window = gm_prefs_window_new (services.get ());
   assistant_window = ekiga_assistant_new (services.get ());
   call_window = gm_call_window_new (*services);
-  statusicon = statusicon_new (*services);
+  if (!notify_has_persistence ())
+    statusicon = statusicon_new (*services);
   main_window = gm_main_window_new (*services);
   // FIXME should be moved inside the gm_accounts_window_new code
   gtk_window_set_transient_for (GTK_WINDOW (accounts_window), GTK_WINDOW (main_window));
diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp
index e2949f1..a2b5860 100644
--- a/src/gui/main_window.cpp
+++ b/src/gui/main_window.cpp
@@ -1006,41 +1006,9 @@ add_device_response_cb (GtkDialog *add_device_popup,
   }
 }
 
-static void
-on_status_icon_embedding_change (G_GNUC_UNUSED GObject obj,
-				 G_GNUC_UNUSED GParamSpec param,
-				 G_GNUC_UNUSED gpointer data)
-{
-  GtkWidget *main_window = NULL;
-  GtkStatusIcon *status_icon = NULL;
-
-  status_icon = GTK_STATUS_ICON (GnomeMeeting::Process ()->GetStatusicon ());
-  main_window = GnomeMeeting::Process ()->GetMainWindow ();
-
-  /* force the main window to show if no status icon for the user */
-  if (!gtk_status_icon_is_embedded (GTK_STATUS_ICON (status_icon)))
-    gtk_widget_show (main_window);
-}
-
 
 /* GTK callbacks */
 static gboolean
-gnomemeeting_tray_hack_cb (G_GNUC_UNUSED gpointer data)
-{
-  GtkWidget *main_window = NULL;
-  GtkStatusIcon *statusicon = NULL;
-
-  statusicon = GTK_STATUS_ICON (GnomeMeeting::Process ()->GetStatusicon ());
-  main_window = GnomeMeeting::Process ()->GetMainWindow ();
-
-  // show the main window if the icon has not appeared in tray
-  if (!gtk_status_icon_is_embedded (GTK_STATUS_ICON (statusicon)))
-    gtk_widget_show (main_window);
-
-  return FALSE;
-}
-
-static gboolean
 on_delayed_hide_call_window_cb (gpointer data)
 {
   g_return_val_if_fail (data != NULL, FALSE);
@@ -1296,15 +1264,7 @@ window_closed_cb (G_GNUC_UNUSED GtkWidget *widget,
 		  G_GNUC_UNUSED GdkEvent *event,
 		  gpointer data)
 {
-  GtkStatusIcon *statusicon = NULL;
-
-  statusicon = GTK_STATUS_ICON (GnomeMeeting::Process ()->GetStatusicon ());
-
-  if (!gtk_status_icon_is_embedded (GTK_STATUS_ICON (statusicon)))
-    quit_callback (NULL, data);
-  else
-    gtk_widget_hide (GTK_WIDGET (data));
-
+  gtk_widget_hide (GTK_WIDGET (data));
   return (TRUE);
 }
 
@@ -2220,7 +2180,6 @@ GtkWidget *
 gm_main_window_new (Ekiga::ServiceCore & core)
 {
   GtkWidget *window = NULL;
-  GtkStatusIcon *status_icon = NULL;
   GtkWidget *chat_window = NULL;
 
   /* initialize the callback to play IM message sound */
@@ -2234,11 +2193,6 @@ gm_main_window_new (Ekiga::ServiceCore & core)
   /* The Top-level window */
   window = ekiga_main_window_new (&core);
 
-  /* Track status icon embed changes */
-  /* FIXME: move this to the status icon code */
-  status_icon = GTK_STATUS_ICON (GnomeMeeting::Process ()->GetStatusicon ());
-  g_signal_connect (status_icon, "notify::embedded",
-		    G_CALLBACK (on_status_icon_embedding_change), NULL);
 
   return window;
 }
@@ -2431,8 +2385,6 @@ main (int argc,
   if (crt_version > 0) {
     if (!gm_conf_get_bool (USER_INTERFACE_KEY "start_hidden"))
       gtk_widget_show (main_window);
-    else
-      g_timeout_add_seconds (15, gnomemeeting_tray_hack_cb, NULL);
   }
 
   /* Call the given host if needed */
diff --git a/src/gui/notify.cpp b/src/gui/notify.cpp
index f0c7f31..ed26eee 100644
--- a/src/gui/notify.cpp
+++ b/src/gui/notify.cpp
@@ -59,36 +59,6 @@ struct CallNotificationInfo
   boost::shared_ptr<Ekiga::Call> call;
 };
 
-struct _Notify
-{
-  NotifyNotification *missed_call_notification;
-  gchar *missed_call_body;
-
-};
-
-// return if the notify server accepts actions (i.e. buttons)
-// taken from https://wiki.ubuntu.com/NotificationDevelopmentGuidelines#Avoiding%20actions
-static int
-hasActionsCap (void)
-{
-  static int accepts_actions = -1;
-  if (accepts_actions == -1) {  // initialise accepts_actions at the first call
-    accepts_actions = 0;
-    GList *capabilities = notify_get_server_caps ();
-    if (capabilities != NULL) {
-      for (GList *c = capabilities ; c != NULL ; c = c->next) {
-        if (strcmp ((char*)c->data, "actions") == 0 ) {
-          accepts_actions = 1;
-          break;
-        }
-      }
-      g_list_foreach (capabilities, (GFunc)g_free, NULL);
-      g_list_free (capabilities);
-    }
-  }
-  return accepts_actions;
-}
-
 static void
 notify_action_cb (NotifyNotification *notification,
                   gchar *action,
@@ -111,30 +81,6 @@ notify_action_cb (NotifyNotification *notification,
     delete priv;
 }
 
-static void
-notify_missed_call_action_cb (G_GNUC_UNUSED NotifyNotification *notification,
-                              gchar *action,
-                              gpointer data)
-{
-  GtkWidget *window = GnomeMeeting::Process ()->GetMainWindow (); //FIXME when GOBJECT
-  _Notify *notifications = (_Notify*) (data);
-
-  if (!strcmp (action, "show")) {
-    gm_conf_set_int (USER_INTERFACE_KEY "main_window/panel_section", CALL);
-
-    if (!gtk_widget_get_visible (window)
-        || (gdk_window_get_state (GDK_WINDOW (window->window)) & GDK_WINDOW_STATE_ICONIFIED))
-      gtk_widget_show (window);
-
-    g_free (notifications->missed_call_body);
-    notifications->missed_call_body = NULL;
-
-    notify_notification_close (notifications->missed_call_notification, NULL);
-    notifications->missed_call_notification = NULL;
-  }
-  else
-    notify_notification_close (notifications->missed_call_notification, NULL);
-}
 
 static void
 notify_show_window_action_cb (NotifyNotification *notification,
@@ -160,35 +106,6 @@ on_incoming_call_gone_cb (gpointer self)
     delete priv;
 }
 
-static void
-on_missed_call_cb (boost::shared_ptr<Ekiga::CallManager>  /*manager*/,
-                   boost::shared_ptr<Ekiga::Call> call,
-                   gpointer data)
-{
-  _Notify *notifications = (_Notify *) (data);
-
-  if (notifications->missed_call_body == NULL)
-    notifications->missed_call_body = g_strdup_printf (_("Missed call from %s"),
-                                                       (const char*) call->get_remote_party_name ().c_str ());
-  else
-    notifications->missed_call_body = g_strdup_printf (_("Missed call from %s\n%s"),
-                                                       (const char*) call->get_remote_party_name ().c_str (),
-                                                       (const char*) notifications->missed_call_body);
-
-  if (notifications->missed_call_notification == NULL) {
-    notifications->missed_call_notification = notify_notification_new (_("Missed Call"),
-                                                                       notifications->missed_call_body,
-                                                                       GM_ICON_LOGO);
-    notify_notification_add_action (notifications->missed_call_notification, "default", _("Show"),
-                                    notify_missed_call_action_cb, data, NULL);
-  }
-  else
-    notify_notification_update (notifications->missed_call_notification, _("Missed Calls"),
-                                notifications->missed_call_body, GM_ICON_LOGO);
-
-  notify_notification_set_timeout (notifications->missed_call_notification, 0);
-  notify_notification_show (notifications->missed_call_notification, NULL);
-}
 
 static void
 on_unread_count_cb (G_GNUC_UNUSED GtkWidget *widget,
@@ -276,7 +193,7 @@ ekiga_incoming_call_notify (boost::shared_ptr<Ekiga::Call> call)
 static void on_setup_call_cb (boost::shared_ptr<Ekiga::CallManager> manager,
                               boost::shared_ptr<Ekiga::Call>  call)
 {
-  if (!call->is_outgoing () && !manager->get_auto_answer () && hasActionsCap ())
+  if (!call->is_outgoing () && !manager->get_auto_answer () && notify_has_actions ())
     ekiga_incoming_call_notify (call);
 }
 
@@ -287,19 +204,56 @@ static void on_setup_call_cb (boost::shared_ptr<Ekiga::CallManager> manager,
 void
 notify_start (Ekiga::ServiceCore & core)
 {
-  _Notify *notifications = new _Notify ();
-  notifications->missed_call_notification = NULL;
-  notifications->missed_call_body = NULL;
-
   boost::shared_ptr<GtkFrontend> frontend = core.get<GtkFrontend> ("gtk-frontend");
   boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
   boost::shared_ptr<Ekiga::AccountCore> account_core = core.get<Ekiga::AccountCore> ("account-core");
 
-  GtkWidget *accounts_window = GnomeMeeting::Process ()->GetAccountsWindow (); //FIXME when GOBJECT
   GtkWidget *chat_window = GTK_WIDGET (frontend->get_chat_window ());
 
   call_core->setup_call.connect (boost::bind (&on_setup_call_cb, _1, _2));
-  call_core->missed_call.connect (boost::bind (&on_missed_call_cb, _1, _2, (gpointer) notifications));
 
   g_signal_connect (chat_window, "unread-count", G_CALLBACK (on_unread_count_cb), chat_window);
 }
+
+gboolean
+notify_has_actions (void)
+{
+  static int accepts_actions = -1;
+  if (accepts_actions == -1) {  // initialise accepts_actions at the first call
+    accepts_actions = 0;
+    GList *capabilities = notify_get_server_caps ();
+    if (capabilities != NULL) {
+      for (GList *c = capabilities ; c != NULL ; c = c->next) {
+        if (strcmp ((char*)c->data, "actions") == 0 ) {
+          accepts_actions = 1;
+          break;
+        }
+      }
+      g_list_foreach (capabilities, (GFunc)g_free, NULL);
+      g_list_free (capabilities);
+    }
+  }
+  return accepts_actions;
+}
+
+gboolean
+notify_has_persistence (void)
+{
+  gboolean has;
+  GList   *caps;
+  GList   *l;
+
+  caps = notify_get_server_caps ();
+  if (caps == NULL) {
+    fprintf (stderr, "Failed to receive server caps.\n");
+    return FALSE;
+  }
+
+  l = g_list_find_custom (caps, "persistence", (GCompareFunc)strcmp);
+  has = l != NULL;
+
+  g_list_foreach (caps, (GFunc) g_free, NULL);
+  g_list_free (caps);
+
+  return has;
+}
diff --git a/src/gui/notify.h b/src/gui/notify.h
index 84148b6..c4fafaf 100644
--- a/src/gui/notify.h
+++ b/src/gui/notify.h
@@ -51,6 +51,17 @@ G_BEGIN_DECLS
  */
 void notify_start (Ekiga::ServiceCore & core);
 
+/* DESCRIPTION  : /
+ * BEHAVIOR     : Returns true if notification server supports actions.
+ */
+gboolean notify_has_actions (void);
+
+/* DESCRIPTION  : /
+ * BEHAVIOR     : Returns true if notification server supports persistent
+ *                notifications.
+ */
+gboolean notify_has_persistence (void);
+
 G_END_DECLS
 
 #endif
diff --git a/src/gui/statusicon.cpp b/src/gui/statusicon.cpp
index 6416d0a..ec037a2 100644
--- a/src/gui/statusicon.cpp
+++ b/src/gui/statusicon.cpp
@@ -105,6 +105,11 @@ unread_count_cb (GtkWidget *widget,
 static gboolean
 statusicon_blink_cb (gpointer data);
 
+static void
+status_icon_embedding_change_cb (G_GNUC_UNUSED GObject obj,
+				 G_GNUC_UNUSED GParamSpec param,
+				 G_GNUC_UNUSED gpointer data);
+
 
 /*
  * Declaration of local functions
@@ -354,6 +359,23 @@ statusicon_blink_cb (gpointer data)
 
 
 static void
+status_icon_embedding_change_cb (G_GNUC_UNUSED GObject obj,
+                                 G_GNUC_UNUSED GParamSpec param,
+                                 gpointer data)
+{
+  GtkWidget *main_window = NULL;
+  GtkStatusIcon *status_icon = NULL;
+
+  status_icon = GTK_STATUS_ICON (data);
+  main_window = GnomeMeeting::Process ()->GetMainWindow ();
+
+  /* force the main window to show if no status icon for the user */
+  if (!gtk_status_icon_is_embedded (GTK_STATUS_ICON (status_icon)))
+    gtk_widget_show (main_window);
+}
+
+
+static void
 personal_details_updated_cb (StatusIcon* self,
 			     boost::shared_ptr<Ekiga::PersonalDetails> details)
 {
@@ -601,6 +623,10 @@ statusicon_new (Ekiga::ServiceCore & core)
   g_signal_connect (self, "activate",
                     G_CALLBACK (statusicon_activated_cb), self);
 
+  g_signal_connect (self, "notify::embedded",
+		    G_CALLBACK (status_icon_embedding_change_cb), self);
+
+
   g_signal_connect (chat_window, "unread-count",
                     G_CALLBACK (unread_count_cb), self);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]