[Xfce4-commits] <xfce4-panel:master> Redo icon positioning (bug #5565, #9650 and more).

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


Updating branch refs/heads/master
         to ad5a85c8e1e89bf8178575ff35a485c43832cc81 (commit)
       from 594216a874de159089743024fbeef9fc83bea7cb (commit)

commit ad5a85c8e1e89bf8178575ff35a485c43832cc81
Author: Nick Schermer <nick at xfce.org>
Date:   Mon Dec 27 20:28:49 2010 +0100

    Redo icon positioning (bug #5565, #9650 and more).
    
    Fix a string break to set the maximum icon size, instead of
    the number of rows (bug #5565). This makes allocation easier
    and better to understand for users.
    
    Then some new allocation code, this should fix a whole pile
    of bugs: #4871, #5200, #6892, #6950, #6984, #7001 and #7017.
    
    Also non-squared icons are now supported (bug #5874).

 plugins/systray/systray-box.c        |  461 ++++++++++++++++++++++------------
 plugins/systray/systray-box.h        |   17 +-
 plugins/systray/systray-dialog.glade |   16 +-
 plugins/systray/systray.c            |   47 ++--
 4 files changed, 348 insertions(+), 193 deletions(-)

diff --git a/plugins/systray/systray-box.c b/plugins/systray/systray-box.c
index 3c12770..b692d45 100644
--- a/plugins/systray/systray-box.c
+++ b/plugins/systray/systray-box.c
@@ -23,6 +23,9 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
 
 #include <exo/exo.h>
 #include <gtk/gtk.h>
@@ -33,8 +36,11 @@
 #include "systray-box.h"
 #include "systray-socket.h"
 
-#define SPACING            (2)
-#define OFFSCREEN          (-9999)
+#define SPACING    (2)
+#define OFFSCREEN  (-9999)
+
+/* some icon implementations request a 1x1 size for invisible icons */
+#define REQUISITION_IS_INVISIBLE(child_req) ((child_req).width <= 1 && (child_req).height <= 1)
 
 
 
@@ -90,15 +96,16 @@ struct _SystrayBox
 
   /* hidden childeren counter */
   gint          n_hidden_childeren;
+  gint          n_visible_children;
 
   /* whether hidden icons are visible */
   guint         show_hidden : 1;
 
-  /* number of rows */
-  gint          rows;
+  /* maximum icon size */
+  gint          size_max;
 
-  /* guess size, this is a value used to reduce the tray flickering */
-  gint          guess_size;
+  /* allocated size by the plugin */
+  gint          size_alloc;
 };
 
 
@@ -145,11 +152,12 @@ systray_box_init (SystrayBox *box)
   GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
 
   box->childeren = NULL;
-  box->rows = 1;
+  box->size_max = SIZE_MAX_DEFAULT;
+  box->size_alloc = SIZE_MAX_DEFAULT;
   box->n_hidden_childeren = 0;
+  box->n_visible_children = 0;
   box->horizontal = TRUE;
   box->show_hidden = FALSE;
-  box->guess_size = 128;
 }
 
 
@@ -215,96 +223,173 @@ systray_box_finalize (GObject *object)
 
 
 static void
+systray_box_size_get_max_child_size (SystrayBox *box,
+                                     gint        alloc_size,
+                                     gint       *rows_ret,
+                                     gint       *row_size_ret,
+                                     gint       *offset_ret)
+{
+  GtkWidget *widget = GTK_WIDGET (box);
+  gint       size;
+  gint       rows;
+  gint       row_size;
+
+  alloc_size -= 2 * GTK_CONTAINER (widget)->border_width;
+
+  /* count the number of rows that fit in the allocated space */
+  for (rows = 1;; rows++)
+    {
+      size = rows * box->size_max + (rows - 1) * SPACING;
+      if (size < alloc_size)
+        continue;
+
+      /* decrease rows if the new size doesn't fit */
+      if (rows > 1 && size > alloc_size)
+        rows--;
+
+      break;
+    }
+
+  row_size = (alloc_size - (rows - 1) * SPACING) / rows;
+  row_size = MIN (box->size_max, row_size);
+
+  if (rows_ret != NULL)
+    *rows_ret = rows;
+
+  if (row_size_ret != NULL)
+    *row_size_ret = row_size;
+
+  if (offset_ret != NULL)
+    {
+      rows = MIN (rows, box->n_visible_children);
+      *offset_ret = (alloc_size - (rows * row_size + (rows - 1) * SPACING)) / 2;
+      if (*offset_ret < 1)
+        *offset_ret = 0;
+    }
+}
+
+
+
+static void
 systray_box_size_request (GtkWidget      *widget,
                           GtkRequisition *requisition)
 {
-  SystrayBox      *box = XFCE_SYSTRAY_BOX (widget);
-  GSList          *li;
-  GtkWidget       *child;
-  gint             n_columns;
-  gint             child_size = -1;
-  GtkRequisition   child_req;
-  gint             n_visible_childeren = 0;
-  gint             swap;
-  gint             guess_size, icon_size;
-  gint             n_hidden_childeren = 0;
-  gboolean         hidden;
-
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (widget));
-  panel_return_if_fail (requisition != NULL);
-
-  /* get the guess size */
-  guess_size = box->guess_size - (SPACING * (box->rows - 1));
-  guess_size /= box->rows;
-
-  /* check if we need to hide or show any childeren */
-  for (li = box->childeren; li != NULL; li = li->next)
+  SystrayBox     *box = XFCE_SYSTRAY_BOX (widget);
+  GtkWidget      *child;
+  gint            border;
+  GtkRequisition  child_req;
+  gint            n_hidden_childeren = 0;
+  gint            rows;
+  gdouble         cols;
+  gint            row_size;
+  gdouble         cells;
+  gint            min_seq_cells = -1;
+  gdouble         ratio;
+  GSList         *li;
+  gboolean        hidden;
+  gint            col_px;
+  gint            row_px;
+
+  box->n_visible_children = 0;
+
+  /* get some info about the n_rows we're going to allocate */
+  systray_box_size_get_max_child_size (box, box->size_alloc, &rows, &row_size, NULL);
+
+  for (li = box->childeren, cells = 0.00; li != NULL; li = li->next)
     {
       child = GTK_WIDGET (li->data);
+      panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (child));
 
-      /* get the icons size request */
       gtk_widget_size_request (child, &child_req);
 
-      /* a 1x1px request is in some tray implementations the same as
-       * an invisible icon, we allocate those offscreen in allocate */
-      if (child_req.width <= 1 && child_req.height <= 1)
+      /* skip invisible requisitions (see macro) or hidden widgets */
+      if (REQUISITION_IS_INVISIBLE (child_req)
+          || !GTK_WIDGET_VISIBLE (child))
         continue;
 
       hidden = systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child));
