[Xfce4-commits] <xfce4-panel:master> Move hidden name handling to plugin.

Nick Schermer noreply at xfce.org
Tue Dec 28 20:50:01 CET 2010


Updating branch refs/heads/master
         to ed53fc21ce8fa4917b0243bd6dc9ca1d617b1867 (commit)
       from a2b94844ad4132af5e883f93c74c6ad242e2f9b0 (commit)

commit ed53fc21ce8fa4917b0243bd6dc9ca1d617b1867
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Dec 23 20:15:20 2010 +0100

    Move hidden name handling to plugin.
    
    Improve readability of the box widget by moving names
    handling to the panel plugin. Use _(s,g)et_hidden in the
    socket as a proxy item to store the hidden state of the icon.
    
    Also make the socket store its name, so we don't need to
    duplicate it in other widgets.

 plugins/systray/systray-box.c    |  378 +++++++-------------------------------
 plugins/systray/systray-box.h    |   19 +--
 plugins/systray/systray-socket.c |   59 ++++++-
 plugins/systray/systray-socket.h |    7 +-
 plugins/systray/systray.c        |  251 +++++++++++++++++++++++--
 5 files changed, 357 insertions(+), 357 deletions(-)

diff --git a/plugins/systray/systray-box.c b/plugins/systray/systray-box.c
index 6ac341c..7d11ac5 100644
--- a/plugins/systray/systray-box.c
+++ b/plugins/systray/systray-box.c
@@ -65,22 +65,14 @@ static void     systray_box_forall                (GtkContainer    *container,
                                                    GtkCallback      callback,
                                                    gpointer         callback_data);
 static GType    systray_box_child_type            (GtkContainer    *container);
-static void     systray_box_names_collect_visible (gpointer         key,
-                                                   gpointer         value,
-                                                   gpointer         user_data);
-static void     systray_box_names_collect_hidden  (gpointer         key,
-                                                   gpointer         value,
-                                                   gpointer         user_data);
-static gboolean systray_box_names_remove          (gpointer         key,
-                                                   gpointer         value,
-                                                   gpointer         user_data);
 static void     systray_box_button_set_arrow      (SystrayBox      *box);
 static gboolean systray_box_button_press_event    (GtkWidget       *widget,
                                                    GdkEventButton  *event,
                                                    GtkWidget       *box);
 static void     systray_box_button_clicked        (GtkToggleButton *button,
                                                    SystrayBox      *box);
-static void     systray_box_update_hidden         (SystrayBox      *box);
+static gint     systray_box_compare_function      (gconstpointer    a,
+                                                   gconstpointer    b);
 
 
 
@@ -124,9 +116,6 @@ typedef struct
   /* the child widget */
   GtkWidget    *widget;
 
-  /* whether it could be hidden */
-  guint         auto_hide : 1;
-
   /* invisible icon because of invalid requisition */
   guint         invalid : 1;
 
@@ -135,13 +124,6 @@ typedef struct
 }
 SystrayBoxChild;
 
-enum
-{
-  PROP_0,
-  PROP_NAMES_HIDDEN,
-  PROP_NAMES_VISIBLE
-};
-
 
 
 XFCE_PANEL_DEFINE_TYPE (SystrayBox, systray_box, GTK_TYPE_CONTAINER)
@@ -170,20 +152,6 @@ systray_box_class_init (SystrayBoxClass *klass)
   gtkcontainer_class->remove = systray_box_remove;
   gtkcontainer_class->forall = systray_box_forall;
   gtkcontainer_class->child_type = systray_box_child_type;
-
-  g_object_class_install_property (gobject_class,
-                                   PROP_NAMES_HIDDEN,
-                                   g_param_spec_boxed ("names-hidden",
-                                                       NULL, NULL,
-                                                       PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
-                                                       EXO_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class,
-                                   PROP_NAMES_VISIBLE,
-                                   g_param_spec_boxed ("names-visible",
-                                                       NULL, NULL,
-                                                       PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
-                                                       EXO_PARAM_READWRITE));
 }
 
 
@@ -200,7 +168,6 @@ systray_box_init (SystrayBox *box)
   box->arrow_type = GTK_ARROW_LEFT;
   box->show_hidden = FALSE;
   box->guess_size = 128;
-  box->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
   /* create arrow button */
   box->button = xfce_arrow_button_new (box->arrow_type);
