--- gnome-panel-2.28.0-orig/applets/wncklet/window-list.c	2009-08-11 14:59:46.000000000 +0000
+++ gnome-panel-2.28.0/applets/wncklet/window-list.c	2009-12-30 14:46:13.000000000 +0000
@@ -130,7 +130,7 @@
 		return;
   
 	tasklist->orientation = new_orient;
-
+        wnck_tasklist_set_orientation (tasklist->tasklist, new_orient);
 	tasklist_update (tasklist);
 }
 
@@ -518,7 +518,8 @@
 	}
 
 	tasklist->tasklist = wnck_tasklist_new (NULL);
-
+        wnck_tasklist_set_orientation (tasklist->tasklist, tasklist->orientation);
+        
         wnck_tasklist_set_icon_loader (WNCK_TASKLIST (tasklist->tasklist),
                                        icon_loader_func,
                                        tasklist,
--- libwnck-2.28.0-orig/libwnck/tasklist.h	2009-04-19 17:40:32.000000000 +0000
+++ libwnck-2.28.0/libwnck/tasklist.h	2009-12-30 17:10:20.000000000 +0000
@@ -99,6 +99,8 @@
 					       gboolean      include_all_workspaces);
 void wnck_tasklist_set_button_relief (WnckTasklist *tasklist,
                                       GtkReliefStyle relief);
+void wnck_tasklist_set_orientation(WnckTasklist *tasklist, GtkOrientation orient);
+
 #ifndef WNCK_DISABLE_DEPRECATED
 void wnck_tasklist_set_minimum_width (WnckTasklist *tasklist, gint size);
 gint wnck_tasklist_get_minimum_width (WnckTasklist *tasklist);
--- libwnck-2.28.0/libwnck/tasklist.c	2009-09-08 03:28:12.000000000 +0200
+++ libwnck-2.28.0-work/libwnck/tasklist.c	2010-01-01 11:00:09.000000000 +0100
@@ -234,6 +234,8 @@
   GdkPixmap *background;
 
   guint drag_start_time;
+
+  GtkOrientation orientation;  
 };
 
 static GType wnck_task_get_type (void);
@@ -312,10 +314,18 @@
                                              gpointer        user_data);
 static void     wnck_tasklist_free_tasks    (WnckTasklist   *tasklist);
 static void     wnck_tasklist_update_lists  (WnckTasklist   *tasklist);
+static int      wnck_tasklist_req_layout    (GtkAllocation  *allocation,
+					     int             max_width,
+					     int             max_height,
+					     int             n_buttons,
+                                             GtkOrientation  orientation,
+					     int            *n_cols_out,
+					     int            *n_rows_out);
 static int      wnck_tasklist_layout        (GtkAllocation  *allocation,
 					     int             max_width,
 					     int             max_height,
 					     int             n_buttons,
+                                             GtkOrientation  orientation,
 					     int            *n_cols_out,
 					     int            *n_rows_out);
 
@@ -724,7 +734,8 @@
   tasklist->priv->background = NULL;
 
   tasklist->priv->drag_start_time = 0;
-
+  tasklist->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+  
   atk_obj = gtk_widget_get_accessible (widget);
   atk_object_set_name (atk_obj, _("Window List"));
   atk_object_set_description (atk_obj, _("Tool to switch between visible windows"));
