Index: configure.in
===================================================================
RCS file: /cvs/gnome/libwnck/configure.in,v
retrieving revision 1.83
diff -u -p -u -r1.83 configure.in
--- configure.in	28 Mar 2003 07:11:05 -0000	1.83
+++ configure.in	2 Apr 2003 05:01:53 -0000
@@ -8,7 +8,7 @@ AM_MAINTAINER_MODE
 dnl libtool versioning for libwnck
 
 dnl increment if the interface has additions, changes, removals.
-LIBWNCK_CURRENT=9
+LIBWNCK_CURRENT=10
 
 dnl increment any time the source changes; set to
 dnl  0 if you increment CURRENT
@@ -17,7 +17,7 @@ LIBWNCK_REVISION=0
 dnl increment if any interfaces have been added; set to 0
 dnl  if any interfaces have been removed. removal has
 dnl  precedence over adding, so set to 0 if both happened.
-LIBWNCK_AGE=5
+LIBWNCK_AGE=6
 
 AC_SUBST(LIBWNCK_CURRENT)
 AC_SUBST(LIBWNCK_REVISION)
Index: libwnck/pager.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/pager.c,v
retrieving revision 1.32
diff -u -p -u -r1.32 pager.c
--- libwnck/pager.c	13 Mar 2003 04:21:05 -0000	1.32
+++ libwnck/pager.c	2 Apr 2003 05:01:53 -0000
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Kim Woelders
+ * Copyright (C) 2003 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,7 +30,7 @@
 #include "workspace-accessible-factory.h"
 
 