@@ -221,25 +188,10 @@ systray_box_get_property (GObject      *object,
                           GValue       *value,
                           GParamSpec   *pspec)
 {
-  SystrayBox *box = XFCE_SYSTRAY_BOX (object);
-  GPtrArray  *array;
+  /*SystrayBox *box = XFCE_SYSTRAY_BOX (object);*/
 
   switch (prop_id)
     {
-    case PROP_NAMES_VISIBLE:
-      array = g_ptr_array_new ();
-      g_hash_table_foreach (box->names, systray_box_names_collect_visible, array);
-      g_value_set_boxed (value, array);
-      xfconf_array_free (array);
-      break;
-
-    case PROP_NAMES_HIDDEN:
-      array = g_ptr_array_new ();
-      g_hash_table_foreach (box->names, systray_box_names_collect_hidden, array);
-      g_value_set_boxed (value, array);
-      xfconf_array_free (array);
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -254,42 +206,10 @@ systray_box_set_property (GObject      *object,
                           const GValue *value,
                           GParamSpec   *pspec)
 {
-  SystrayBox   *box = XFCE_SYSTRAY_BOX (object);
-  GPtrArray    *array;
-  guint         i;
-  const GValue *tmp;
-  gchar        *name;
-  gboolean      hidden = TRUE;
+  /*SystrayBox   *box = XFCE_SYSTRAY_BOX (object);*/
 
   switch (prop_id)
     {
-    case PROP_NAMES_VISIBLE:
-      hidden = FALSE;
-      /* fall-though */
-
-    case PROP_NAMES_HIDDEN:
-      /* remove old names with this state */
-      g_hash_table_foreach_remove (box->names,
-                                   systray_box_names_remove,
-                                   GUINT_TO_POINTER (hidden));
-
-      /* add new values */
-      array = g_value_get_boxed (value);
-      if (G_LIKELY (array != NULL))
-        {
-          for (i = 0; i < array->len; i++)
-            {
-              tmp = g_ptr_array_index (array, i);
-              panel_assert (G_VALUE_HOLDS_STRING (tmp));
-              name = g_value_dup_string (tmp);
-              g_hash_table_replace (box->names, name, GUINT_TO_POINTER (hidden));
-            }
-        }
-
-      /* update icons in the box */
-      systray_box_update_hidden (box);
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -311,9 +231,6 @@ systray_box_finalize (GObject *object)
       g_debug ("Leaking memory, not all children have been removed");
     }
 
-  /* destroy the hash table */
-  g_hash_table_destroy (box->names);
-
   G_OBJECT_CLASS (systray_box_parent_class)->finalize (object);
 }
 
@@ -357,7 +274,7 @@ systray_box_size_request (GtkWidget      *widget,
               child_info->invalid = TRUE;
 
               /* decrease the hidden counter if needed */
-              if (child_info->auto_hide)
+              if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)))
                 box->n_hidden_childeren--;
             }
         }
@@ -370,12 +287,12 @@ systray_box_size_request (GtkWidget      *widget,
               child_info->invalid = FALSE;
 
               /* update counter */
-              if (child_info->auto_hide)
+              if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)))
                 box->n_hidden_childeren++;
             }
 
           /* count the number of visible childeren */
-          if (!child_info->auto_hide || box->show_hidden)
+          if (!systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)) || box->show_hidden)
             {
               /* get the icon size */
               icon_size = MIN (guess_size, MAX (child_req.width, child_req.height));
@@ -541,7 +458,8 @@ systray_box_size_allocate (GtkWidget     *widget,
     {
       child_info = li->data;
 
-      if (child_info->invalid || (child_info->auto_hide && !box->show_hidden))
+      if (child_info->invalid
+          || (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)) && !box->show_hidden))
         {
           /* put icons offscreen */
           child_allocation.x = child_allocation.y = OFFSCREEN;
@@ -609,7 +527,7 @@ systray_box_expose_event (GtkWidget      *widget,
 
           /* skip invisible or not composited children */
           if (child_info->invalid
-              || (child_info->auto_hide && !box->show_hidden)
+              || (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)) && !box->show_hidden)
               || !systray_socket_is_composited (XFCE_SYSTRAY_SOCKET (child_info->widget)))
             continue;
 
@@ -632,12 +550,28 @@ static void
 systray_box_add (GtkContainer *container,
                  GtkWidget    *child)
 {
-  SystrayBox *box = XFCE_SYSTRAY_BOX (container);
+  SystrayBoxChild *child_info;
+  SystrayBox      *box = XFCE_SYSTRAY_BOX (container);
 
   panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
+  panel_return_if_fail (GTK_IS_WIDGET (child));
+  panel_return_if_fail (child->parent == NULL);
+
+  /* create child info */
+  child_info = g_slice_new (SystrayBoxChild);
+  child_info->widget = child;
+  child_info->invalid = FALSE;
+
+  /* update hidden counter */
+  if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget)))
+    box->n_hidden_childeren++;
+
+  /* insert sorted */
+  box->childeren = g_slist_insert_sorted (box->childeren, child_info,
+                                          systray_box_compare_function);
 