@@ -972,6 +983,20 @@
 }
 
 /**
+ * wnck_tasklist_set_orientation:
+ * @tasklist: a #WnckTasklist.
+ * @orient: a GtkOrientation.
+ *
+ * Set the orientation of the @taskluist.  The main use of this function is
+ * proper integration of #WnckTasklist in vertical panels.
+ */
+ 
+void wnck_tasklist_set_orientation(WnckTasklist *tasklist, GtkOrientation orient)
+{
+    tasklist->priv->orientation = orient;
+}
+
+/**
  * wnck_tasklist_set_switch_workspace_on_unminimize:
  * @tasklist: a #WnckTasklist.
  * @switch_workspace_on_unminimize: whether to activate the #WnckWorkspace a
@@ -1143,29 +1168,117 @@
 		      int            max_width,
 		      int            max_height,
 		      int            n_buttons,
+                      GtkOrientation orientation,
 		      int           *n_cols_out,
 		      int           *n_rows_out)
 {
-  int n_cols, n_rows;
+  int n_cols, n_rows, next_rows, next_cols, width, height;
 
-  /* How many rows fit in the allocation */
-  n_rows = allocation->height / max_height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL) { 
+      /* How many rows fit in the allocation */
+      n_rows = allocation->height / max_height;
+      
+      /* Don't have more rows than buttons */
+      n_rows = MIN (n_rows, n_buttons);
+      
+      /* At least one row */
+      n_rows = MAX (n_rows, 1);
+      
+      /* We want to use as many rows as possible to limit the width */
+      n_cols = (n_buttons + n_rows - 1) / n_rows;
+      
+      /* At least one column */
+      n_cols = MAX (n_cols, 1);
 
-  /* Don't have more rows than buttons */
-  n_rows = MIN (n_rows, n_buttons);
+      /* Try to stay square with a little preference to the width if we are
+         space constrained */
+      while (allocation->width / n_cols < max_width
+             && allocation->width / n_cols < allocation->height / n_rows)
+        {
+          next_rows = n_rows + 1;
+          if (next_rows > n_buttons)
+            break;
+          next_cols = (n_buttons + next_rows - 1) / next_rows;
+          if (next_cols < 1)
+            break;
+          n_rows = next_rows;
+          n_cols = next_cols;
+        }
+  } else {
+      n_cols = allocation->width / max_width;
+      n_cols = MIN(n_cols, n_buttons);
+      n_cols = MAX(n_cols, 1);
+
+      n_rows = (n_buttons + n_cols - 1) / n_cols;
+      n_rows = MAX(n_rows, 1);
+
+      /* If we are space constrained, try to stay square with a little
+         preference to the width.  Note the dissymetry with the above code,
+         due to the fact that here the loop decrease the width while the
+         above one increased it.
+      */
+      while (allocation->height / n_rows < max_height) {
+        next_cols = n_cols + 1;
+        if (next_cols > n_buttons)
+          break;
+        width = allocation->width / next_cols;
+        next_rows = (n_buttons + next_cols - 1) / next_cols;
+        if (next_rows < 1)
+          break;
+        height = allocation->height / next_rows;
+        if (width < MINI_ICON_SIZE + 2 * TASKLIST_BUTTON_PADDING
+            && height > width)
+          break;
+        n_rows = next_rows;
+        n_cols = next_cols;
+      }
+  }
+  *n_cols_out = n_cols;
+  *n_rows_out = n_rows;
+  return allocation->width / n_cols;
+}
 
-  /* At least one row */
-  n_rows = MAX (n_rows, 1);
-  
-  /* We want to use as many rows as possible to limit the width */
-  n_cols = (n_buttons + n_rows - 1) / n_rows;
+/* returns the maximal possible button width (i.e. if you don't want to
+ * stretch the buttons to fill the alloctions the width can be smaller).
+ * Here we don't try to have a better split as it is used to determine a
+ * requirement.*/
+static int
+wnck_tasklist_req_layout (GtkAllocation *allocation,
+                          int            max_width,
+                          int            max_height,
+                          int            n_buttons,
+                          GtkOrientation orientation,
+                          int           *n_cols_out,
+                          int           *n_rows_out)
+{
+  int n_cols, n_rows;
 
-  /* At least one column */
-  n_cols = MAX (n_cols, 1);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL) { 
+      /* How many rows fit in the allocation */
+      n_rows = allocation->height / max_height;
+      
+      /* Don't have more rows than buttons */
+      n_rows = MIN (n_rows, n_buttons);
+      
+      /* At least one row */
+      n_rows = MAX (n_rows, 1);
+      
+      /* We want to use as many rows as possible to limit the width */
+      n_cols = (n_buttons + n_rows - 1) / n_rows;
+      
+      /* At least one column */
+      n_cols = MAX (n_cols, 1);
+      
+  } else {
+      n_cols = allocation->width / max_width;
+      n_cols = MIN(n_cols, n_buttons);
+      n_cols = MAX(n_cols, 1);
 
+      n_rows = (n_buttons + n_cols - 1) / n_cols;
+      n_rows = MAX(n_rows, 1);
+  }
   *n_cols_out = n_cols;
   *n_rows_out = n_rows;