+      if (hidden)
+        n_hidden_childeren++;
 
+      /* if we show hidden icons */
       if (!hidden || box->show_hidden)
         {
-          /* get the icon size */
-          icon_size = MIN (guess_size, MAX (child_req.width, child_req.height));
+          /* special handling for non-squared icons. this only works if
+           * the icon size ratio is > 1.00, if this is lower then 1.00
+           * the icon implementation should respect the tray orientation */
+          if (G_UNLIKELY (child_req.width != child_req.height))
+            {
+              ratio = (gdouble) child_req.width / (gdouble) child_req.height;
+              if (!box->horizontal)
+                ratio = 1 / ratio;
 
-          /* pick largest icon */
-          if (G_UNLIKELY (child_size == -1))
-            child_size = icon_size;
-          else
-            child_size = MAX (child_size, icon_size);
+              if (ratio > 1.00)
+                {
+                  if (G_UNLIKELY (rows > 1))
+                    {
+                      /* align to whole blocks if we have multiple rows */
+                      ratio = ceil (ratio);
 
-          /* increase number of visible childeren */
-          n_visible_childeren++;
-        }
+                      /* update the min sequential number of blocks */
+                      min_seq_cells = MAX (min_seq_cells, ratio);
+                    }
 
-      if (hidden)
-        n_hidden_childeren++;
+                  cells += ratio;
+
+                  continue;
+                }
+            }
+
+          /* don't do anything with the actual size,
+           * just count the number of cells */
+          cells += 1.00;
+          box->n_visible_children++;
+        }
     }
 
