Index: gnome-panel-2.24.0/applets/wncklet/workspace-switcher.c
===================================================================
--- gnome-panel-2.24.0.orig/applets/wncklet/workspace-switcher.c	2008-10-19 22:02:52.000000000 -0700
+++ gnome-panel-2.24.0/applets/wncklet/workspace-switcher.c	2008-10-19 22:02:57.000000000 -0700
@@ -253,26 +253,21 @@
 	}
 }
 
-static gboolean
-applet_scroll (PanelApplet    *applet,
-               GdkEventScroll *event,
-               PagerData      *pager)
+static int
+applet_scroll_get_next_index (PanelApplet    *applet,
+                              GdkEventScroll *event,
+                              PagerData      *pager,
+                              int             index,
+                              int             n_rows,
+                              int             n_columns,
+                              int             n_workspaces)
 {
 	GdkScrollDirection absolute_direction;
-	int                index;
-	int                n_workspaces;
-	int                n_columns;
 	int                in_last_row;
 	
-	if (event->type != GDK_SCROLL)
-		return FALSE;
-
-	index          = wnck_workspace_get_number (wnck_screen_get_active_workspace (pager->screen));
-	n_workspaces   = wnck_screen_get_workspace_count (pager->screen);
-	n_columns      = n_workspaces / pager->n_rows;
-	if (n_workspaces % pager->n_rows != 0)
+	if (n_workspaces % n_rows != 0)
 		n_columns++;
-	in_last_row    = n_workspaces % n_columns;
+	in_last_row = n_workspaces % n_columns;
 	
 	absolute_direction = event->direction;
 	if (gtk_widget_get_direction (GTK_WIDGET (applet)) == GTK_TEXT_DIR_RTL) {
@@ -322,14 +317,96 @@
 		g_assert_not_reached ();
 		break;
 	}
+	
+	return index;
+}
 
-	wnck_workspace_activate (wnck_screen_get_workspace (pager->screen,
-							    index),
-				 event->time);
+static gboolean
+applet_scroll_workspace (PanelApplet    *applet,
+                         GdkEventScroll *event,
+                         PagerData      *pager)
+{
+	WnckWorkspace     *space;
+	int                index;
+	int                n_workspaces;
+	int                n_columns;
+	
+	index          = wnck_workspace_get_number (wnck_screen_get_active_workspace (pager->screen));
+	n_workspaces   = wnck_screen_get_workspace_count (pager->screen);
+	n_columns      = n_workspaces / pager->n_rows;
+	
+	index = applet_scroll_get_next_index (applet, event, pager, index,
+	                                      pager->n_rows, n_columns,
+	                                      n_workspaces);
+	
+	space = wnck_screen_get_workspace (pager->screen, index);
+	wnck_workspace_activate (space, event->time);
 	
 	return TRUE;
 }
 
+static gboolean
+applet_scroll_viewport (PanelApplet    *applet,
+                        GdkEventScroll *event,
+                        PagerData      *pager)
+{
+	WnckWorkspace *space;
+	int index;
+	int screen_width, screen_height;
+	int workspace_width, workspace_height;
+	int viewport_x, viewport_y;
+	int n_rows, n_columns, n_workspaces;
+	
+	/* There's only one workspace */
+	space = wnck_screen_get_workspace (pager->screen, 0);
+	
+	workspace_width = wnck_workspace_get_width (space);
+	workspace_height = wnck_workspace_get_height (space);
+	
+	screen_width  = wnck_screen_get_width  (pager->screen);
+	screen_height = wnck_screen_get_height (pager->screen);
+	
+	viewport_x = wnck_workspace_get_viewport_x (space);
+	viewport_y = wnck_workspace_get_viewport_y (space);
+	
+	/* Calculate the initial index based on viewport position:
+	
+	   - workspace_* are the dimensions of the entire
+	     virtual desktop.
+	   - screen_* are the dimensions of each viewport.
+	   - viewport_* are the location of the user's viewport.
+	**/
+	n_rows = workspace_height / screen_height;
+	n_columns = workspace_width / screen_width;
+	n_workspaces = n_rows * n_columns;
+	
+	index = n_columns * (viewport_y / screen_height) + viewport_x / screen_width;
+	index = applet_scroll_get_next_index (applet, event, pager, index,
+	                                      n_rows, n_columns,
+	                                      n_workspaces);
+	
+	/* From the new index, calculate the viewport's offset */
+	viewport_x = (index % n_columns) * screen_width;
+	viewport_y = (index / n_columns) * screen_height;
+	
+	wnck_screen_move_viewport (pager->screen, viewport_x, viewport_y);
+	
+	return TRUE;
+}
+
+static gboolean
+applet_scroll (PanelApplet    *applet,
+               GdkEventScroll *event,
+               PagerData      *pager)
+{
+	if (event->type != GDK_SCROLL)
+		return FALSE;
+	
+	if (pager->wm == PAGER_WM_COMPIZ)
+		return applet_scroll_viewport (applet, event, pager);
+	return applet_scroll_workspace (applet, event, pager);
+}
+
 static void
 destroy_pager(GtkWidget * widget, PagerData *pager)
 {