-  /* add the entry */
-  systray_box_add_with_name (box, child, NULL);
+  /* set parent widget */
+  gtk_widget_set_parent (child, GTK_WIDGET (box));
 }
 
 
@@ -659,18 +593,16 @@ systray_box_remove (GtkContainer *container,
       if (child_info->widget == child)
         {
           /* whether the need to redraw afterwards */
-          need_resize = !child_info->auto_hide;
+          need_resize = !systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget));
 
           /* update hidden counter */
-          if (child_info->auto_hide && !child_info->invalid)
+          if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget))
+              && !child_info->invalid)
             box->n_hidden_childeren--;
 
           /* remove from list */
           box->childeren = g_slist_remove_link (box->childeren, li);
 
-          /* free name */
-          g_free (child_info->name);
-
           /* free child info */
           g_slice_free (SystrayBoxChild, child_info);
 
@@ -699,7 +631,8 @@ systray_box_forall (GtkContainer *container,
   GSList          *li;
 
   /* for button */
-  (*callback) (GTK_WIDGET (box->button), callback_data);
+  if (include_internals)
+    (*callback) (GTK_WIDGET (box->button), callback_data);
 
   /* run callback for all childeren */
   for (li = box->childeren; li != NULL; li = li->next)
@@ -721,54 +654,6 @@ systray_box_child_type (GtkContainer *container)
 
 
 
-static inline void
-systray_box_names_collect (GPtrArray   *array,
-                           const gchar *name)
-{
-  GValue *tmp;
-
-  tmp = g_new0 (GValue, 1);
-  g_value_init (tmp, G_TYPE_STRING);
-  g_value_set_string (tmp, name);
-  g_ptr_array_add (array, tmp);
-}
-
-
-
-static void
-systray_box_names_collect_visible (gpointer key,
-                                   gpointer value,
-                                   gpointer user_data)
-{
-  /* add all the visible names */
-  if (!GPOINTER_TO_UINT (value))
-    systray_box_names_collect (user_data, key);
-}
-
-
-
-static void
-systray_box_names_collect_hidden  (gpointer key,
-                                   gpointer value,
-                                   gpointer user_data)
-{
-  /* add all the hidden names */
-  if (GPOINTER_TO_UINT (value))
-    systray_box_names_collect (user_data, key);
-}
-
-
-
-static gboolean
-systray_box_names_remove (gpointer key,
-                          gpointer value,
-                          gpointer user_data)
-{
-  return GPOINTER_TO_UINT (value) == GPOINTER_TO_UINT (user_data);
-}
-
-
-
 static void
 systray_box_button_set_arrow (SystrayBox *box)
 {
@@ -827,63 +712,27 @@ systray_box_compare_function (gconstpointer a,
 {
   const SystrayBoxChild *child_a = a;
   const SystrayBoxChild *child_b = b;
+  const gchar           *name_a;
+  const gchar           *name_b;
 
   /* sort hidden icons before visible ones */
-  if (child_a->auto_hide != child_b->auto_hide)
-    return (child_a->auto_hide ? -1 : 1);
+  if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_a->widget))
+      != systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_b->widget)))
+    return (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_a->widget)) ? -1 : 1);
 
   /* put icons without name after the hidden icons */
-  if (exo_str_is_empty (child_a->name) || exo_str_is_empty (child_b->name))
+  name_a = systray_socket_get_name (XFCE_SYSTRAY_SOCKET (child_a->widget));
+  name_b = systray_socket_get_name (XFCE_SYSTRAY_SOCKET (child_b->widget));
+  if (exo_str_is_empty (name_a) || exo_str_is_empty (name_b))
     {
-      if (!exo_str_is_empty (child_a->name) == !exo_str_is_empty (child_b->name))
+      if (!exo_str_is_empty (name_a) == !exo_str_is_empty (name_b))
         return 0;
       else
-        return exo_str_is_empty (child_a->name) ? -1 : 1;
+        return exo_str_is_empty (name_a) ? -1 : 1;
     }
 
   /* sort by name */
