[Xfce4-commits] <xfce4-indicator-plugin:master> Added support for indicator reordering.

Andrzej noreply at xfce.org
Thu Apr 4 17:44:23 CEST 2013


Updating branch refs/heads/master
         to 0db001bdd6e764e2e375ac69ad01418c09c3b6da (commit)
       from 86c62c471dcaf3f2a9b84a501e9e49d2ffc1152e (commit)

commit 0db001bdd6e764e2e375ac69ad01418c09c3b6da
Author: Andrzej <ndrwrdck at gmail.com>
Date:   Tue Mar 12 02:08:51 2013 +0000

    Added support for indicator reordering.
    
    Fairly extensive changes to the indicator container class.
    Needs testing with more complex indicators (globalmenu etc).

 panel-plugin/indicator-box.c    |  318 +++++++++++++++++++++++----------------
 panel-plugin/indicator-button.c |   13 ++
 panel-plugin/indicator-button.h |   28 ++--
 panel-plugin/indicator.c        |   12 +-
 4 files changed, 227 insertions(+), 144 deletions(-)

diff --git a/panel-plugin/indicator-box.c b/panel-plugin/indicator-box.c
index 2766bc1..a48f22b 100644
--- a/panel-plugin/indicator-box.c
+++ b/panel-plugin/indicator-box.c
@@ -34,6 +34,8 @@
 #include "indicator-button.h"
 
 static void                 xfce_indicator_box_finalize       (GObject          *object);
+static void                 xfce_indicator_box_list_changed   (XfceIndicatorBox *box,
+                                                               IndicatorConfig  *config);
 static void                 xfce_indicator_box_add            (GtkContainer     *container,
                                                                GtkWidget        *child);
 static void                 xfce_indicator_box_remove         (GtkContainer     *container,
@@ -55,7 +57,7 @@ struct _XfceIndicatorBox
 
   IndicatorConfig      *config;
 
-  GSList               *children;
+  GHashTable           *children;
 
   gint                  panel_size;
   gint                  nrows;
@@ -64,6 +66,8 @@ struct _XfceIndicatorBox
 
   GtkOrientation        panel_orientation;
   GtkOrientation        orientation;
+
+  gulong                indicator_list_changed_id;
 };
 
 struct _XfceIndicatorBoxClass
@@ -107,7 +111,12 @@ xfce_indicator_box_init (XfceIndicatorBox *box)
   gtk_widget_set_can_focus(GTK_WIDGET(box), TRUE);
   gtk_container_set_border_width(GTK_CONTAINER(box), 0);
 
-  box->children = NULL;
+  /* todo: no deallocation function for values */
+  box->children = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  box->indicator_list_changed_id =
+    g_signal_connect_swapped (G_OBJECT (box->config), "indicator-list-changed",
+                              G_CALLBACK (xfce_indicator_box_list_changed), box);
 }
 
 
@@ -117,12 +126,14 @@ xfce_indicator_box_finalize (GObject *object)
 {
   XfceIndicatorBox *box = XFCE_INDICATOR_BOX (object);
 
-  if (box->children != NULL)
+  if (box->indicator_list_changed_id != 0)
     {
-      g_slist_free (box->children);
-      g_debug ("Not all icons have been removed from the indicator icon box.");
+      g_signal_handler_disconnect (box->config, box->indicator_list_changed_id);
+      box->indicator_list_changed_id = 0;
     }
 
+  g_hash_table_destroy (box->children);
+
   G_OBJECT_CLASS (xfce_indicator_box_parent_class)->finalize (object);
 }
 
@@ -141,16 +152,34 @@ xfce_indicator_box_new (IndicatorConfig *config)
 
 
 static void