-#define N_SCREEN_CONNECTIONS 10
+#define N_SCREEN_CONNECTIONS 11
 
 struct _WnckPagerPrivate
 {
@@ -298,7 +300,9 @@ wnck_pager_size_request  (GtkWidget     
     }
   else
     {
-      screen_aspect = (double) gdk_screen_width () / (double) gdk_screen_height ();
+      screen_aspect =
+        (double) wnck_screen_get_width (pager->priv->screen) /
+        (double) wnck_screen_get_height (pager->priv->screen);
       
       if (pager->priv->show_all_workspaces)
 	{
@@ -525,20 +529,24 @@ get_windows_for_workspace_in_bottom_to_t
   GList *result;
   GList *windows;
   GList *tmp;
+  gboolean is_active;
   
   result = NULL;
+  is_active = workspace == wnck_screen_get_active_workspace (screen);
 
   windows = wnck_screen_get_windows_stacked (screen);
-  tmp = windows;
-  while (tmp != NULL)
+  for (tmp = windows; tmp != NULL; tmp = tmp->next)
     {
       WnckWindow *win = WNCK_WINDOW (tmp->data);
 
-      if (wnck_window_is_visible_on_workspace (win, workspace) &&
-          (wnck_window_get_state (win) & WNCK_WINDOW_STATE_SKIP_PAGER) == 0)
-        result = g_list_prepend (result, win);
-      
-      tmp = tmp->next;
+      if (!wnck_window_is_visible_on_workspace (win, workspace))
+        continue;
+      if (wnck_window_get_state (win) & WNCK_WINDOW_STATE_SKIP_PAGER)
+        continue;
+      if (!is_active && wnck_window_is_sticky (win))
+        continue;
+
+      result = g_list_prepend (result, win);
     }
 
   result = g_list_reverse (result);
@@ -553,12 +561,20 @@ get_window_rect (WnckWindow         *win
 {
   double width_ratio, height_ratio;
   int x, y, width, height;
+  WnckWorkspace *workspace;
   
-  width_ratio = (double) workspace_rect->width / (double) gdk_screen_width ();
-  height_ratio = (double) workspace_rect->height / (double) gdk_screen_height ();
+  workspace = wnck_window_get_workspace (window);
+  if (workspace == NULL)
+    workspace = wnck_screen_get_active_workspace (wnck_window_get_screen (window));
+
+  /* scale window down by same ratio we scaled workspace down */
+  width_ratio = (double) workspace_rect->width / (double) wnck_workspace_get_width (workspace);
+  height_ratio = (double) workspace_rect->height / (double) wnck_workspace_get_height (workspace);
   
   wnck_window_get_geometry (window, &x, &y, &width, &height);
   
+  x += wnck_workspace_get_viewport_x (workspace);
+  y += wnck_workspace_get_viewport_y (workspace);
   x *= width_ratio;
   y *= height_ratio;
   width *= width_ratio;
@@ -675,7 +691,9 @@ draw_window (GdkDrawable        *drawabl
 static int
 workspace_at_point (WnckPager *pager,
                     int        x,
-                    int        y)
+                    int        y,
+                    int       *viewport_x,
+                    int       *viewport_y)
 {
   GtkWidget *widget;
   int i;
@@ -731,7 +749,25 @@ workspace_at_point (WnckPager *pager,
 	}
 
       if (POINT_IN_RECT (x, y, rect))
-        return i;
+        {
+	  double width_ratio, height_ratio;
+	  WnckWorkspace *space;
+
+	  space = wnck_screen_get_workspace (pager->priv->screen, i);
+          g_assert (space != NULL);
+
+          /* Scale x, y mouse coords to corresponding screenwide viewport coords */
+          
+          width_ratio = (double) wnck_workspace_get_width (space) / (double) rect.width;
+          height_ratio = (double) wnck_workspace_get_height (space) / (double) rect.height;
+
+          if (viewport_x)
+            *viewport_x = width_ratio * (x - rect.x);
+          if (viewport_y)
+            *viewport_y = height_ratio * (y - rect.y);
+
+	  return i;
+	}
 
       ++i;
     }
@@ -761,12 +797,23 @@ wnck_pager_draw_workspace (WnckPager    
    */
   
   if (is_current)
-    gdk_draw_rectangle (GTK_WIDGET (pager)->window,
-                        prelight ? 
-                        GTK_WIDGET (pager)->style->mid_gc[GTK_STATE_SELECTED] :
-                        GTK_WIDGET (pager)->style->dark_gc[GTK_STATE_SELECTED],
-                        TRUE,
-                        rect->x, rect->y, rect->width, rect->height);
+    {
+      int vx, vy, vw, vh; /* viewport */
+      double width_ratio, height_ratio;
+      
+      width_ratio = rect->width / (double) wnck_workspace_get_width (active_space);
+      height_ratio = rect->height / (double) wnck_workspace_get_height (active_space);
+      vx = rect->x + width_ratio * wnck_workspace_get_viewport_x (active_space);
+      vy = rect->y + height_ratio * wnck_workspace_get_viewport_y (active_space);
+      vw = width_ratio * wnck_screen_get_width (pager->priv->screen);
+      vh = height_ratio * wnck_screen_get_height (pager->priv->screen);
+
+      gdk_draw_rectangle (GTK_WIDGET (pager)->window,
+                          prelight ? 
+                          GTK_WIDGET (pager)->style->mid_gc[GTK_STATE_SELECTED] :
+                          GTK_WIDGET (pager)->style->dark_gc[GTK_STATE_SELECTED],
+                          TRUE, vx, vy, vw, vh); 
+    }
   else if (prelight)
     gdk_draw_rectangle (GTK_WIDGET (pager)->window,
                         GTK_WIDGET (pager)->style->dark_gc[GTK_STATE_PRELIGHT],
@@ -827,8 +874,6 @@ wnck_pager_draw_workspace (WnckPager    
       PangoLayout *layout;
       int w, h;
 
-      
-
       workspace_name = wnck_workspace_get_name (wnck_screen_get_workspace (pager->priv->screen,
 									   workspace));
       layout = gtk_widget_create_pango_layout  (GTK_WIDGET (pager),
@@ -901,7 +946,8 @@ wnck_pager_expose_event  (GtkWidget     
   if (pager->priv->dragging)
     drag_space = workspace_at_point (pager,
                                      pager->priv->drag_window_x,
-                                     pager->priv->drag_window_y);
+                                     pager->priv->drag_window_y,
+                                     NULL, NULL);
   else
     drag_space = -1;
   
@@ -974,7 +1020,7 @@ wnck_pager_button_press (GtkWidget      
 						    
   pager = WNCK_PAGER (widget);
 
-  space_number = workspace_at_point (pager, event->x, event->y);
+  space_number = workspace_at_point (pager, event->x, event->y, NULL, NULL);
 
   if (space_number != -1)
     {
@@ -1068,15 +1114,14 @@ wnck_pager_button_release (GtkWidget    
   WnckPager *pager;
   int i;
   gboolean handled = FALSE;
-
+  int viewport_x;
+  int viewport_y;
+  
   pager = WNCK_PAGER (widget);
 
   if (event->button == 1 && pager->priv->dragging)
     {
-      
-      i = workspace_at_point (pager,
-                              event->x,
-                              event->y);
+      i = workspace_at_point (pager, event->x, event->y, NULL, NULL);
 
       if (i >= 0)
 	{
@@ -1096,9 +1141,7 @@ wnck_pager_button_release (GtkWidget    
     }
   else if (event->button == 1)
     {
-      i = workspace_at_point (pager,
-                              event->x,
-                              event->y);
+      i = workspace_at_point (pager, event->x, event->y, &viewport_x, &viewport_y);
 
       if (i >= 0)
 	{
@@ -1106,9 +1149,14 @@ wnck_pager_button_release (GtkWidget    
 
 	  if (space)
             {
-              if (space != wnck_screen_get_active_workspace (pager->priv->screen))
-                wnck_workspace_activate (space);
-              else if (pager->priv->drag_window)
+              wnck_workspace_activate (space);
+
+              /* EWMH only lets us move the viewport for the active workspace */
+              if (space == wnck_screen_get_active_workspace (pager->priv->screen))
+                wnck_screen_move_viewport (pager->priv->screen,
+                                           viewport_x, viewport_y);
+              
+              if (pager->priv->drag_window)
                 wnck_window_activate (pager->priv->drag_window);
             }
 	}
@@ -1412,6 +1460,13 @@ workspace_name_changed_callback (WnckWor
 }
 
 static void
+viewports_changed_callback (WnckWorkspace *space,
+                            gpointer       data)
+{
+  gtk_widget_queue_resize (GTK_WIDGET (data));
+}
+
+static void
 wnck_pager_connect_screen (WnckPager  *pager,
                            WnckScreen *screen)
 {
@@ -1482,6 +1537,11 @@ wnck_pager_connect_screen (WnckPager  *p
                            G_CALLBACK (background_changed_callback),
                            pager);
   ++i;
+
+  c[i] = g_signal_connect (G_OBJECT (screen), "viewports_changed",
+                           G_CALLBACK (viewports_changed_callback),
+                           pager);
+  ++i;
   
   g_assert (i == N_SCREEN_CONNECTIONS);
 
@@ -1699,7 +1759,7 @@ _wnck_pager_get_workspace (WnckPager *pa
 void 
 _wnck_pager_activate_workspace (WnckWorkspace *wspace)
 {
-  wnck_workspace_activate (wspace); 
+  wnck_workspace_activate (wspace);
 }
 
 void
Index: libwnck/private.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/private.h,v
retrieving revision 1.14
diff -u -p -u -r1.14 private.h
--- libwnck/private.h	23 Jan 2003 02:11:30 -0000	1.14
+++ libwnck/private.h	2 Apr 2003 05:01:53 -0000
@@ -77,6 +77,9 @@ void _wnck_screen_change_workspace_name 
                                          int         number,
                                          const char *name);
 
+gboolean _wnck_workspace_set_geometry (WnckWorkspace *space, int w, int h);
+gboolean _wnck_workspace_set_viewport (WnckWorkspace *space, int x, int y);
+
 void _wnck_init (void);
 
 #define DEFAULT_ICON_WIDTH 32
Index: libwnck/screen.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/screen.c,v
retrieving revision 1.22
diff -u -p -u -r1.22 screen.c
--- libwnck/screen.c	3 Nov 2002 19:04:18 -0000	1.22
+++ libwnck/screen.c	2 Apr 2003 05:01:53 -0000
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Kim Woelders
+ * Copyright (C) 2003 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -37,8 +39,7 @@ struct _WnckScreenPrivate
   int number;
   Window xroot;
   Screen *xscreen;
-  int width;
-  int height;
+  
   /* in map order */
   GList *mapped_windows;
   /* in stacking order */
@@ -64,6 +65,7 @@ struct _WnckScreenPrivate
    */
   guint need_update_stack_list : 1;
   guint need_update_workspace_list : 1;
+  guint need_update_viewport_settings : 1;
   guint need_update_active_workspace : 1;
   guint need_update_active_window : 1;
   guint need_update_workspace_names : 1;
@@ -83,6 +85,7 @@ enum {
   APPLICATION_CLOSED,
   BACKGROUND_CHANGED,
   SHOWING_DESKTOP_CHANGED,
+  VIEWPORTS_CHANGED,
   LAST_SIGNAL
 };
 
@@ -90,12 +93,13 @@ static void wnck_screen_init        (Wnc
 static void wnck_screen_class_init  (WnckScreenClass *klass);
 static void wnck_screen_finalize    (GObject         *object);
 
-static void update_client_list      (WnckScreen      *screen);
-static void update_workspace_list   (WnckScreen      *screen);
-static void update_active_workspace (WnckScreen      *screen);
-static void update_active_window    (WnckScreen      *screen);
-static void update_workspace_names  (WnckScreen      *screen);
-static void update_showing_desktop  (WnckScreen      *screen);
+static void update_client_list        (WnckScreen      *screen);
+static void update_workspace_list     (WnckScreen      *screen);
+static void update_viewport_settings  (WnckScreen      *screen);
+static void update_active_workspace   (WnckScreen      *screen);
+static void update_active_window      (WnckScreen      *screen);
+static void update_workspace_names    (WnckScreen      *screen);
+static void update_showing_desktop    (WnckScreen      *screen);
 
 static void queue_update            (WnckScreen      *screen);
 static void unqueue_update          (WnckScreen      *screen);              
@@ -118,6 +122,7 @@ static void emit_application_closed     
                                            WnckApplication *app);
 static void emit_background_changed       (WnckScreen      *screen);
 static void emit_showing_desktop_changed  (WnckScreen      *screen);
+static void emit_viewports_changed        (WnckScreen      *screen);
 
 static gpointer parent_class;
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -272,6 +277,20 @@ wnck_screen_class_init (WnckScreenClass 
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+    signals[VIEWPORTS_CHANGED] =
+    g_signal_new ("viewports_changed",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST,
+#if 0
+                  /* FIXME when we can break ABI add this */
+                  G_STRUCT_OFFSET (WnckScreenClass, viewports_changed),
+#else
+                  0,
+#endif
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 }
 
 static void
@@ -338,11 +357,9 @@ wnck_screen_construct (WnckScreen *scree
   _wnck_select_input (screen->priv->xroot,
                       PropertyChangeMask);
 
-  screen->priv->width = WidthOfScreen (screen->priv->xscreen);
-  screen->priv->height = HeightOfScreen (screen->priv->xscreen);
-
   screen->priv->need_update_workspace_list = TRUE;
   screen->priv->need_update_stack_list = TRUE;
+  screen->priv->need_update_viewport_settings = TRUE;
   screen->priv->need_update_active_workspace = TRUE;
   screen->priv->need_update_active_window = TRUE;
   screen->priv->need_update_workspace_names = TRUE;
@@ -645,6 +662,18 @@ _wnck_screen_process_property_notify (Wn
       queue_update (screen);
     }
   else if (xevent->xproperty.atom ==
+           _wnck_atom_get ("_NET_DESKTOP_VIEWPORT"))
+    {
+      screen->priv->need_update_viewport_settings = TRUE;
+      queue_update (screen);
+    }
+  else if (xevent->xproperty.atom ==
+           _wnck_atom_get ("_NET_DESKTOP_GEOMETRY"))
+    {
+      screen->priv->need_update_viewport_settings = TRUE;
+      queue_update (screen);
+    }
+  else if (xevent->xproperty.atom ==
            _wnck_atom_get ("_NET_NUMBER_OF_DESKTOPS"))
     {
       screen->priv->need_update_workspace_list = TRUE;
@@ -1138,6 +1167,118 @@ update_workspace_list (WnckScreen *scree
 }
 
 static void
+update_viewport_settings (WnckScreen *screen)
+{
+  int i, n_spaces;
+  WnckWorkspace *space;
+  gulong *p_coord;
+  int n_coord;
+  gboolean do_update;
+  int space_width, space_height;
+  gboolean got_viewport_prop;
+  
+  if (!screen->priv->need_update_viewport_settings)
+    return;
+
+  screen->priv->need_update_viewport_settings = FALSE;
+
+  do_update = FALSE;
+
+  n_spaces = wnck_screen_get_workspace_count (screen);
+
+  /* If no property, use the screen's size */
+  space_width = wnck_screen_get_width (screen);
+  space_height = wnck_screen_get_height (screen);
+  
+  if (_wnck_get_cardinal_list (screen->priv->xroot,
+			       _wnck_atom_get ("_NET_DESKTOP_GEOMETRY"),
+                               &p_coord, &n_coord) &&
+      p_coord != NULL)
+    {
+      if (n_coord == 2)
+	{
+          space_width = p_coord[0];
+          space_height = p_coord[1];
+          
+          if (space_width < wnck_screen_get_width (screen))
+            space_width = wnck_screen_get_width (screen);
+
+          if (space_height < wnck_screen_get_height (screen))
+            space_height = wnck_screen_get_height (screen);
+	}
+      
+      g_free (p_coord);
+    }
+          
+  for (i = 0; i < n_spaces; i++)
+    {
+      space = wnck_screen_get_workspace (screen, i);
+      g_assert (space != NULL);
+      
+      if (_wnck_workspace_set_geometry (space, space_width, space_height))
+        do_update = TRUE;
+    }
+
+  got_viewport_prop = FALSE;
+  
+  if (_wnck_get_cardinal_list (screen->priv->xroot,
+                               _wnck_atom_get ("_NET_DESKTOP_VIEWPORT"),
+                               &p_coord, &n_coord) &&
+      p_coord != NULL)
+    {
+      if (n_coord == 2 * n_spaces)
+        {
+          int screen_width, screen_height;
+
+          got_viewport_prop = TRUE;
+          
+          screen_width = wnck_screen_get_width (screen);
+          screen_height = wnck_screen_get_height (screen);
+          
+	  for (i = 0; i < n_spaces; i++)
+	    {
+              int x = 2 * i;
+              int y = 2 * i + 1;
+
+              space = wnck_screen_get_workspace (screen, i);
+              g_assert (space != NULL);
+              
+              if (p_coord[x] < 0)
+                p_coord[x] = 0;
+              else if (p_coord[x] > space_width - screen_width)
+                p_coord[x] = space_width - screen_width;
+
+              if (p_coord[y] < 0)
+                p_coord[y] = 0;
+              else if (p_coord[y] > space_height - screen_height)
+                p_coord[y] = space_height - screen_height;
+
+	      if (_wnck_workspace_set_viewport (space,
+                                                p_coord[x], p_coord[y]))
+                do_update = TRUE;
+	    }
+	}
+      
+      g_free (p_coord);
+    }
+
+  if (!got_viewport_prop)
+    {
+      for (i = 0; i < n_spaces; i++)
+        {
+          space = wnck_screen_get_workspace (screen, i);
+          g_assert (space != NULL);
+          
+          if (_wnck_workspace_set_viewport (space, 0, 0))
+            do_update = TRUE;
+        }
+    }
+  
+  if (do_update)
+    emit_viewports_changed (screen);
+}
+
+static void
 update_active_workspace (WnckScreen *screen)
 {
   int number;
@@ -1284,6 +1425,7 @@ do_update_now (WnckScreen *screen)
 
   /* Then note any smaller-scale changes */
   update_active_workspace (screen);
+  update_viewport_settings (screen);
   update_active_window (screen);
   update_workspace_names (screen);
   update_showing_desktop (screen);
@@ -1418,6 +1560,14 @@ emit_showing_desktop_changed (WnckScreen
                  0);
 }
 
+static void
+emit_viewports_changed (WnckScreen *screen)
+{
+  g_signal_emit (G_OBJECT (screen),
+                 signals[VIEWPORTS_CHANGED],
+                 0);
+}
+
 gboolean
 wnck_screen_net_wm_supports (WnckScreen *screen,
                              const char *atom)
@@ -1438,7 +1588,7 @@ wnck_screen_get_width (WnckScreen *scree
 {
   g_return_val_if_fail (WNCK_IS_SCREEN (screen), 0);
 
-  return gdk_screen_width ();
+  return WidthOfScreen (screen->priv->xscreen);
 }
 
 int
@@ -1446,7 +1596,7 @@ wnck_screen_get_height (WnckScreen *scre
 {
   g_return_val_if_fail (WNCK_IS_SCREEN (screen), 0);
 
-  return gdk_screen_height ();
+  return HeightOfScreen (screen->priv->xscreen);
 }
 
 Screen *
@@ -1507,6 +1657,27 @@ wnck_screen_toggle_showing_desktop (Wnck
 
   _wnck_toggle_showing_desktop (screen->priv->xscreen,
                                 show);
+}
+
+
+/**
+ * wnck_screen_move_viewport:
+ * @screen: a #WnckScreen
+ * @x: X offset of viewport
+ * @y: Y offset of viewport
+ *
+ * Ask window manager to move the viewport of the current workspace.
+ */
+void
+wnck_screen_move_viewport (WnckScreen *screen,
+                           int         x,
+                           int         y)
+{
+  g_return_if_fail (WNCK_IS_SCREEN (screen));
+  g_return_if_fail (x >= 0);
+  g_return_if_fail (y >= 0);
+  
+  _wnck_change_viewport (WNCK_SCREEN_XSCREEN (screen), x, y);
 }
 
 #ifdef HAVE_STARTUP_NOTIFICATION
Index: libwnck/screen.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/screen.h,v
retrieving revision 1.12
diff -u -p -u -r1.12 screen.h
--- libwnck/screen.h	3 Nov 2002 19:04:18 -0000	1.12
+++ libwnck/screen.h	2 Apr 2003 05:01:53 -0000
@@ -88,6 +88,9 @@ struct _WnckScreenClass
 
   /* Toggle showing desktop */
   void (* showing_desktop_changed)  (WnckScreen      *screen);
+
+  /* Viewport stuff changed */
+  void (* viewports_changed)        (WnckScreen      *screen);
   
   void (* pad1) (void);
   void (* pad2) (void);
@@ -102,44 +105,36 @@ struct _WnckScreenClass
 
 GType wnck_screen_get_type (void) G_GNUC_CONST;
 
-WnckScreen* wnck_screen_get_default (void);
-WnckScreen* wnck_screen_get (int index);
-WnckScreen* wnck_screen_get_for_root (gulong root_window_id);
-
-WnckWorkspace* wnck_screen_get_workspace        (WnckScreen *screen,
-						 int         workspace);
-WnckWorkspace* wnck_screen_get_active_workspace (WnckScreen *screen);
-WnckWindow*    wnck_screen_get_active_window    (WnckScreen *screen);
-
-GList*         wnck_screen_get_windows          (WnckScreen *screen);
-GList*         wnck_screen_get_windows_stacked  (WnckScreen *screen);
-
-void wnck_screen_force_update (WnckScreen *screen);
-
-int  wnck_screen_get_workspace_count    (WnckScreen *screen);
-void wnck_screen_change_workspace_count (WnckScreen *screen,
-                                         int         count);
-
-gboolean wnck_screen_net_wm_supports (WnckScreen *screen,
-                                      const char *atom);
-
-gulong wnck_screen_get_background_pixmap (WnckScreen *screen);
-
-int wnck_screen_get_width (WnckScreen *screen);
-int wnck_screen_get_height (WnckScreen *screen);
-
-gboolean wnck_screen_get_showing_desktop    (WnckScreen *screen);
-void     wnck_screen_toggle_showing_desktop (WnckScreen *screen,
-                                             gboolean    show);
-
-int  wnck_screen_try_set_workspace_layout (WnckScreen *screen,
-                                           int         current_token,
-                                           int         rows,
-                                           int         columns);
-void wnck_screen_release_workspace_layout (WnckScreen *screen,
-                                           int         current_token);
-
-
+WnckScreen*    wnck_screen_get_default              (void);
+WnckScreen*    wnck_screen_get                      (int         index);
+WnckScreen*    wnck_screen_get_for_root             (gulong      root_window_id);
+WnckWorkspace* wnck_screen_get_workspace            (WnckScreen *screen,
+                                                     int         workspace);
+WnckWorkspace* wnck_screen_get_active_workspace     (WnckScreen *screen);
+WnckWindow*    wnck_screen_get_active_window        (WnckScreen *screen);
+GList*         wnck_screen_get_windows              (WnckScreen *screen);
+GList*         wnck_screen_get_windows_stacked      (WnckScreen *screen);
+void           wnck_screen_force_update             (WnckScreen *screen);
+int            wnck_screen_get_workspace_count      (WnckScreen *screen);
+void           wnck_screen_change_workspace_count   (WnckScreen *screen,
+                                                     int         count);
+gboolean       wnck_screen_net_wm_supports          (WnckScreen *screen,
+                                                     const char *atom);
+gulong         wnck_screen_get_background_pixmap    (WnckScreen *screen);
+int            wnck_screen_get_width                (WnckScreen *screen);
+int            wnck_screen_get_height               (WnckScreen *screen);
+gboolean       wnck_screen_get_showing_desktop      (WnckScreen *screen);
+void           wnck_screen_toggle_showing_desktop   (WnckScreen *screen,
+                                                     gboolean    show);
+void           wnck_screen_move_viewport            (WnckScreen *screen,
+                                                     int         x,
+                                                     int         y);
+int            wnck_screen_try_set_workspace_layout (WnckScreen *screen,
+                                                     int         current_token,
+                                                     int         rows,
+                                                     int         columns);
+void           wnck_screen_release_workspace_layout (WnckScreen *screen,
+                                                     int         current_token);
 
 
 G_END_DECLS
Index: libwnck/tasklist.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/tasklist.c,v
retrieving revision 1.47
diff -u -p -u -r1.47 tasklist.c
--- libwnck/tasklist.c	25 Jan 2003 21:16:17 -0000	1.47
+++ libwnck/tasklist.c	2 Apr 2003 05:01:54 -0000
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Kim Woelders
+ * Copyright (C) 2003 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -1384,7 +1386,7 @@ wnck_tasklist_update_lists (WnckTasklist
       if ((state & WNCK_WINDOW_STATE_SKIP_TASKLIST) == 0 &&
 	  (tasklist->priv->include_all_workspaces ||
 	   active_workspace == NULL ||
-	   wnck_window_is_on_workspace (win, active_workspace)))
+	   wnck_window_is_in_viewport (win, active_workspace)))
 	{
 	  win_task = wnck_task_new_from_window (tasklist, win);
 	  tasklist->priv->windows = g_list_prepend (tasklist->priv->windows, win_task);
Index: libwnck/window.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/window.c,v
retrieving revision 1.34
diff -u -p -u -r1.34 window.c
--- libwnck/window.c	23 Jan 2003 02:11:30 -0000	1.34
+++ libwnck/window.c	2 Apr 2003 05:01:54 -0000
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Kim Woelders
+ * Copyright (C) 2003 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -1282,6 +1284,43 @@ wnck_window_is_on_workspace (WnckWindow 
   
   return wnck_window_is_pinned (window) ||
     wnck_window_get_workspace (window) == workspace;
+}
+
+/**
+ * wnck_window_is_in_viewport:
+ * @window: a #WnckWindow
+ * @workspace: a #WnckWorkspace
+ * 
+ * Returns #TRUE if the window is inside the current viewport
+ * of the given workspace.
+ * 
+ * Return value: %TRUE if @window appears in current viewport
+ **/
+gboolean
+wnck_window_is_in_viewport (WnckWindow    *window,
+                            WnckWorkspace *workspace)
+{
+  GdkRectangle window_rect;
+  GdkRectangle viewport_rect;
+  
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  g_return_val_if_fail (WNCK_IS_WORKSPACE (workspace), FALSE);
+
+  if (wnck_window_get_workspace (window) != workspace &&
+      !wnck_window_is_pinned (window))
+    return FALSE;
+
+  viewport_rect.x = wnck_workspace_get_viewport_x (workspace);
+  viewport_rect.y = wnck_workspace_get_viewport_y (workspace);
+  viewport_rect.width = wnck_screen_get_width (window->priv->screen);
+  viewport_rect.height = wnck_screen_get_height (window->priv->screen);
+
+  window_rect.x = window->priv->x + viewport_rect.x;
+  window_rect.y = window->priv->y + viewport_rect.y;
+  window_rect.width = window->priv->width;
+  window_rect.height = window->priv->height;
+
+  return gdk_rectangle_intersect (&viewport_rect, &window_rect, &window_rect);
 }
 
 void
Index: libwnck/window.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/window.h,v
retrieving revision 1.19
diff -u -p -u -r1.19 window.h
--- libwnck/window.h	31 Oct 2002 05:43:44 -0000	1.19
+++ libwnck/window.h	2 Apr 2003 05:01:54 -0000
@@ -210,6 +210,8 @@ gboolean wnck_window_is_visible_on_works
                                               WnckWorkspace *workspace);
 gboolean wnck_window_is_on_workspace         (WnckWindow    *window,
                                               WnckWorkspace *workspace);
+gboolean wnck_window_is_in_viewport          (WnckWindow    *window,
+                                              WnckWorkspace *workspace);
 
 G_END_DECLS
 
Index: libwnck/workspace.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/workspace.c,v
retrieving revision 1.10
diff -u -p -u -r1.10 workspace.c
--- libwnck/workspace.c	3 Nov 2002 19:04:18 -0000	1.10
+++ libwnck/workspace.c	2 Apr 2003 05:01:54 -0000
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Kim Woelders
+ * Copyright (C) 2003 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -31,6 +33,8 @@ struct _WnckWorkspacePrivate
   WnckScreen *screen;
   int number;
   char *name;
+  int width, height;            /* Workspace size */
+  int viewport_x, viewport_y;   /* Viewport origin */
 };
 
 enum {
@@ -143,9 +147,6 @@ wnck_workspace_get_number (WnckWorkspace
  * in the user interface. If the user hasn't set a special name,
  * will be something like "Workspace 3" - otherwise whatever name
  * the user set.
- *
- * FIXME haven't actually implemented reading the user-set
- * name from the window manager.
  * 
  * Return value: workspace name, never %NULL 
  **/
@@ -204,6 +205,13 @@ _wnck_workspace_create (int number, Wnck
 
   _wnck_workspace_update_name (space, NULL);
   
+  /* Just set reasonable defaults */
+  space->priv->width = wnck_screen_get_width (screen);
+  space->priv->height = wnck_screen_get_height (screen);
+
+  space->priv->viewport_x = 0;
+  space->priv->viewport_y = 0;
+
   return space;
 }
 
@@ -236,4 +244,60 @@ emit_name_changed (WnckWorkspace *space)
   g_signal_emit (G_OBJECT (space),
                  signals[NAME_CHANGED],
                  0);
+}
+
+gboolean
+_wnck_workspace_set_geometry (WnckWorkspace *space,
+                              int            w,
+                              int            h)
+{
+  if (space->priv->width != w || space->priv->height != h)
+    {
+      space->priv->width = w;
+      space->priv->height = h;
+
+      return TRUE;  /* change was made */
+    }
+  else
+    return FALSE; 
+}
+
+gboolean
+_wnck_workspace_set_viewport (WnckWorkspace *space,
+                              int            x,
+                              int            y)
+{
+  if (space->priv->viewport_x != x || space->priv->viewport_y != y)
+    {
+      space->priv->viewport_x = x;
+      space->priv->viewport_y = y;
+
+      return TRUE; /* change was made */
+    }
+  else
+    return FALSE;
+}
+
+int
+wnck_workspace_get_width (WnckWorkspace *space)
+{
+  return space->priv->width;
+}
+
+int
+wnck_workspace_get_height (WnckWorkspace *space)
+{
+  return space->priv->height;
+}
+
+int
+wnck_workspace_get_viewport_x (WnckWorkspace *space)
+{
+  return space->priv->viewport_x;
+}
+
+int
+wnck_workspace_get_viewport_y (WnckWorkspace *space)
+{
+  return space->priv->viewport_y;
 }
Index: libwnck/workspace.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/workspace.h,v
retrieving revision 1.7
diff -u -p -u -r1.7 workspace.h
--- libwnck/workspace.h	3 Nov 2002 19:04:18 -0000	1.7
+++ libwnck/workspace.h	2 Apr 2003 05:01:54 -0000
@@ -53,13 +53,16 @@ struct _WnckWorkspaceClass
 
 GType wnck_workspace_get_type (void) G_GNUC_CONST;
 
-int wnck_workspace_get_number (WnckWorkspace *space);
+int         wnck_workspace_get_number     (WnckWorkspace *space);
+const char* wnck_workspace_get_name       (WnckWorkspace *space);
+void        wnck_workspace_change_name    (WnckWorkspace *space,
+                                           const char    *name);
+void        wnck_workspace_activate       (WnckWorkspace *space);
+int         wnck_workspace_get_width      (WnckWorkspace *space);
+int         wnck_workspace_get_height     (WnckWorkspace *space);
+int         wnck_workspace_get_viewport_x (WnckWorkspace *space);
+int         wnck_workspace_get_viewport_y (WnckWorkspace *space);
 
-const char* wnck_workspace_get_name    (WnckWorkspace *space);
-void        wnck_workspace_change_name (WnckWorkspace *space,
-                                        const char    *name);
-
-void wnck_workspace_activate (WnckWorkspace *space);
 
 G_END_DECLS
 
Index: libwnck/xutils.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/xutils.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 xutils.c
--- libwnck/xutils.c	23 Jan 2003 02:11:30 -0000	1.39
+++ libwnck/xutils.c	2 Apr 2003 05:01:54 -0000
@@ -1015,6 +1015,31 @@ _wnck_activate_workspace (Screen *screen
 }
 
 void
+_wnck_change_viewport (Screen *screen,
+		       int     x,
+		       int     y)
+{
+  XEvent xev;
+  
+  xev.xclient.type = ClientMessage;
+  xev.xclient.serial = 0;
+  xev.xclient.send_event = True;
+  xev.xclient.display = gdk_display;
+  xev.xclient.window = RootWindowOfScreen (screen);
+  xev.xclient.message_type = _wnck_atom_get ("_NET_DESKTOP_VIEWPORT");
+  xev.xclient.format = 32;
+  xev.xclient.data.l[0] = x;
+  xev.xclient.data.l[1] = y;
+  xev.xclient.data.l[2] = 0;
+
+  XSendEvent (gdk_display,
+	      RootWindowOfScreen (screen),
+              False,
+	      SubstructureRedirectMask | SubstructureNotifyMask,
+	      &xev);
+}
+
+void
 _wnck_toggle_showing_desktop (Screen  *screen,
                               gboolean show)
 {
Index: libwnck/xutils.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/xutils.h,v
retrieving revision 1.22
diff -u -p -u -r1.22 xutils.h
--- libwnck/xutils.h	23 Jan 2003 02:11:30 -0000	1.22
+++ libwnck/xutils.h	2 Apr 2003 05:01:54 -0000
@@ -102,6 +102,9 @@ void _wnck_activate         (Screen  *sc
 			     Window   xwindow);
 void _wnck_activate_workspace (Screen *screen,
 			       int     new_active_space);
+void _wnck_change_viewport (Screen *screen,
+			    int     x,
+			    int     y);
 
 Window _wnck_get_group_leader   (Window xwindow);
 char*  _wnck_get_session_id     (Window xwindow);