-  return strcmp (child_a->name, child_b->name);
-}
-
-
-
-static void
-systray_box_update_hidden (SystrayBox *box)
-{
-  SystrayBoxChild *child_info;
-  GSList          *li;
-  gint             n_hidden_childeren;
-
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
-
-  /* reset counter */
-  n_hidden_childeren = 0;
-
-  /* update the icons */
-  for (li = box->childeren; li != NULL; li = li->next)
-    {
-      child_info = li->data;
-
-      /* update the hidden state */
-      child_info->auto_hide = systray_box_name_get_hidden (box, child_info->name);
-
-      /* increase counter if needed */
-      if (child_info->auto_hide && !child_info->invalid)
-        n_hidden_childeren++;
-    }
-
-  if (box->n_hidden_childeren != n_hidden_childeren)
-    {
-      /* set value */
-      box->n_hidden_childeren = n_hidden_childeren;
-
-      /* sort the list again */
-      box->childeren = g_slist_sort (box->childeren,
-          systray_box_compare_function);
-
-      /* update the box */
-      gtk_widget_queue_resize (GTK_WIDGET (box));
-    }
+  return strcmp (name_a, name_b);
 }
 
 
@@ -960,131 +809,38 @@ systray_box_get_rows (SystrayBox *box)
 
 
 void
-systray_box_add_with_name (SystrayBox  *box,
-                           GtkWidget   *child,
-                           const gchar *name)
+systray_box_update (SystrayBox *box)
 {
   SystrayBoxChild *child_info;
+  GSList          *li;
+  gint             n_hidden_childeren;
 
   panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
-  panel_return_if_fail (GTK_IS_WIDGET (child));
-  panel_return_if_fail (child->parent == NULL);
-  panel_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
-
-  /* create child info */
-  child_info = g_slice_new (SystrayBoxChild);
-  child_info->widget = child;
-  child_info->invalid = FALSE;
-  child_info->name = g_strdup (name);
-  child_info->auto_hide = systray_box_name_get_hidden (box, child_info->name);
-
-  /* update hidden counter */
-  if (child_info->auto_hide)
-      box->n_hidden_childeren++;
-
-  /* insert sorted */
-  box->childeren = g_slist_insert_sorted (box->childeren, child_info,
-                                          systray_box_compare_function);
-
-  /* set parent widget */
-  gtk_widget_set_parent (child, GTK_WIDGET (box));
-}
-
-
-
-void
-systray_box_name_add (SystrayBox  *box,
-                      const gchar *name,
-                      gboolean     hidden)
-{
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
-  panel_return_if_fail (!exo_str_is_empty (name));
-
-  /* insert the application */
-  g_hash_table_insert (box->names, g_strdup (name),
-                       GUINT_TO_POINTER (hidden ? 1 : 0));
-
-  g_object_notify (G_OBJECT (box), hidden ? "names-hidden"
-                   : "names-visible");
-}
 
+  /* reset counter */
+  n_hidden_childeren = 0;
 
-
-void
-systray_box_name_set_hidden (SystrayBox  *box,
-                             const gchar *name,
-                             gboolean     hidden)
-{
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
-  panel_return_if_fail (!exo_str_is_empty (name));
-
-  /* replace the old name */
-  g_hash_table_replace (box->names, g_strdup (name),
-      GUINT_TO_POINTER (hidden ? 1 : 0));
-
-  /* save new values */
-  g_object_notify (G_OBJECT (box), "names-hidden");
-  g_object_notify (G_OBJECT (box), "names-visible");
-
-  /* update the box */
-  systray_box_update_hidden (box);
-}
-
-
-
-gboolean
-systray_box_name_get_hidden (SystrayBox  *box,
-                             const gchar *name)
-{
-  gpointer p;
-
-  /* do not hide icons without name */
-  if (G_UNLIKELY (name == NULL))
-    return FALSE;
-
-  /* lookup the name in the table */
-  p = g_hash_table_lookup (box->names, name);
-  if (G_UNLIKELY (p == NULL))
+  /* update the icons */
+  for (li = box->childeren; li != NULL; li = li->next)
     {
-      /* add the name */
-      systray_box_name_add (box, name, FALSE);
+      child_info = li->data;
 
-      /* do not hide the icon */
-      return FALSE;
-    }
-  else
-    {
-      return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE);
+      /* increase counter if needed */
+      if (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child_info->widget))
+          && !child_info->invalid)
+        n_hidden_childeren++;
     }
-}
-
-
 
-GList *
-systray_box_name_list (SystrayBox *box)
-{
-  GList *keys;
-
-  /* get the hash table keys */
-  keys = g_hash_table_get_keys (box->names);
-
-  /* sort the list */
-  keys = g_list_sort (keys, (GCompareFunc) strcmp);
-
-  return keys;
-}
-
-
-
-void
-systray_box_name_clear (SystrayBox *box)
-{
-  /* remove all the entries from the list */
-  g_hash_table_remove_all (box->names);
+  if (box->n_hidden_childeren != n_hidden_childeren)
+    {
+      /* set value */
+      box->n_hidden_childeren = n_hidden_childeren;
 
-  g_object_notify (G_OBJECT (box), "names-hidden");
-  g_object_notify (G_OBJECT (box), "names-visible");
+      /* sort the list again */
+      box->childeren = g_slist_sort (box->childeren,
+          systray_box_compare_function);
 
-  systray_box_update_hidden (box);
+      /* update the box */
+      gtk_widget_queue_resize (GTK_WIDGET (box));
+    }
 }