-  /* update the visibility of the arrow button */
-  if (box->n_hidden_childeren != n_hidden_childeren)
+  if (cells > 0.00)
     {
-      box->n_hidden_childeren = n_hidden_childeren;
-      g_object_notify (G_OBJECT (box), "has-hidden");
-    }
+      cols = cells / (gdouble) rows;
+      if (rows > 1)
+        cols = ceil (cols);
+      if (cols * rows < cells)
+        cols += 1.00;
 
-  /* number of columns */
-  n_columns = n_visible_childeren / box->rows;
-  if (n_visible_childeren > (n_columns * box->rows))
-    n_columns++;
+      /* make sure we have enough columns to fix the minimum amount of cells */
+      if (min_seq_cells != -1)
+        cols = MAX (min_seq_cells, cols);
 
-  /* set the width and height needed for the icons */
-  if (n_visible_childeren > 0)
-    {
-      requisition->width = ((child_size + SPACING) * n_columns) - SPACING;
-      requisition->height = ((child_size + SPACING) * box->rows) - SPACING;
+      col_px = row_size * cols + (cols - 1) * SPACING;
+      row_px = row_size * rows + (rows - 1) * SPACING;
+
+      if (box->horizontal)
+        {
+          requisition->width = col_px;
+          requisition->height = row_px;
+        }
+      else
+        {
+          requisition->width = row_px;
+          requisition->height = col_px;
+        }
     }
   else
     {
-      requisition->width = requisition->height = 0;
+      requisition->width = 0;
+      requisition->height = 0;
     }
 
-  /* swap the sizes if the orientation is vertical */
-  if (!box->horizontal)
+  /* emit property if changed */
+  if (box->n_hidden_childeren != n_hidden_childeren)
     {
-      swap = requisition->width;
-      requisition->width = requisition->height;
-      requisition->height = swap;
+      box->n_hidden_childeren = n_hidden_childeren;
+      g_object_notify (G_OBJECT (box), "has-hidden");
     }
 
-  /* add container border */
-  requisition->width += GTK_CONTAINER (widget)->border_width * 2;
-  requisition->height += GTK_CONTAINER (widget)->border_width * 2;
+  /* add border size */
+  border = GTK_CONTAINER (widget)->border_width * 2;
+  requisition->width += border;
+  requisition->height += border;
 }
 
 
@@ -313,101 +398,152 @@ static void
 systray_box_size_allocate (GtkWidget     *widget,
                            GtkAllocation *allocation)
 {
-  SystrayBox      *box = XFCE_SYSTRAY_BOX (widget);
-  GtkWidget       *child;
-  GSList          *li;
-  gint             n;
-  gint             x, y;
-  gint             width, height;
-  gint             offset = 0;
-  gint             child_size;
-  GtkAllocation    child_alloc;
-  GtkRequisition   child_req;
-  gint             swap;
-  gint             n_children;
-
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (widget));
-  panel_return_if_fail (allocation != NULL);
-
-  /* set widget allocation */
+  SystrayBox     *box = XFCE_SYSTRAY_BOX (widget);
+  GtkWidget      *child;
+  GtkAllocation   child_alloc;
+  GtkRequisition  child_req;
+  gint            border;
+  gint            rows;
+  gint            row_size;
+  gdouble         ratio;
+  gint            x, x_start, x_end;
+  gint            y, y_start, y_end;
+  gint            offset;
+  GSList         *li;
+  gint            alloc_size;
+  gint            idx;
+
   widget->allocation = *allocation;
 
-  n_children = g_slist_length (box->childeren);
-  if (n_children == 0)
-    return;
+  border = GTK_CONTAINER (widget)->border_width;
 
-  /* get root coordinates */
-  x = allocation->x + GTK_CONTAINER (widget)->border_width;
-  y = allocation->y + GTK_CONTAINER (widget)->border_width;
+  alloc_size = box->horizontal ? widget->allocation.height : widget->allocation.width;
+  systray_box_size_get_max_child_size (box, alloc_size, &rows, &row_size, &offset);
 
-  /* get real size */
-  width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width;
-  height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width;
+  /* get allocation bounds */
+  x_start = allocation->x + border;
+  x_end = allocation->x + allocation->width - border;
 