+xfce_indicator_box_list_changed (XfceIndicatorBox *box,
+                                 IndicatorConfig  *config)
+{
+  g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
+  g_return_if_fail (XFCE_IS_INDICATOR_CONFIG (config));
+
+  gtk_widget_queue_resize (GTK_WIDGET (box));
+}
+
+
+
+static void
 xfce_indicator_box_add (GtkContainer *container,
                         GtkWidget    *child)
 {
   XfceIndicatorBox    *box = XFCE_INDICATOR_BOX (container);
+  XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (child);
+  GList               *li;
+  const gchar         *io_name;
 
   g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
-  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
   g_return_if_fail (child->parent == NULL);
 
-  box->children = g_slist_append (box->children, child);
+  io_name = xfce_indicator_button_get_io_name (button);
+  li = g_hash_table_lookup (box->children, io_name);
+  li = g_list_append (li, button);
+  g_hash_table_replace (box->children, g_strdup (io_name), li);
 
   gtk_widget_set_parent (child, GTK_WIDGET (box));
 
@@ -163,17 +192,22 @@ static void
 xfce_indicator_box_remove (GtkContainer *container,
                            GtkWidget    *child)
 {
-  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (container);
-  GSList           *li;
+  XfceIndicatorBox    *box = XFCE_INDICATOR_BOX (container);
+  XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (child);
+  GList               *li, *li_tmp;
+  const gchar         *io_name;
 
   /* search the child */
-  li = g_slist_find (box->children, child);
-  if (G_LIKELY (li != NULL))
+  io_name = xfce_indicator_button_get_io_name (button);
+  li = g_hash_table_lookup (box->children, io_name);
+  li_tmp = g_list_find (li, child);
+  if (G_LIKELY (li_tmp != NULL))
     {
-      g_assert (GTK_WIDGET (li->data) == child);
+      g_assert (GTK_WIDGET (li_tmp->data) == child);
 
       /* unparent widget */
-      box->children = g_slist_remove_link (box->children, li);
+      li = g_list_remove_link (li, li_tmp);
+      g_hash_table_replace (box->children, g_strdup (io_name), li);
       gtk_widget_unparent (child);
 
       /* resize, so we update has-hidden */
@@ -190,13 +224,23 @@ xfce_indicator_box_forall (GtkContainer *container,
                            gpointer      callback_data)
 {
   XfceIndicatorBox *box = XFCE_INDICATOR_BOX (container);
-  GSList           *li, *lnext;
+  GList            *known_indicators;
+  GList            *li, *li_int, *li_tmp;
 
   /* run callback for all children */
-  for (li = box->children; li != NULL; li = lnext)
+  known_indicators = indicator_config_get_known_indicators (box->config);
+  for (li = known_indicators; li != NULL; li = li->next)
+    {
+      li_int = g_hash_table_lookup (box->children, li->data);
+      for (li_tmp = li_int; li_tmp != NULL; li_tmp = li_tmp->next)
+        {
+          (*callback) (GTK_WIDGET (li_tmp->data), callback_data);
+        }
+    }
+  li_int = g_hash_table_lookup (box->children, "<placeholder>");
+  for (li_tmp = li_int; li_tmp != NULL; li_tmp = li_tmp->next)
     {
-      lnext = li->next;
-      (*callback) (GTK_WIDGET (li->data), callback_data);
+      (*callback) (GTK_WIDGET (li_tmp->data), callback_data);
     }
 }
 
@@ -205,7 +249,7 @@ xfce_indicator_box_forall (GtkContainer *container,
 static GType
 xfce_indicator_box_child_type (GtkContainer *container)
 {
-  return GTK_TYPE_WIDGET;
+  return XFCE_TYPE_INDICATOR_BUTTON;
 }
 
 
@@ -234,17 +278,17 @@ static void
 xfce_indicator_box_size_request (GtkWidget      *widget,
                                  GtkRequisition *requisition)
 {
-  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (widget);
-  GtkWidget        *child;
-  GtkRequisition    child_req;
-  GSList           *li;
-  gint              panel_size;
-  gint              length;
-  gint              row;
-  gint              nrows;
-  gint              x;
-  gboolean          has_label;
-  GtkOrientation    panel_orientation;
+  XfceIndicatorBox    *box = XFCE_INDICATOR_BOX (widget);
+  XfceIndicatorButton *button;
+  GtkRequisition       child_req;
+  GList               *known_indicators, *li, *li_int, *li_tmp;
+  gint                 panel_size;
+  gint                 length;
+  gint                 row;
+  gint                 nrows;
+  gint                 x;
+  gboolean             has_label;
+  GtkOrientation       panel_orientation;
 
   panel_size = indicator_config_get_panel_size (box->config);
   panel_orientation = indicator_config_get_panel_orientation (box->config);
@@ -253,34 +297,41 @@ xfce_indicator_box_size_request (GtkWidget      *widget,
   x = 0;
   nrows = panel_size / xfce_indicator_box_get_row_size (box);
 
-  for (li = box->children; li != NULL; li = li->next)
+  if (g_hash_table_lookup (box->children, "<placeholder>") != NULL)
+    known_indicators = g_list_append (NULL, "<placeholder>");
+  else
+    known_indicators = indicator_config_get_known_indicators (box->config);
+  for (li = known_indicators; li != NULL; li = li->next)
     {
-      child = GTK_WIDGET (li->data);
-      g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
-
-      gtk_widget_size_request (child, &child_req);
-      has_label = (xfce_indicator_button_get_label (XFCE_INDICATOR_BUTTON (child)) != NULL);
-
-      /* wrap rows if column is overflowing or a label is encountered */
-      if (row > 0 && (has_label || row >= nrows))
-        {
-          x += length;
-          row = 0;
-          length = 0;
-        }
-
-      length =
-        MAX (length, (panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
-
-      if (has_label || row >= nrows)
-        {
-          x += length;
-          row = 0;
-          length = 0;
-        }
-      else
+      li_int = g_hash_table_lookup (box->children, li->data);
+      for (li_tmp = li_int; li_tmp != NULL; li_tmp = li_tmp->next)
         {
-          row += 1;
+          button = XFCE_INDICATOR_BUTTON (li_tmp->data);
+
+          gtk_widget_size_request (GTK_WIDGET (button), &child_req);
+          has_label = (xfce_indicator_button_get_label (button) != NULL);
+
+          /* wrap rows if column is overflowing or a label is encountered */
+          if (row > 0 && (has_label || row >= nrows))
+            {
+              x += length;
+              row = 0;
+              length = 0;
+            }
+
+          length =
+            MAX (length, (panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
+
+          if (has_label || row >= nrows)
+            {
+              x += length;
+              row = 0;
+              length = 0;
+            }
+          else
+            {
+              row += 1;
+            }
         }
     }
 
@@ -305,19 +356,19 @@ static void
 xfce_indicator_box_size_allocate (GtkWidget     *widget,
                                   GtkAllocation *allocation)
 {
-  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (widget);
-  GtkWidget        *child;
-  GtkAllocation     child_alloc;
-  GtkRequisition    child_req;
-  gint              panel_size, size;
-  gint              x, y;
-  gint              x0, y0;
-  GSList           *li;
-  gint              length, width;
-  gint              row;
-  gint              nrows;
-  gboolean          has_label;
-  GtkOrientation    panel_orientation;
+  XfceIndicatorBox    *box = XFCE_INDICATOR_BOX (widget);
+  XfceIndicatorButton *button;
+  GtkAllocation        child_alloc;
+  GtkRequisition       child_req;
+  gint                 panel_size, size;
+  gint                 x, y;
+  gint                 x0, y0;
+  GList               *known_indicators, *li, *li_int, *li_tmp;
+  gint                 length, width;
+  gint                 row;
+  gint                 nrows;
+  gboolean             has_label;
+  GtkOrientation       panel_orientation;
 
   row = 0;
   length = 0;
@@ -331,59 +382,66 @@ xfce_indicator_box_size_allocate (GtkWidget     *widget,
   nrows = panel_size / xfce_indicator_box_get_row_size (box);
   size = panel_size / nrows;
 
-  for (li = box->children; li != NULL; li = li->next)
+  if (g_hash_table_lookup (box->children, "<placeholder>") != NULL)
+    known_indicators = g_list_append (NULL, "<placeholder>");
+  else
+    known_indicators = indicator_config_get_known_indicators (box->config);
+  for (li = known_indicators; li != NULL; li = li->next)
     {
-      child = GTK_WIDGET (li->data);
-      g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
-
-      gtk_widget_get_child_requisition (child, &child_req);
-
-      has_label = (xfce_indicator_button_get_label (XFCE_INDICATOR_BUTTON (child)) != NULL);
-
-      /* wrap rows if column is overflowing or a label is encountered */
-      if (row > 0 && (has_label || row >= nrows))
+      li_int = g_hash_table_lookup (box->children, li->data);
+      for (li_tmp = li_int; li_tmp != NULL; li_tmp = li_tmp->next)
         {
-          x += length;
-          y = 0;
-          row = 0;
-          length = 0;
-        }
-
-      width = (has_label) ? panel_size : size;
-      length = MAX (length,
-                    (panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
-
-      if (panel_orientation == GTK_ORIENTATION_HORIZONTAL)
-        {
-          child_alloc.x = x0 + x;
-          child_alloc.y = y0 + y;
-          child_alloc.width = length;
-          child_alloc.height = width;
-        }
-      else
-        {
-          child_alloc.x = x0 + y;
-          child_alloc.y = y0 + x;
-          child_alloc.width = width;
-          child_alloc.height = length;
-        }
-
-      /* g_debug ("indicator-box size allocate: x=%d y=%d w=%d h=%d", */
-      /*          child_alloc.x, child_alloc.y, child_alloc.width, child_alloc.height); */
-
-      gtk_widget_size_allocate (child, &child_alloc);
-
-      if (has_label || row >= nrows)
-        {
-          x += length;
-          y = 0;
-          row = 0;
-          length = 0;
-        }
-      else
-        {
-          row += 1;
-          y += size;
+          button = XFCE_INDICATOR_BUTTON (li_tmp->data);
+
+          gtk_widget_get_child_requisition (GTK_WIDGET (button), &child_req);
+
+          has_label = (xfce_indicator_button_get_label (button) != NULL);
+
+          /* wrap rows if column is overflowing or a label is encountered */
+          if (row > 0 && (has_label || row >= nrows))
+            {
+              x += length;
+              y = 0;
+              row = 0;
+              length = 0;
+            }
+
+          width = (has_label) ? panel_size : size;
+          length = MAX (length,
+                        (panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
+
+          if (panel_orientation == GTK_ORIENTATION_HORIZONTAL)
+            {
+              child_alloc.x = x0 + x;
+              child_alloc.y = y0 + y;
+              child_alloc.width = length;
+              child_alloc.height = width;
+            }
+          else
+            {
+              child_alloc.x = x0 + y;
+              child_alloc.y = y0 + x;
+              child_alloc.width = width;
+              child_alloc.height = length;
+            }
+
+          /* g_debug ("indicator-box size allocate: x=%d y=%d w=%d h=%d", */
+          /*          child_alloc.x, child_alloc.y, child_alloc.width, child_alloc.height); */
+
+          gtk_widget_size_allocate (GTK_WIDGET (button), &child_alloc);
+
+          if (has_label || row >= nrows)
+            {
+              x += length;
+              y = 0;
+              row = 0;
+              length = 0;
+            }
+          else
+            {
+              row += 1;
+              y += size;
+            }
         }
     }
 }
@@ -394,22 +452,24 @@ void
 xfce_indicator_box_remove_entry (XfceIndicatorBox     *box,
                                  IndicatorObjectEntry *entry)
 {
-  GSList              *li;
-  GtkWidget           *child;
+  GList               *known_indicators, *li, *li_int, *li_tmp;
   XfceIndicatorButton *button;
 
   g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
 
-  for (li = box->children; li != NULL; li = li->next)
+  known_indicators = indicator_config_get_known_indicators (box->config);
+  for (li = known_indicators; li != NULL; li = li->next)
     {
-      child = GTK_WIDGET (li->data);
-      g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
-
-      button = XFCE_INDICATOR_BUTTON (child);
-      if (xfce_indicator_button_get_entry (button) == entry)
+      li_int = g_hash_table_lookup (box->children, li->data);
+      for (li_tmp = li_int; li_tmp != NULL; li_tmp = li_tmp->next)
         {
-          xfce_indicator_button_disconnect_signals (button);
-          gtk_widget_destroy (GTK_WIDGET (button));
+          button = XFCE_INDICATOR_BUTTON (li_tmp->data);
+          if (xfce_indicator_button_get_entry (button) == entry)
+            {
+              xfce_indicator_button_disconnect_signals (button);
+              gtk_widget_destroy (GTK_WIDGET (button));
+              return;
+            }
         }
     }
 }
diff --git a/panel-plugin/indicator-button.c b/panel-plugin/indicator-button.c
index 49c7a1e..f01db2f 100644
--- a/panel-plugin/indicator-button.c
+++ b/panel-plugin/indicator-button.c
@@ -56,6 +56,7 @@ struct _XfceIndicatorButton
   GtkToggleButton       __parent__;
 
   IndicatorObject      *io;
+  const gchar          *io_name;
   IndicatorObjectEntry *entry;
   GtkMenu              *menu;
   XfcePanelPlugin      *plugin;
@@ -423,6 +424,16 @@ xfce_indicator_button_get_io (XfceIndicatorButton *button)
 
 
 
+const gchar *
+xfce_indicator_button_get_io_name (XfceIndicatorButton *button)
+{
+  g_return_val_if_fail (XFCE_IS_INDICATOR_BUTTON (button), NULL);
+
+  return button->io_name;
+}
+
+
+
 GtkMenu *
 xfce_indicator_button_get_menu (XfceIndicatorButton *button)
 {
@@ -489,6 +500,7 @@ xfce_indicator_configuration_changed (XfceIndicatorButton *button,
 
 GtkWidget *
 xfce_indicator_button_new (IndicatorObject      *io,
+                           const gchar          *io_name,
                            IndicatorObjectEntry *entry,
                            XfcePanelPlugin      *plugin,
                            IndicatorConfig      *config)
@@ -498,6 +510,7 @@ xfce_indicator_button_new (IndicatorObject      *io,
   g_return_val_if_fail (XFCE_IS_PANEL_PLUGIN (plugin), NULL);
 
   button->io = io;
+  button->io_name = io_name;
   button->entry = entry;
   button->plugin = plugin;
   button->config = config;
diff --git a/panel-plugin/indicator-button.h b/panel-plugin/indicator-button.h
index 80912fa..5eb1dc1 100644
--- a/panel-plugin/indicator-button.h
+++ b/panel-plugin/indicator-button.h
@@ -36,32 +36,38 @@ GType xfce_indicator_button_get_type (void);
 #define XFCE_IS_INDICATOR_BUTTON_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), XFCE_TYPE_INDICATOR_BUTTON))
 #define XFCE_INDICATOR_BUTTON_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), XFCE_TYPE_INDICATOR_BUTTON, XfceIndicatorButtonClass))
 
-typedef struct _XfceIndicatorButton XfceIndicatorButton;
-typedef struct _XfceIndicatorButtonClass XfceIndicatorButtonClass;
+typedef struct          _XfceIndicatorButton              XfceIndicatorButton;
+typedef struct          _XfceIndicatorButtonClass         XfceIndicatorButtonClass;
 
 
-void xfce_indicator_button_set_label (XfceIndicatorButton *button, GtkLabel *label);
+void                    xfce_indicator_button_set_label   (XfceIndicatorButton        *button,
+                                                           GtkLabel                   *label);
 
-void xfce_indicator_button_set_image (XfceIndicatorButton *button, GtkImage *image);
+void                    xfce_indicator_button_set_image   (XfceIndicatorButton        *button,
+                                                           GtkImage                   *image);
 
-void xfce_indicator_button_set_menu (XfceIndicatorButton *button, GtkMenu *menu);
+void                    xfce_indicator_button_set_menu    (XfceIndicatorButton        *button,
+                                                           GtkMenu                    *menu);
 
-GtkWidget *xfce_indicator_button_get_label (XfceIndicatorButton *button);
+GtkWidget              *xfce_indicator_button_get_label   (XfceIndicatorButton        *button);
 
-GtkWidget *xfce_indicator_button_get_image (XfceIndicatorButton *button);
+GtkWidget              *xfce_indicator_button_get_image   (XfceIndicatorButton        *button);
 
-IndicatorObjectEntry *xfce_indicator_button_get_entry (XfceIndicatorButton *button);
+IndicatorObjectEntry   *xfce_indicator_button_get_entry   (XfceIndicatorButton        *button);
 
-IndicatorObject *xfce_indicator_button_get_io (XfceIndicatorButton *button);
+IndicatorObject        *xfce_indicator_button_get_io      (XfceIndicatorButton        *button);
 
-GtkMenu *xfce_indicator_button_get_menu (XfceIndicatorButton *button);
+const gchar            *xfce_indicator_button_get_io_name (XfceIndicatorButton        *button);
+
+GtkMenu                *xfce_indicator_button_get_menu    (XfceIndicatorButton        *button);
 
 GtkWidget              *xfce_indicator_button_new         (IndicatorObject            *io,
+                                                           const gchar                *io_name,
                                                            IndicatorObjectEntry       *entry,
                                                            XfcePanelPlugin            *plugin,
                                                            IndicatorConfig            *config);
 
-void xfce_indicator_button_disconnect_signals (XfceIndicatorButton *button);
+void                    xfce_indicator_button_disconnect_signals (XfceIndicatorButton *button);
 
 G_END_DECLS
 
diff --git a/panel-plugin/indicator.c b/panel-plugin/indicator.c
index 42ef448..d5d56f8 100644
--- a/panel-plugin/indicator.c
+++ b/panel-plugin/indicator.c
@@ -249,6 +249,7 @@ indicator_construct (XfcePanelPlugin *plugin)
   if (indicators_loaded == 0) {
     /* A label to allow for click through */
     indicator->item = xfce_indicator_button_new (NULL,
+                                                 "<placeholder>",
                                                  NULL,
                                                  plugin,
                                                  indicator->config);
@@ -266,10 +267,12 @@ entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_d
 {
   XfcePanelPlugin *plugin = XFCE_PANEL_PLUGIN (user_data);
   IndicatorPlugin *indicator = XFCE_INDICATOR_PLUGIN (plugin);
-  GtkWidget *button = xfce_indicator_button_new (io,
-                                                 entry,
-                                                 plugin,
-                                                 indicator->config);
+  const gchar     *io_name = g_object_get_data (G_OBJECT (io), "io-name");
+  GtkWidget       *button = xfce_indicator_button_new (io,
+                                                       io_name,
+                                                       entry,
+                                                       plugin,
+                                                       indicator->config);
 
   /* remove placeholder item when there are real entries to be added */
   if (indicator->item != NULL)
@@ -325,6 +328,7 @@ load_module (const gchar * name, IndicatorPlugin * indicator)
   fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
   io = indicator_object_new_from_file(fullpath);
   g_free(fullpath);
+  g_object_set_data (G_OBJECT (io), "io-name", g_strdup (name));
 
   g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
                    G_CALLBACK(entry_added), indicator);


More information about the Xfce4-commits mailing list