-
diff --git a/plugins/systray/systray-box.h b/plugins/systray/systray-box.h
index 493364f..d28c10c 100644
--- a/plugins/systray/systray-box.h
+++ b/plugins/systray/systray-box.h
@@ -46,23 +46,6 @@ void       systray_box_set_rows        (SystrayBox          *box,
 
 gint       systray_box_get_rows        (SystrayBox          *box);
 
-void       systray_box_add_with_name   (SystrayBox          *box,
-                                        GtkWidget           *child,
-                                        const gchar         *name);
-
-void       systray_box_name_add        (SystrayBox          *box,
-                                        const gchar         *name,
-                                        gboolean             hidden);
-
-void       systray_box_name_set_hidden (SystrayBox          *box,
-                                        const gchar         *name,
-                                        gboolean             hidden);
-
-gboolean   systray_box_name_get_hidden (SystrayBox          *box,
-                                        const gchar         *name);
-
-GList     *systray_box_name_list       (SystrayBox          *box);
-
-void       systray_box_name_clear      (SystrayBox          *box);
+void       systray_box_update          (SystrayBox          *box);
 
 #endif /* !__SYSTRAY_BOX_H__ */
diff --git a/plugins/systray/systray-socket.c b/plugins/systray/systray-socket.c
index 4d1c5de..8718078 100644
--- a/plugins/systray/systray-socket.c
+++ b/plugins/systray/systray-socket.c
@@ -52,12 +52,16 @@ struct _SystraySocket
   /* plug window */
   GdkNativeWindow window;
 
-  guint           is_composited : 1;
-  guint           parent_relative_bg : 1;
+  gchar           *name;
+
+  guint            is_composited : 1;
+  guint            parent_relative_bg : 1;
+  guint            hidden : 1;
 };
 
 
 
+static void     systray_socket_finalize      (GObject        *object);
 static void     systray_socket_realize       (GtkWidget      *widget);
 static void     systray_socket_size_allocate (GtkWidget      *widget,
                                               GtkAllocation  *allocation);
@@ -76,6 +80,10 @@ static void
 systray_socket_class_init (SystraySocketClass *klass)
 {
   GtkWidgetClass *gtkwidget_class;
+  GObjectClass   *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = systray_socket_finalize;
 
   gtkwidget_class = GTK_WIDGET_CLASS (klass);
   gtkwidget_class->realize = systray_socket_realize;
@@ -89,6 +97,20 @@ systray_socket_class_init (SystraySocketClass *klass)
 static void
 systray_socket_init (SystraySocket *socket)
 {
+  socket->hidden = FALSE;
+  socket->name = NULL;
+}
+
+
+
+static void
+systray_socket_finalize (GObject *object)
+{
+  SystraySocket *socket = XFCE_SYSTRAY_SOCKET (object);
+
+  g_free (socket->name);
+
+  G_OBJECT_CLASS (systray_socket_parent_class)->finalize (object);
 }
 
 
@@ -307,10 +329,9 @@ systray_socket_is_composited (SystraySocket *socket)
 
 
 
-gchar *
-systray_socket_get_title  (SystraySocket *socket)
+const gchar *
+systray_socket_get_name  (SystraySocket *socket)
 {
-  gchar      *name = NULL;
   GdkDisplay *display;
   Atom        utf8_string, type;
   gint        result;
@@ -321,6 +342,9 @@ systray_socket_get_title  (SystraySocket *socket)
 
   panel_return_val_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket), NULL);
 
+  if (socket->name != NULL)
+    return socket->name;
+
   display = gtk_widget_get_display (GTK_WIDGET (socket));
 
   utf8_string = gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING");
@@ -350,11 +374,11 @@ systray_socket_get_title  (SystraySocket *socket)
       return NULL;
     }
 
-  name = g_utf8_strdown (val, nitems);
+  socket->name = g_utf8_strdown (val, nitems);
 
   XFree (val);
 
-  return name;
+  return socket->name;
 }
 
 
@@ -366,3 +390,24 @@ systray_socket_get_window (SystraySocket *socket)
 
   return &socket->window;
 }