-  /* child size */
-  if (box->rows == 1)
-    {
-      child_size = box->horizontal ? width : height;
-      n = n_children - (box->show_hidden ? 0 : box->n_hidden_childeren);
-      child_size -= SPACING * MAX (n - 1, 0);
-      if (n > 1)
-        child_size /= n;
+  y_start = allocation->y + border;
+  y_end = allocation->y + allocation->height - border;
 
-      if (box->horizontal)
-        y += MAX (height - child_size, 0) / 2;
-      else
-        x += MAX (width - child_size, 0) / 2;
-    }
+  /* add offset to center the tray contents */
+  if (box->horizontal)
+    y_start += offset;
   else
-    {
-      child_size = box->horizontal ? height : width;
-      child_size -= SPACING * (box->rows - 1);
-      child_size /= box->rows;
-    }
+    x_start += offset;
+
+  restart_allocation:
 
-  /* don't allocate zero width icon */
-  if (child_size < 1)
-    child_size = 1;
+  x = x_start;
+  y = y_start;
 
-  /* position icons */
-  for (li = box->childeren, n = 0; li != NULL; li = li->next)
+  for (li = box->childeren; li != NULL; li = li->next)
     {
       child = GTK_WIDGET (li->data);
+      panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (child));
+
+      if (!GTK_WIDGET_VISIBLE (child))
+        continue;
 
       gtk_widget_get_child_requisition (child, &child_req);
-      if ((child_req.width == 1 && child_req.height == 1)
-          || (systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child)) && !box->show_hidden))
+
+      if (REQUISITION_IS_INVISIBLE (child_req)
+          || (!box->show_hidden
+              && systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (child))))
         {
-          /* put icons offscreen */
+          /* position hidden icons offscreen if we don't show hidden icons
+           * or the requested size looks like an invisible icons (see macro) */
           child_alloc.x = child_alloc.y = OFFSCREEN;
+
+          /* do nothing special with the requested size */
+          child_alloc.width = child_req.width;
+          child_alloc.height = child_req.height;
         }
       else
         {
-          /* set coordinates */
-          child_alloc.x = (child_size + SPACING) * (n / box->rows) + offset;
-          child_alloc.y = (child_size + SPACING) * (n % box->rows);
+          /* special case handling for non-squared icons */
+          if (G_UNLIKELY (child_req.width != child_req.height))
+            {
+              ratio = (gdouble) child_req.width / (gdouble) child_req.height;
+
+              if (box->horizontal)
+                {
+                  child_alloc.height = row_size;
+                  child_alloc.width = row_size * ratio;
+                  child_alloc.y = child_alloc.x = 0;
+
+                  if (rows > 1)
+                    {
+                      ratio = ceil (ratio);
+                      child_alloc.x = ((ratio * row_size) - child_alloc.width) / 2;
+                    }
+                }
+              else
+                {
+                  ratio = 1 / ratio;
+
+                  child_alloc.width = row_size;
+                  child_alloc.height = row_size * ratio;
+                  child_alloc.x = child_alloc.y = 0;
+
+                  if (rows > 1)
+                    {
+                      ratio = ceil (ratio);
+                      child_alloc.y = ((ratio * row_size) - child_alloc.height) / 2;
+                    }
+                }
+            }
+          else
+            {
+              /* fix icon to row size */
+              child_alloc.width = row_size;
+              child_alloc.height = row_size;
+              child_alloc.x = 0;
+              child_alloc.y = 0;
 
-          /* increase item counter */
-          n++;
+              ratio = 1.00;
+            }
 
-          /* swap coordinates on a vertical panel */
-          if (!box->horizontal)
+          if ((box->horizontal && x + child_alloc.width > x_end)
+              || (!box->horizontal && y + child_alloc.height > y_end))
             {
-              swap = child_alloc.x;
-              child_alloc.x = child_alloc.y;
-              child_alloc.y = swap;
+              if (ratio >= 2
+                  && li->next != NULL)
+                {
+                  /* child doesn't fit, but maybe we still have space for the
+                   * next icon, so move the child 1 step forward in the list
+                   * and restart allocating the box */
+                  idx = g_slist_position (box->childeren, li);
+                  box->childeren = g_slist_delete_link (box->childeren, li);
+                  box->childeren = g_slist_insert (box->childeren, child, idx + 1);
+
+                  goto restart_allocation;
+                }
+
+              /* TODO maybe restart allocating with row_size-- if new row
+               * doesn't fit? */
+              if (box->horizontal)
+                {
+                  x = x_start;
+                  y += row_size + SPACING;
+                }
+              else
+                {
+                  y = y_start;
+                  x += row_size + SPACING;
+                }
             }
 
-          /* add root */
           child_alloc.x += x;
           child_alloc.y += y;
-        }
 
