Index: libwnck/tasklist.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/tasklist.c,v
retrieving revision 1.85
diff -u -p -r1.85 tasklist.c
--- libwnck/tasklist.c	24 Jul 2005 01:09:36 -0000	1.85
+++ libwnck/tasklist.c	18 Aug 2005 19:03:42 -0000
@@ -157,6 +157,7 @@ struct _WnckTasklistPrivate
 
   gint max_button_width;
   gint max_button_height;
+  gint n_rows, n_cols;
 
   gboolean switch_workspace_on_unminimize;
   
@@ -1255,6 +1257,7 @@ wnck_tasklist_size_allocate (GtkWidget  
   GList *ungrouped_class_groups;
   WnckTask *win_task;
   GList *visible_tasks = NULL;
+  GList *windows_sorted = NULL;
   int grouping_limit;
   
   tasklist = WNCK_TASKLIST (widget);
@@ -1327,7 +1330,8 @@ wnck_tasklist_size_allocate (GtkWidget  
 					   n_startup_sequences + n_windows - n_grouped_buttons,
 					   &n_cols, &n_rows);
     }
-
+  tasklist->priv->n_rows = n_rows;
+  tasklist->priv->n_cols = n_cols;
   /* Add all ungrouped windows to visible_tasks, and hide their class groups */
   l = ungrouped_class_groups;
   while (l != NULL)
@@ -1373,6 +1377,13 @@ wnck_tasklist_size_allocate (GtkWidget  
       gtk_widget_size_allocate (task->button, &child_allocation);
       gtk_widget_set_child_visible (GTK_WIDGET (task->button), TRUE);
 
+      /* Build sorted windows list */
+      if (g_list_length (task->windows) > 1)
+        windows_sorted = g_list_concat (windows_sorted,
+                                       g_list_copy (task->windows));
+      else
+        windows_sorted = g_list_append (windows_sorted, task);
+
       i++;
       l = l->next;
     }
@@ -1381,6 +1392,8 @@ wnck_tasklist_size_allocate (GtkWidget  
   wnck_tasklist_update_icon_geometries (tasklist, visible_tasks);
   
   g_list_free (visible_tasks);
+  g_list_free (tasklist->priv->windows);
+  tasklist->priv->windows = windows_sorted;
   
   GTK_WIDGET_CLASS (tasklist_parent_class)->size_allocate (widget, allocation);
 }
@@ -1614,6 +1627,59 @@ wnck_tasklist_set_screen (WnckTasklist *
   wnck_tasklist_connect_screen (tasklist, screen);
 }
 
+static gboolean
+wnck_tasklist_scroll_cb (WnckTasklist *tasklist,
+                         GdkEventScroll *event,
+                         gpointer user_data)
+{
+  GList *window;
+  gint i;
+
+  window = g_list_find (tasklist->priv->windows,
+                        tasklist->priv->active_task);
+
+  switch (event->direction)
+    {
+      case GDK_SCROLL_RIGHT:
+        if (!window)
+          window = tasklist->priv->windows;
+        else
+          for (i = 0; i < tasklist->priv->n_rows && window; i++)
+            window = window->next;
+      break;
+
+      case GDK_SCROLL_DOWN:
+        if (!window)
+          window = tasklist->priv->windows;
+        else
+          window = window->next;
+      break;
+      
+      case GDK_SCROLL_LEFT:
+        if (!window)
+          window = g_list_last (tasklist->priv->windows);
+        else
+          for (i = 0; i < tasklist->priv->n_rows && window; i++)
+            window = window->prev;
+      break;
+
+      case GDK_SCROLL_UP:
+        if (!window)
+          window = g_list_last (tasklist->priv->windows);
+        else
+          window = window->prev;
+      break;
+
+      default:
+        g_assert_not_reached ();
+    }
+
+  if (window)
+    wnck_tasklist_activate_task_window (window->data, event->time);
+
+  return TRUE;
+}
+
 GtkWidget*
 wnck_tasklist_new (WnckScreen *screen)
 {
@@ -1627,6 +1693,13 @@ wnck_tasklist_new (WnckScreen *screen)
 
   wnck_tasklist_set_screen (tasklist, screen);
 
+  /* callback when there is a scroll-event for switching to the next window  */
+  g_signal_connect_object (G_OBJECT (tasklist),
+                           "scroll-event",
+                           G_CALLBACK (wnck_tasklist_scroll_cb),
+                           G_OBJECT (tasklist),
+                           0);
+  
   return GTK_WIDGET (tasklist);
 }
 