+
+
+
+gboolean
+systray_socket_get_hidden (SystraySocket *socket)
+{
+  panel_return_val_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket), FALSE);
+
+  return socket->hidden;
+}
+
+
+
+void
+systray_socket_set_hidden (SystraySocket *socket,
+                           gboolean       hidden)
+{
+  panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket));
+
+  socket->hidden = hidden;
+}
diff --git a/plugins/systray/systray-socket.h b/plugins/systray/systray-socket.h
index 42a6588..bda91f8 100644
--- a/plugins/systray/systray-socket.h
+++ b/plugins/systray/systray-socket.h
@@ -45,8 +45,13 @@ void             systray_socket_force_redraw  (SystraySocket   *socket);
 
 gboolean         systray_socket_is_composited (SystraySocket   *socket);
 
-gchar           *systray_socket_get_title     (SystraySocket   *socket) G_GNUC_MALLOC;
+const gchar     *systray_socket_get_name      (SystraySocket   *socket);
 
 GdkNativeWindow *systray_socket_get_window    (SystraySocket   *socket);
 
+gboolean         systray_socket_get_hidden    (SystraySocket   *socket);
+
+void             systray_socket_set_hidden    (SystraySocket   *socket,
+                                               gboolean         hidden);
+
 #endif /* !__SYSTRAY_SOCKET_H__ */
diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c
index f869b6c..9e4b626 100644
--- a/plugins/systray/systray.c
+++ b/plugins/systray/systray.c
@@ -55,6 +55,18 @@ static void     systray_plugin_orientation_changed          (XfcePanelPlugin
 static gboolean systray_plugin_size_changed                 (XfcePanelPlugin       *panel_plugin,
                                                              gint                   size);
 static void     systray_plugin_configure_plugin             (XfcePanelPlugin       *panel_plugin);
+static void     systray_plugin_names_collect_visible        (gpointer               key,
+                                                             gpointer               value,
+                                                             gpointer               user_data);
+static void     systray_plugin_names_collect_hidden         (gpointer               key,
+                                                             gpointer               value,
+                                                             gpointer               user_data);
+static gboolean systray_plugin_names_remove                 (gpointer               key,
+                                                             gpointer               value,
+                                                             gpointer               user_data);
+static void     systray_plugin_names_update                 (SystrayPlugin         *plugin);
+static gboolean systray_plugin_names_get_hidden             (SystrayPlugin         *plugin,
+                                                             const gchar           *name);
 static void     systray_plugin_icon_added                   (SystrayManager        *manager,
                                                              GtkWidget             *icon,
                                                              SystrayPlugin         *plugin);
@@ -93,13 +105,16 @@ struct _SystrayPlugin
 
   /* settings */
   guint           show_frame : 1;
+  GHashTable     *names;
 };
 
 enum
 {
   PROP_0,
   PROP_ROWS,
-  PROP_SHOW_FRAME
+  PROP_SHOW_FRAME,
+  PROP_NAMES_HIDDEN,
+  PROP_NAMES_VISIBLE
 };
 
 enum
@@ -161,6 +176,20 @@ systray_plugin_class_init (SystrayPluginClass *klass)
                                                          NULL, NULL,
                                                          TRUE,
                                                          EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_NAMES_HIDDEN,
+                                   g_param_spec_boxed ("names-hidden",
+                                                       NULL, NULL,
+                                                       PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
+                                                       EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_NAMES_VISIBLE,
+                                   g_param_spec_boxed ("names-visible",
+                                                       NULL, NULL,
+                                                       PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
+                                                       EXO_PARAM_READWRITE));
 }
 
 
@@ -171,6 +200,7 @@ systray_plugin_init (SystrayPlugin *plugin)
   plugin->manager = NULL;
   plugin->show_frame = TRUE;
   plugin->idle_startup = 0;
+  plugin->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
   plugin->frame = gtk_frame_new (NULL);
   gtk_container_add (GTK_CONTAINER (plugin), plugin->frame);