-      /* set child width and height */
-      child_alloc.width = child_size;
-      child_alloc.height = child_size;
+          if (box->horizontal)
+            x += row_size * ratio + SPACING;
+          else
+            y += row_size * ratio + SPACING;
+        }
 
-      /* allocate widget size */
       gtk_widget_size_allocate (child, &child_alloc);
     }
 }
@@ -497,7 +633,7 @@ systray_box_compare_function (gconstpointer a,
   hidden_a = systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (a));
   hidden_b = systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (b));
   if (hidden_a != hidden_b)
-    return hidden_a ? -1 : 1;
+    return hidden_a ? 1 : -1;
 
   /* sort icons by name */
   name_a = systray_socket_get_name (XFCE_SYSTRAY_SOCKET (a));
@@ -526,18 +662,6 @@ systray_box_new (void)
 
 
 void
-systray_box_set_guess_size (SystrayBox *box,
-                            gint        guess_size)
-{
-  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
-
-  /* set the systray guess size */
-  box->guess_size = guess_size;
-}
-
-
-
-void
 systray_box_set_orientation (SystrayBox     *box,
                              GtkOrientation  orientation)
 {
@@ -558,17 +682,17 @@ systray_box_set_orientation (SystrayBox     *box,
 
 
 void
-systray_box_set_rows (SystrayBox *box,
-                      gint        rows)
+systray_box_set_size_max (SystrayBox *box,
+                          gint        size_max)
 {
   panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
 
-  if (G_LIKELY (rows != box->rows))
+  size_max = CLAMP (size_max, SIZE_MAX_MIN, SIZE_MAX_MAX);
+
+  if (G_LIKELY (size_max != box->size_max))
     {
-      /* set new setting */
-      box->rows = MAX (1, rows);
+      box->size_max = size_max;
 
-      /* queue a resize */
       if (box->childeren != NULL)
         gtk_widget_queue_resize (GTK_WIDGET (box));
     }
@@ -577,11 +701,28 @@ systray_box_set_rows (SystrayBox *box,
 
 
 gint
-systray_box_get_rows (SystrayBox *box)
+systray_box_get_size_max (SystrayBox *box)
 {
-  panel_return_val_if_fail (XFCE_IS_SYSTRAY_BOX (box), 1);
+  panel_return_val_if_fail (XFCE_IS_SYSTRAY_BOX (box), SIZE_MAX_DEFAULT);
 
-  return box->rows;
+  return box->size_max;
+}
+
+
+
+void
+systray_box_set_size_alloc (SystrayBox *box,
+                            gint        size_alloc)
+{
+  panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
+
+  if (G_LIKELY (size_alloc != box->size_alloc))
+    {
+      box->size_alloc = size_alloc;
+
+      if (box->childeren != NULL)
+        gtk_widget_queue_resize (GTK_WIDGET (box));
+    }
 }
 
 
@@ -595,7 +736,9 @@ systray_box_set_show_hidden (SystrayBox *box,
   if (box->show_hidden != show_hidden)
     {
       box->show_hidden = show_hidden;
-      gtk_widget_queue_resize (GTK_WIDGET (box));
+
+      if (box->childeren != NULL)
+        gtk_widget_queue_resize (GTK_WIDGET (box));
     }
 }
 
diff --git a/plugins/systray/systray-box.h b/plugins/systray/systray-box.h
index cb5cf3d..67ff3a9 100644
--- a/plugins/systray/systray-box.h
+++ b/plugins/systray/systray-box.h
@@ -22,6 +22,11 @@
 typedef struct _SystrayBoxClass SystrayBoxClass;
 typedef struct _SystrayBox      SystrayBox;
 
+/* keep those in sync with the glade file too! */
+#define SIZE_MAX_MIN     (12)
+#define SIZE_MAX_MAX     (64)
+#define SIZE_MAX_DEFAULT (22)
+
 #define XFCE_TYPE_SYSTRAY_BOX            (systray_box_get_type ())
 #define XFCE_SYSTRAY_BOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SYSTRAY_BOX, SystrayBox))
 #define XFCE_SYSTRAY_BOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SYSTRAY_BOX, SystrayBoxClass))
@@ -35,16 +40,16 @@ void       systray_box_register_type   (XfcePanelTypeModule *module);
 
 GtkWidget *systray_box_new             (void) G_GNUC_MALLOC;
 
-void       systray_box_set_guess_size  (SystrayBox          *box,
-                                        gint                 guess_size);
-
 void       systray_box_set_orientation (SystrayBox          *box,
                                         GtkOrientation       orientation);
 
-void       systray_box_set_rows        (SystrayBox          *box,
-                                        gint                 rows);
+void       systray_box_set_size_max    (SystrayBox          *box,
+                                        gint                 size_max);
+
+gint       systray_box_get_size_max    (SystrayBox          *box);
 
-gint       systray_box_get_rows        (SystrayBox          *box);
+void       systray_box_set_size_alloc  (SystrayBox          *box,
+                                        gint                 size_alloc);
 
 void       systray_box_set_show_hidden (SystrayBox          *box,
                                         gboolean             show_hidden);
diff --git a/plugins/systray/systray-dialog.glade b/plugins/systray/systray-dialog.glade
index be87fe1..a960c6e 100644
--- a/plugins/systray/systray-dialog.glade
+++ b/plugins/systray/systray-dialog.glade
@@ -55,9 +55,9 @@
                               <object class="GtkLabel" id="label2">
                                 <property name="visible">True</property>
                                 <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Number of rows:</property>
+                                <property name="label" translatable="yes">_Maximum icon size (px):</property>
                                 <property name="use_underline">True</property>
-                                <property name="mnemonic_widget">rows</property>
+                                <property name="mnemonic_widget">size-max</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
@@ -65,10 +65,10 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkSpinButton" id="rows">
+                              <object class="GtkSpinButton" id="size-max">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="adjustment">rows-adjustment</property>
+                                <property name="adjustment">size-adjustment</property>
                                 <property name="numeric">True</property>
                               </object>
                               <packing>
@@ -279,10 +279,10 @@
       <action-widget response="0">help-button</action-widget>
     </action-widgets>
   </object>
-  <object class="GtkAdjustment" id="rows-adjustment">
-    <property name="value">1</property>
-    <property name="lower">1</property>
-    <property name="upper">10</property>
+  <object class="GtkAdjustment" id="size-adjustment">
+    <property name="value">32</property>
+    <property name="lower">12</property>
+    <property name="upper">64</property>
     <property name="step_increment">1</property>
     <property name="page_increment">2</property>
   </object>
diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c
index 03e5c80..9d46b12 100644
--- a/plugins/systray/systray.c
+++ b/plugins/systray/systray.c
@@ -34,9 +34,9 @@
 #include "systray-manager.h"
 #include "systray-dialog_ui.h"
 
-#define ICON_SIZE   (22)
-#define BUTTON_SIZE (16)
-
+#define ICON_SIZE     (22)
+#define BUTTON_SIZE   (16)
+#define FRAME_SPACING (1)
 
 
 static void     systray_plugin_get_property                 (GObject               *object,
@@ -118,7 +118,7 @@ struct _SystrayPlugin
 enum
 {
   PROP_0,
-  PROP_ROWS,
+  PROP_SIZE_MAX,
   PROP_SHOW_FRAME,
   PROP_NAMES_HIDDEN,
   PROP_NAMES_VISIBLE
@@ -174,10 +174,12 @@ systray_plugin_class_init (SystrayPluginClass *klass)
   plugin_class->orientation_changed = systray_plugin_orientation_changed;
 
   g_object_class_install_property (gobject_class,
-                                   PROP_ROWS,
-                                   g_param_spec_uint ("rows",
+                                   PROP_SIZE_MAX,
+                                   g_param_spec_uint ("size-max",
                                                       NULL, NULL,
-                                                      1, 10, 1,
+                                                      SIZE_MAX_MIN,
+                                                      SIZE_MAX_MAX,
+                                                      SIZE_MAX_DEFAULT,
                                                       EXO_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
@@ -225,6 +227,7 @@ systray_plugin_init (SystrayPlugin *plugin)
   gtk_box_pack_start (GTK_BOX (plugin->hvbox), plugin->box, TRUE, TRUE, 0);
   g_signal_connect (G_OBJECT (plugin->box), "expose-event",
       G_CALLBACK (systray_plugin_box_expose_event), NULL);
+  gtk_container_set_border_width (GTK_CONTAINER (plugin->box), FRAME_SPACING);
   gtk_widget_show (plugin->box);
 
   plugin->button = xfce_arrow_button_new (GTK_ARROW_RIGHT);
@@ -245,14 +248,13 @@ systray_plugin_get_property (GObject    *object,
                              GParamSpec *pspec)
 {
   SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object);
-  guint          rows;
   GPtrArray     *array;
 
   switch (prop_id)
     {
-    case PROP_ROWS:
-      rows = systray_box_get_rows (XFCE_SYSTRAY_BOX (plugin->box));
-      g_value_set_uint (value, rows);
+    case PROP_SIZE_MAX:
+      g_value_set_uint (value,
+          systray_box_get_size_max (XFCE_SYSTRAY_BOX (plugin->box)));
       break;
 
     case PROP_SHOW_FRAME:
@@ -297,9 +299,9 @@ systray_plugin_set_property (GObject      *object,
 
   switch (prop_id)
     {
-    case PROP_ROWS:
-      systray_box_set_rows (XFCE_SYSTRAY_BOX (plugin->box),
-                            g_value_get_uint (value));
+    case PROP_SIZE_MAX:
+      systray_box_set_size_max (XFCE_SYSTRAY_BOX (plugin->box),
+                                g_value_get_uint (value));
       break;
 
     case PROP_SHOW_FRAME:
@@ -309,6 +311,9 @@ systray_plugin_set_property (GObject      *object,
           plugin->show_frame = show_frame;
           gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame),
               show_frame ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_NONE);
+
+          gtk_container_set_border_width (GTK_CONTAINER (plugin->box),
+              plugin->show_frame ? FRAME_SPACING : 0);
         }
       break;
 
@@ -418,7 +423,7 @@ systray_plugin_construct (XfcePanelPlugin *panel_plugin)
   SystrayPlugin       *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin);
   const PanelProperty  properties[] =
   {
-    { "rows", G_TYPE_UINT },
+    { "size-max", G_TYPE_UINT },
     { "show-frame", G_TYPE_BOOLEAN },
     { "names-visible", PANEL_PROPERTIES_TYPE_VALUE_ARRAY },
     { "names-hidden", PANEL_PROPERTIES_TYPE_VALUE_ARRAY },
@@ -498,10 +503,12 @@ systray_plugin_size_changed (XfcePanelPlugin *panel_plugin,
     border = 1;
   gtk_container_set_border_width (GTK_CONTAINER (frame), border);
 
-  /* set the guess size this is used to get the initial icon size request
-   * correct to avoid flickering in the system tray for new applications */
+  /* because the allocated size, used in size_requested is always 1 step
+   * behind the allocated size when resizing and during startup, we
+   * correct the maximum size set by the user with the size the panel
+   * will most likely allocated */
   border += MAX (frame->style->xthickness, frame->style->ythickness);
-  systray_box_set_guess_size (XFCE_SYSTRAY_BOX (plugin->box), size - 2 * border);
+  systray_box_set_size_alloc (XFCE_SYSTRAY_BOX (plugin->box), size - 2 * border);
 
   return TRUE;
 }
@@ -522,9 +529,9 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
   if (G_UNLIKELY (builder == NULL))
     return;
 
-  object = gtk_builder_get_object (builder, "rows");
+  object = gtk_builder_get_object (builder, "size-max");
   panel_return_if_fail (GTK_IS_WIDGET (object));
-  exo_mutual_binding_new (G_OBJECT (plugin), "rows",
+  exo_mutual_binding_new (G_OBJECT (plugin), "size-max",
                           G_OBJECT (object), "value");
 
   object = gtk_builder_get_object (builder, "show-frame");



More information about the Xfce4-commits mailing list