commit 436489073a29f31938ab2ed6d4dc5666ffeb5cd5
Author: Andrzej <ndrwrdck@gmail.com>
Date:   Sat Nov 26 03:12:55 2011 +0900

    pager, bug #664779: enhancing pager layout policy.
    
    Application may now force "width for height" or "height for width" regardless of the pager orientation.

diff --git a/libwnck/pager.c b/libwnck/pager.c
index 9474d1a..694ce5d 100644
--- a/libwnck/pager.c
+++ b/libwnck/pager.c
@@ -69,6 +69,7 @@ struct _WnckPagerPrivate
   
   int n_rows; /* really columns for vertical orientation */
   WnckPagerDisplayMode display_mode;
+  WnckPagerLayoutPolicy layout_policy;
   gboolean show_all_workspaces;
   GtkShadowType shadow_type;
   
@@ -210,6 +211,7 @@ wnck_pager_init (WnckPager *pager)
   pager->priv->shadow_type = GTK_SHADOW_NONE;
 
   pager->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+  pager->priv->layout_policy = WNCK_PAGER_LAYOUT_POLICY_AUTOMATIC;
   pager->priv->workspace_size = 48;
 
   for (i = 0; i < N_SCREEN_CONNECTIONS; i++)
@@ -428,7 +430,9 @@ wnck_pager_size_request  (GtkWidget      *widget,
   spaces_per_row = (n_spaces + pager->priv->n_rows - 1) / pager->priv->n_rows;
   space = wnck_screen_get_workspace (pager->priv->screen, 0);
   
-  if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
+  if (pager->priv->layout_policy == WNCK_PAGER_LAYOUT_POLICY_HEIGHT_FOR_WIDTH ||
+      (pager->priv->layout_policy == WNCK_PAGER_LAYOUT_POLICY_AUTOMATIC &&
+       pager->priv->orientation == GTK_ORIENTATION_VERTICAL))
     {
       if (space) {
         screen_aspect =
@@ -455,9 +459,16 @@ wnck_pager_size_request  (GtkWidget      *widget,
 	}
       
       other_dimension_size = screen_aspect * size;
-      
-      requisition->width = size * n_rows + (n_rows - 1);
-      requisition->height = other_dimension_size * spaces_per_row  + (spaces_per_row - 1);
+      if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
+	{
+	  requisition->width = size * n_rows + (n_rows - 1);
+	  requisition->height = other_dimension_size * spaces_per_row  + (spaces_per_row - 1);
+	}
+      else
+	{
+	  requisition->width = size * spaces_per_row + (spaces_per_row - 1);
+	  requisition->height = other_dimension_size * n_rows  + (n_rows - 1);
+	}
     }
   else
     {
@@ -512,8 +523,16 @@ wnck_pager_size_request  (GtkWidget      *widget,
 	  other_dimension_size += 2;
 	}
       
-      requisition->width = other_dimension_size * spaces_per_row + (spaces_per_row - 1);
-      requisition->height = size * n_rows + (n_rows - 1);
+      if (pager->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+	{
+	  requisition->width = other_dimension_size * spaces_per_row + (spaces_per_row - 1);
+	  requisition->height = size * n_rows + (n_rows - 1);
+	}
+      else
+	{
+	  requisition->width = other_dimension_size * n_rows + (n_rows - 1);
+	  requisition->height = size * spaces_per_row + (spaces_per_row - 1);
+	}
     }
 
   if (pager->priv->shadow_type != GTK_SHADOW_NONE)
@@ -543,6 +562,8 @@ wnck_pager_size_allocate (GtkWidget      *widget,
   int focus_width;
   int width;
   int height;
+  int n_spaces;
+  int spaces_per_row;
 
   pager = WNCK_PAGER (widget);
 
@@ -565,17 +586,34 @@ wnck_pager_size_allocate (GtkWidget      *widget,
 
   g_assert (pager->priv->n_rows > 0);
 
-  if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
+  n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
+  spaces_per_row = (n_spaces + pager->priv->n_rows - 1) / pager->priv->n_rows;
+  if (spaces_per_row == 0)
+    spaces_per_row = 1;
+
+  if (pager->priv->layout_policy == WNCK_PAGER_LAYOUT_POLICY_HEIGHT_FOR_WIDTH ||
+      (pager->priv->layout_policy == WNCK_PAGER_LAYOUT_POLICY_AUTOMATIC &&
+       pager->priv->orientation == GTK_ORIENTATION_VERTICAL))
     {
       if (pager->priv->show_all_workspaces)
-	workspace_size = (width - (pager->priv->n_rows - 1))  / pager->priv->n_rows;
+	{
+	  if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
+	    workspace_size = (width - (pager->priv->n_rows - 1))  / pager->priv->n_rows;
+	  else
+	    workspace_size = (width - (spaces_per_row - 1)) / spaces_per_row;
+	}
       else
 	workspace_size = width;
     }
   else
     {
       if (pager->priv->show_all_workspaces)
-	workspace_size = (height - (pager->priv->n_rows - 1))/ pager->priv->n_rows;
+	{
+	  if (pager->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    workspace_size = (height - (pager->priv->n_rows - 1))/ pager->priv->n_rows;
+	  else
+	    workspace_size = (height - (spaces_per_row - 1)) / spaces_per_row;
+	}
       else
 	workspace_size = height;
     }
@@ -2169,6 +2207,26 @@ wnck_pager_set_display_mode (WnckPager            *pager,
 }
 
 /**
+ * wnck_pager_set_layout_policy:
+ * @pager: a #WnckPager.
+ * @policy: a layout policy.
+ *
+ * Sets the layout policy for @pager to @policy.
+ */
+void
+wnck_pager_set_layout_policy (WnckPager            *pager,
+			      WnckPagerLayoutPolicy policy)
+{
+  g_return_if_fail (WNCK_IS_PAGER (pager));
+
+  if (pager->priv->layout_policy == policy)
+    return;
+
+  pager->priv->layout_policy = policy;
+  gtk_widget_queue_resize (GTK_WIDGET (pager));
+}
+
+/**
  * wnck_pager_set_show_all:
  * @pager: a #WnckPager.
  * @show_all_workspaces: whether to display all #WnckWorkspace in @pager.
diff --git a/libwnck/pager.h b/libwnck/pager.h
index 9104755..6691ae0 100644
--- a/libwnck/pager.h
+++ b/libwnck/pager.h
@@ -61,7 +61,7 @@ struct _WnckPagerClass
   void (* pad1) (void);
   void (* pad2) (void);
   void (* pad3) (void);
-  void (* pad4) (void);
+  void (* pad4) (void); /* should we remove one? */
 };
 
 /**
@@ -78,6 +78,26 @@ typedef enum {
   WNCK_PAGER_DISPLAY_CONTENT
 } WnckPagerDisplayMode;
 
+/**
+ * WnckPagerLayoutPolicy:
+ * @WNCK_PAGER_LAYOUT_POLICY_AUTOMATIC: the #WnckPager is resize policy is
+ * "height for width" for in vertical orientation, or "width for height"
+ * in horizontal one. This is a default behavior of libwnck <= 2.30.7
+ * @WNCK_PAGER_LAYOUT_POLICY_WIDTH_FOR_HEIGHT: the #WnckPager is forced to resize its
+ * width in proportion to a preset height. This can be used for instantiating a vertical
+ * #WnckPager inside a horizontal panel.
+ * @WNCK_PAGER_LAYOUT_POLICY_HEIGHT_FOR_WIDTH: the #WnckPager is forced to resize its
+ * height in proportion to a preset width. This can be used for instantiating a horizontal
+ * #WnckPager inside a vertical panel.
+ *
+ * Policy defining how a #WnckPager will resize itself.
+ */
+typedef enum {
+  WNCK_PAGER_LAYOUT_POLICY_AUTOMATIC,
+  WNCK_PAGER_LAYOUT_POLICY_WIDTH_FOR_HEIGHT,
+  WNCK_PAGER_LAYOUT_POLICY_HEIGHT_FOR_WIDTH
+} WnckPagerLayoutPolicy;
+
 GType wnck_pager_get_type (void) G_GNUC_CONST;
 
 GtkWidget* wnck_pager_new (WnckScreen *screen);
@@ -92,6 +112,8 @@ void wnck_pager_set_show_all     (WnckPager            *pager,
 				  gboolean              show_all_workspaces);
 void wnck_pager_set_shadow_type  (WnckPager	       *pager,
 				  GtkShadowType		shadow_type);
+void wnck_pager_set_layout_policy (WnckPager            *pager,
+                                   WnckPagerLayoutPolicy policy);
 
 
 #ifndef WNCK_DISABLE_DEPRECATED