-  
   return allocation->width / n_cols;
 }
 
@@ -1281,6 +1394,7 @@
   return width;
 }
 
+int counter = 0;
 static void
 wnck_tasklist_size_request  (GtkWidget      *widget,
                              GtkRequisition *requisition)
@@ -1297,7 +1411,8 @@
   int n_windows;
   int n_startup_sequences;
   int n_rows;
-  int n_cols, last_n_cols;
+  int n_cols;
+  int last_n_minor;
   int n_grouped_buttons;
   gboolean score_set;
   int val;
@@ -1350,27 +1465,49 @@
   ungrouped_class_groups = g_list_copy (tasklist->priv->class_groups);
   score_set = FALSE;
 
-  grouping_limit = MIN (tasklist->priv->grouping_limit,
-			tasklist->priv->max_button_width);
+  if (tasklist->priv->orientation == GTK_ORIENTATION_HORIZONTAL) {
+    grouping_limit = MIN (tasklist->priv->grouping_limit,
+                          tasklist->priv->max_button_width);
+  } else {
+    /* The value of grouping limit doesn't make sense for vertical layout,
+     * here we compute one, we could set another parameter to the task list
+     */
+    grouping_limit = tasklist->priv->max_button_width*3/4;
+  }
   
   /* Try ungrouped mode */