@@ -193,6 +223,7 @@ systray_plugin_get_property (GObject    *object,
 {
   SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object);
   guint          rows;
+  GPtrArray     *array;
 
   switch (prop_id)
     {
@@ -205,6 +236,20 @@ systray_plugin_get_property (GObject    *object,
       g_value_set_boolean (value, plugin->show_frame);
       break;
 
+   case PROP_NAMES_VISIBLE:
+      array = g_ptr_array_new ();
+      g_hash_table_foreach (plugin->names, systray_plugin_names_collect_visible, array);
+      g_value_set_boxed (value, array);
+      xfconf_array_free (array);
+      break;
+
+    case PROP_NAMES_HIDDEN:
+      array = g_ptr_array_new ();
+      g_hash_table_foreach (plugin->names, systray_plugin_names_collect_hidden, array);
+      g_value_set_boxed (value, array);
+      xfconf_array_free (array);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -221,6 +266,11 @@ systray_plugin_set_property (GObject      *object,
 {
   SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object);
   gboolean       show_frame;
+  gboolean       hidden = TRUE;
+  GPtrArray     *array;
+  const GValue  *tmp;
+  gchar         *name;
+  guint          i;
 
   switch (prop_id)
     {
@@ -239,6 +289,33 @@ systray_plugin_set_property (GObject      *object,
         }
       break;
 
+    case PROP_NAMES_VISIBLE:
+      hidden = FALSE;
+      /* fall-though */
+
+    case PROP_NAMES_HIDDEN:
+      /* remove old names with this state */
+      g_hash_table_foreach_remove (plugin->names,
+                                   systray_plugin_names_remove,
+                                   GUINT_TO_POINTER (hidden));
+
+      /* add new values */
+      array = g_value_get_boxed (value);
+      if (G_LIKELY (array != NULL))
+        {
+          for (i = 0; i < array->len; i++)
+            {
+              tmp = g_ptr_array_index (array, i);
+              panel_assert (G_VALUE_HOLDS_STRING (tmp));
+              name = g_value_dup_string (tmp);
+              g_hash_table_replace (plugin->names, name, GUINT_TO_POINTER (hidden));
+            }
+        }
+
+      /* update icons in the box */
+      systray_plugin_names_update (plugin);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -320,10 +397,6 @@ systray_plugin_construct (XfcePanelPlugin *panel_plugin)
   {
     { "rows", G_TYPE_UINT },
     { "show-frame", G_TYPE_BOOLEAN },
-    { NULL }
-  };
-  const PanelProperty  box_properties[] =
-  {
     { "names-visible", PANEL_PROPERTIES_TYPE_VALUE_ARRAY },
     { "names-hidden", PANEL_PROPERTIES_TYPE_VALUE_ARRAY },
     { NULL }
@@ -331,13 +404,9 @@ systray_plugin_construct (XfcePanelPlugin *panel_plugin)
 
   xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (plugin));
 
-  /* bind all properties */
   panel_properties_bind (NULL, G_OBJECT (plugin),
                          xfce_panel_plugin_get_property_base (panel_plugin),
                          properties, FALSE);
-  panel_properties_bind (NULL, G_OBJECT (plugin->box),
-                         xfce_panel_plugin_get_property_base (panel_plugin),
-                         box_properties, FALSE);
 
   /* monitor screen changes */
   g_signal_connect (G_OBJECT (plugin), "screen-changed",
@@ -360,6 +429,8 @@ systray_plugin_free_data (XfcePanelPlugin *panel_plugin)
   g_signal_handlers_disconnect_by_func (G_OBJECT (plugin),
       systray_plugin_screen_changed, NULL);
 
+  g_hash_table_destroy (plugin->names);
+
   if (G_LIKELY (plugin->manager != NULL))
     {
       systray_manager_unregister (plugin->manager);
@@ -519,21 +590,156 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
 
 
 static void
+systray_plugin_names_collect (GPtrArray   *array,
+                              const gchar *name)
+{
+  GValue *tmp;
+
+  tmp = g_new0 (GValue, 1);
+  g_value_init (tmp, G_TYPE_STRING);
+  g_value_set_string (tmp, name);
+  g_ptr_array_add (array, tmp);
+}
+
+
+
+static void
+systray_plugin_names_collect_visible (gpointer key,
+                                      gpointer value,
+                                      gpointer user_data)
+{
+  /* add all the visible names */
+  if (!GPOINTER_TO_UINT (value))
+    systray_plugin_names_collect (user_data, key);
+}
+
+
+
+static void
+systray_plugin_names_collect_hidden (gpointer key,
+                                     gpointer value,
+                                     gpointer user_data)
+{
+  /* add all the hidden names */
+  if (GPOINTER_TO_UINT (value))
+    systray_plugin_names_collect (user_data, key);
+}
+
+
+
+static gboolean
+systray_plugin_names_remove (gpointer key,
+                             gpointer value,
+                             gpointer user_data)
+{
+  return GPOINTER_TO_UINT (value) == GPOINTER_TO_UINT (user_data);
+}
+
+
+
+static void
+systray_plugin_names_update_icon (GtkWidget *icon,
+                                  gpointer   data)
+{
+  SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (data);
+  SystraySocket *socket = XFCE_SYSTRAY_SOCKET (icon);
+  const gchar   *name;
+
+  panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+  panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (icon));
+
+  name = systray_socket_get_name (socket);
+  systray_socket_set_hidden (socket,
+      systray_plugin_names_get_hidden (plugin, name));
+}
+
+
+
+static void
+systray_plugin_names_update (SystrayPlugin *plugin)
+{
+  panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+
+  gtk_container_foreach (GTK_CONTAINER (plugin->box),
+     systray_plugin_names_update_icon, plugin);
+  systray_box_update (XFCE_SYSTRAY_BOX (plugin->box));
+}
+
+
+
+static void
+systray_plugin_names_set_hidden (SystrayPlugin *plugin,
+                                 const gchar   *name,
+                                 gboolean       hidden)
+{
+  panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+  panel_return_if_fail (!exo_str_is_empty (name));
+
+  g_hash_table_replace (plugin->names, g_strdup (name),
+                        GUINT_TO_POINTER (hidden ? 1 : 0));
+
+  systray_plugin_names_update (plugin);
+
+  g_object_notify (G_OBJECT (plugin), "names-visible");
+  g_object_notify (G_OBJECT (plugin), "names-hidden");
+}
+
+
+
+static gboolean
+systray_plugin_names_get_hidden (SystrayPlugin *plugin,
+                                 const gchar   *name)
+{
+  gpointer p;
+
+  if (exo_str_is_empty (name))
+    return FALSE;
+
+  /* lookup the name in the table */
+  p = g_hash_table_lookup (plugin->names, name);
+  if (G_UNLIKELY (p == NULL))
+    {
+      /* add the new name */
+      g_hash_table_insert (plugin->names, g_strdup (name), GUINT_TO_POINTER (0));
+      g_object_notify (G_OBJECT (plugin), "names-visible");
+
+      /* do not hide the icon */
+      return FALSE;
+    }
+  else
+    {
+      return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE);
+    }
+}
+
+
+
+static void
+systray_plugin_names_clear (SystrayPlugin *plugin)
+{
+  g_hash_table_remove_all (plugin->names);
+
+  g_object_notify (G_OBJECT (plugin), "names-hidden");
+  g_object_notify (G_OBJECT (plugin), "names-visible");
+
+  systray_plugin_names_update (plugin);
+}
+
+
+
+static void
 systray_plugin_icon_added (SystrayManager *manager,
                            GtkWidget      *icon,
                            SystrayPlugin  *plugin)
 {
-  gchar *name;
-
   panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
   panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+  panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (icon));
   panel_return_if_fail (plugin->manager == manager);
   panel_return_if_fail (GTK_IS_WIDGET (icon));
 
-  name = systray_socket_get_title (XFCE_SYSTRAY_SOCKET (icon));
-  systray_box_add_with_name (XFCE_SYSTRAY_BOX (plugin->box), icon, name);
-  g_free (name);
-
+  systray_plugin_names_update_icon (icon, plugin);
+  gtk_container_add (GTK_CONTAINER (plugin->box), icon);
   gtk_widget_show (icon);
 }
 
@@ -665,7 +871,9 @@ systray_plugin_dialog_add_application_names (SystrayPlugin *plugin,
   icon_theme = gtk_icon_theme_get_default ();
 
   /* get the know application names and insert them in the store */
-  names = systray_box_name_list (XFCE_SYSTRAY_BOX (plugin->box));
+  /* TODO use foreach here */
+  names = g_hash_table_get_keys (plugin->names);
+  names = g_list_sort (names, (GCompareFunc) strcmp);
   for (li = names; li != NULL; li = li->next)
     {
       name = li->data;
@@ -677,7 +885,7 @@ systray_plugin_dialog_add_application_names (SystrayPlugin *plugin,
       title = NULL;
       icon_name = name;
       camelcase = NULL;
-      hidden = systray_box_name_get_hidden (XFCE_SYSTRAY_BOX (plugin->box), name);
+      hidden = systray_plugin_names_get_hidden (plugin, name);
 
       /* check if we have a better name for the application */
       for (i = 0; i < G_N_ELEMENTS (known_applications); i++)
@@ -740,9 +948,12 @@ systray_plugin_dialog_hidden_toggled (GtkCellRendererToggle *renderer,
                           COLUMN_HIDDEN, &hidden,
                           COLUMN_INTERNAL_NAME, &name, -1);
 
+      /* insert value (we need to update it) */
+      hidden = !hidden;
+
       /* update box and store with new state */
-      systray_box_name_set_hidden (XFCE_SYSTRAY_BOX (plugin->box), name, !hidden);
-      gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, !hidden, -1);
+      systray_plugin_names_set_hidden (plugin, name, hidden);
+      gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, hidden, -1);
 
       g_free (name);
     }
@@ -768,6 +979,6 @@ systray_plugin_dialog_clear_clicked (GtkWidget     *button,
       panel_return_if_fail (GTK_IS_LIST_STORE (store));
       gtk_list_store_clear (store);
 
-      systray_box_name_clear (XFCE_SYSTRAY_BOX (plugin->box));
+      systray_plugin_names_clear (plugin);
     }
 }



More information about the Xfce4-commits mailing list