Index: libwnck/pager.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/pager.c,v
retrieving revision 1.35
diff -u -r1.35 pager.c
--- libwnck/pager.c	22 Oct 2003 00:04:24 -0000	1.35
+++ libwnck/pager.c	9 Mar 2004 23:20:14 -0000
@@ -31,6 +31,7 @@
 
 
 #define N_SCREEN_CONNECTIONS 11
+#define TIMEOUT_ACTIVATE 1000
 
 struct _WnckPagerPrivate
 {
@@ -59,6 +60,8 @@
   GdkPixbuf *bg_cache;
 
   int layout_manager_token;
+  guint workspace_activate;
+  int over_workspace;
 };
 
 enum
@@ -90,6 +93,14 @@
                                           GdkEventButton   *event);
 static gboolean wnck_pager_motion        (GtkWidget        *widget,
                                           GdkEventMotion   *event);
+static gboolean wnck_pager_drag_motion   (GtkWidget        *widget,
+                                          GdkDragContext   *context,
+                                          gint             x,
+                                          gint             y,
+                                          guint            time);
+static void wnck_pager_drag_leave        (GtkWidget        *widget,
+                                          GdkDragContext   *context,
+                                          guint            time);
 static gboolean wnck_pager_button_release (GtkWidget        *widget,
                                            GdkEventButton   *event);
 static gboolean wnck_pager_focus         (GtkWidget        *widget,
@@ -160,8 +171,11 @@
   pager->priv->workspace_size = 48;
   pager->priv->bg_cache = NULL;
   pager->priv->layout_manager_token = WNCK_NO_MANAGER_TOKEN;
+  pager->priv->workspace_activate = 0;
+  pager->priv->over_workspace = -1;
 
   GTK_WIDGET_SET_FLAGS (GTK_WIDGET (pager), GTK_CAN_FOCUS);
+  gtk_drag_dest_set(GTK_WIDGET(pager), 0, NULL, 0, 0);
 }
 
 static void
@@ -182,6 +196,8 @@
   widget_class->button_press_event = wnck_pager_button_press;
   widget_class->button_release_event = wnck_pager_button_release;
   widget_class->motion_notify_event = wnck_pager_motion;
+  widget_class->drag_motion = wnck_pager_drag_motion;
+  widget_class->drag_leave = wnck_pager_drag_leave;
   widget_class->focus = wnck_pager_focus;
   widget_class->get_accessible = wnck_pager_get_accessible;   
 }
@@ -1081,6 +1097,80 @@
 }
 
 static gboolean
+wnck_pager_motion_timeout (gpointer data)
+{
+  WnckPager *pager = WNCK_PAGER(data);
+  WnckWorkspace *space;
+  int viewport_x,viewport_y;
+
+  pager->priv->workspace_activate = 0;
+
+  if (pager->priv->over_workspace >= 0)
+    {
+      space = wnck_screen_get_workspace (pager->priv->screen,
+                                         pager->priv->over_workspace);
+      if (space)
+        {
+          wnck_workspace_activate (space);
+
+          /* EWMH only lets us move the viewport for the active workspace,
+           * but we just go ahead and hackily assume that the activate
+           * just above takes effect prior to moving the viewport
+           */
+          viewport_x = wnck_workspace_get_viewport_x (space);
+          viewport_y = wnck_workspace_get_viewport_y (space);
+          wnck_screen_move_viewport (pager->priv->screen,
+                                     viewport_x, viewport_y);
+        }
+    }
+
+  return FALSE;
+}
+
+static gboolean
+wnck_pager_drag_motion (GtkWidget        *widget,
+                        GdkDragContext   *context,
+                        gint             x,
+                        gint             y,
+                        guint            time)
+{
+  WnckPager *pager = WNCK_PAGER(widget);
+  int i;
+
+  i = workspace_at_point(pager, x, y, NULL, NULL);
+  if (i >= 0 && pager->priv->over_workspace != i)
+    {
+      if (pager->priv->workspace_activate != 0)
+        g_source_remove(pager->priv->workspace_activate);
+      pager->priv->over_workspace = i;
+      pager->priv->workspace_activate = g_timeout_add (TIMEOUT_ACTIVATE,
+                                                       wnck_pager_motion_timeout,
+                                                       pager);
+    }
+
+  gdk_drag_status(context, 0, time);
+
+  return TRUE;
+}
+
+static void
+wnck_pager_drag_leave (GtkWidget         *widget,
+                       GdkDragContext    *context,
+                       guint             time)
+{
+  WnckPager *pager;
+
+  pager = WNCK_PAGER(widget);
+
+  if (pager->priv->workspace_activate != 0)
+    {
+      g_source_remove(pager->priv->workspace_activate);
+      pager->priv->workspace_activate = 0;
+      pager->priv->over_workspace = -1;
+    }
+}
+
+static gboolean
 wnck_pager_motion (GtkWidget        *widget,
                    GdkEventMotion   *event)
 {