-  wnck_tasklist_layout (&fake_allocation,
+  wnck_tasklist_req_layout (&fake_allocation,
 			tasklist->priv->max_button_width,
 			tasklist->priv->max_button_height,
 			n_windows + n_startup_sequences,
+                        tasklist->priv->orientation,
 			&n_cols, &n_rows);
 
-  last_n_cols = G_MAXINT;
+  /* gives now more hints */
+  last_n_minor = G_MAXINT;
   lowest_range = G_MAXINT;
   if (tasklist->priv->grouping != WNCK_TASKLIST_ALWAYS_GROUP)
     {
-      val = n_cols * tasklist->priv->max_button_width;
-      g_array_insert_val (array, array->len, val);
-      val = n_cols * grouping_limit;
-      g_array_insert_val (array, array->len, val);
-
-      last_n_cols = n_cols;
-      lowest_range = val;
+      if (tasklist->priv->orientation == GTK_ORIENTATION_HORIZONTAL) {
+        val = n_cols * tasklist->priv->max_button_width;
+        g_array_insert_val (array, array->len, val);
+        val = n_cols * grouping_limit;
+        g_array_insert_val (array, array->len, val);
+        
+        last_n_minor = n_cols;
+        lowest_range = val;
+      } else {
+        val = n_rows * tasklist->priv->max_button_height;
+        g_array_insert_val (array, array->len, val);
+        val = n_rows * grouping_limit;
+        g_array_insert_val (array, array->len, val);
+        
+        last_n_minor = n_rows;
+        lowest_range = val;            
+      }
+      /* that's what we would like */
+      requisition->width  = n_cols * tasklist->priv->max_button_width;
+      requisition->height = n_rows * tasklist->priv->max_button_height;
     }
 
   while (ungrouped_class_groups != NULL &&
@@ -1386,33 +1523,73 @@
 
       n_grouped_buttons += g_list_length (class_group_task->windows) - 1;
 
-      wnck_tasklist_layout (&fake_allocation,
+      wnck_tasklist_req_layout (&fake_allocation,
 			    tasklist->priv->max_button_width,
 			    tasklist->priv->max_button_height,
 			    n_startup_sequences + n_windows - n_grouped_buttons,
+                            tasklist->priv->orientation,
 			    &n_cols, &n_rows);
-      if (n_cols != last_n_cols &&
-	  (tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
-	   ungrouped_class_groups == NULL))
-	{
-	  val = n_cols * tasklist->priv->max_button_width;
-	  if (val >= lowest_range)
-	    { /* Overlaps old range */
-              g_assert (array->len > 0);
-	      lowest_range = n_cols * grouping_limit;
-              g_array_index(array, int, array->len-1) = lowest_range;
-	    }
-	  else
-	    {
-	      /* Full new range */
-	      g_array_insert_val (array, array->len, val);
-	      val = n_cols * grouping_limit;
-	      g_array_insert_val (array, array->len, val);
-	      lowest_range = val;
-	    }
-
-	  last_n_cols = n_cols;
-	}
+      if (tasklist->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          if (n_cols != last_n_minor &&
+              (tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
+               ungrouped_class_groups == NULL))
+            {
+              if (lowest_range == G_MAXINT)
+                {
+                  requisition->width  = n_cols * tasklist->priv->max_button_width;
+                  requisition->height = n_rows * tasklist->priv->max_button_height;
+                }
+              val = n_cols * tasklist->priv->max_button_width;
+              if (val >= lowest_range)
+                { /* Overlaps old range */
+                  g_assert (array->len > 0);
+                  lowest_range = n_cols * grouping_limit;
+                  g_array_index(array, int, array->len-1) = lowest_range;
+                }
+              else
+                {
+                  /* Full new range */
+                  g_array_insert_val (array, array->len, val);
+                  val = n_cols * grouping_limit;
+                  g_array_insert_val (array, array->len, val);
+                  lowest_range = val;
+                }
+              
+              last_n_minor = n_cols;
+            }
+        }
+      else
+        {
+          if (n_rows != last_n_minor &&
+              (tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
+               ungrouped_class_groups == NULL))
+            {
+              if (lowest_range == G_MAXINT)
+                {
+                  requisition->width  = n_cols * tasklist->priv->max_button_width;
+                  requisition->height = n_rows * tasklist->priv->max_button_height;
+                }
+              val = n_rows * tasklist->priv->max_button_height;;
+              if (val >= lowest_range)
+                { /* Overlaps old range */
+                  g_assert (array->len > 0);
+                  lowest_range = n_rows * grouping_limit;
+                  g_array_index(array, int, array->len-1) = lowest_range;
+                }
+              else
+                {
+                  /* Full new range */
+                  g_array_insert_val (array, array->len, val);
+                  val = n_rows * grouping_limit;
+                  g_array_insert_val (array, array->len, val);
+                  lowest_range = val;
+                }
+              
+              last_n_minor = n_rows;
+            }
+        }
+      
     }
 
   g_list_free (ungrouped_class_groups);
@@ -1433,9 +1610,6 @@
   tasklist->priv->size_hints_len = array->len;
     
   tasklist->priv->size_hints = (int *)g_array_free (array, FALSE);
-
-  requisition->width = tasklist->priv->size_hints[0];
-  requisition->height = fake_allocation.height;
 }
 
 /**
@@ -1528,6 +1702,7 @@
 				       tasklist->priv->max_button_width,
 				       tasklist->priv->max_button_height,
 				       n_startup_sequences + n_windows,
+                                       tasklist->priv->orientation,
 				       &n_cols, &n_rows);
   while (ungrouped_class_groups != NULL &&
 	 ((tasklist->priv->grouping == WNCK_TASKLIST_ALWAYS_GROUP) ||
@@ -1577,6 +1752,7 @@
 					   tasklist->priv->max_button_width,
 					   tasklist->priv->max_button_height,
 					   n_startup_sequences + n_windows - n_grouped_buttons,
+                                           tasklist->priv->orientation,
 					   &n_cols, &n_rows);
     }
 
@@ -4196,7 +4372,6 @@
   WnckTask *task;
 
   task = g_object_new (WNCK_TYPE_TASK, NULL);
-
   task->type = WNCK_TASK_WINDOW;
   task->window = g_object_ref (window);
   task->class_group = g_object_ref (wnck_window_get_class_group (window));
