diff -Nurd metacity-2.21.13/src/core/prefs.c metacity-2.21.13.new/src/core/prefs.c
--- metacity-2.21.13/src/core/prefs.c	2008-02-03 05:49:18.000000000 +0100
+++ metacity-2.21.13.new/src/core/prefs.c	2008-02-13 06:01:37.000000000 +0100
@@ -77,6 +77,7 @@
 #define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme"
 #define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size"
 #define KEY_COMPOSITING_MANAGER "/apps/metacity/general/compositing_manager"
+#define KEY_CYCLE_WORKSPACES "/apps/metacity/general/cycle_workspaces"
 
 #ifdef HAVE_GCONF
 static GConfClient *default_client = NULL;
@@ -107,6 +108,7 @@
 static char *cursor_theme = NULL;
 static int   cursor_size = 24;
 static gboolean compositing_manager = FALSE;
+static gboolean cycle_workspaces = FALSE;
 
 static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
 static MetaButtonLayout button_layout;
@@ -156,6 +158,7 @@
 static gboolean update_cursor_theme       (const char *value);
 static gboolean update_cursor_size        (int size);
 static gboolean update_compositing_manager (gboolean	value);
+static gboolean update_cycle_workspaces (gboolean value);
 
 static void change_notify (GConfClient    *client,
                            guint           cnxn_id,
@@ -484,6 +487,11 @@
   bool_val = compositing_manager;
   if (get_bool (KEY_COMPOSITING_MANAGER, &bool_val))
     update_compositing_manager (bool_val);
+
+  bool_val = cycle_workspaces;
+  if (get_bool (KEY_CYCLE_WORKSPACES, &bool_val))
+    update_cycle_workspaces (bool_val);
+
   
   str_val = gconf_client_get_string (default_client, KEY_VISUAL_BELL_TYPE,
                                      &err);
@@ -1065,6 +1073,22 @@
       if (update_compositing_manager (b))
         queue_changed (META_PREF_COMPOSITING_MANAGER);
     }
+  else if (strcmp (key, KEY_CYCLE_WORKSPACES) == 0)
+    {
+      gboolean b;
+
+      if (value && value->type != GCONF_VALUE_BOOL)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                       KEY_CYCLE_WORKSPACES);
+          goto out;
+        }
+      
+      b = value ? gconf_value_get_bool (value) : cycle_workspaces;
+      
+      if (update_cycle_workspaces (b))
+        queue_changed (META_PREF_CYCLE_WORKSPACES);
+    }
   else
     {
       meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@@ -1850,6 +1874,9 @@
 
     case META_PREF_COMPOSITING_MANAGER:
       return "COMPOSITING_MANAGER";
+
+    case META_PREF_CYCLE_WORKSPACES:
+      return "CYCLE_WORKSPACES";
     }
 
   return "(unknown)";
@@ -3036,6 +3063,17 @@
   
   return old != compositing_manager;
 }
+
+static gboolean
+update_cycle_workspaces (gboolean value)
+{
+  gboolean old = cycle_workspaces;
+
+  cycle_workspaces = value;
+  
+  return old != cycle_workspaces;
+}
+
 #endif
 
 gboolean
@@ -3044,6 +3082,14 @@
   return compositing_manager;
 }
 
+gboolean
+meta_prefs_get_cycle_workspaces (void)
+{
+  return cycle_workspaces;
+}
+
+
+
 static void
 init_button_layout(void)
 {
diff -Nurd metacity-2.21.13/src/core/workspace.c metacity-2.21.13.new/src/core/workspace.c
--- metacity-2.21.13/src/core/workspace.c	2008-02-03 05:49:18.000000000 +0100
+++ metacity-2.21.13.new/src/core/workspace.c	2008-02-13 06:01:37.000000000 +0100
@@ -710,6 +710,7 @@
   MetaWorkspaceLayout layout;  
   int i, current_space, num_workspaces;
   gboolean ltr;
+  gboolean cycle;
 
   current_space = meta_workspace_index (workspace);
   num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
@@ -736,15 +737,16 @@
       layout.current_row += 1;
       break;
     }
+  cycle = meta_prefs_get_cycle_workspaces();
 
   if (layout.current_col < 0)
-    layout.current_col = 0;
+    layout.current_col = cycle ? (layout.cols - 1) : 0;
   if (layout.current_col >= layout.cols)
-    layout.current_col = layout.cols - 1;
+    layout.current_col = cycle ? 0 : (layout.cols - 1);
   if (layout.current_row < 0)
-    layout.current_row = 0;
+    layout.current_row = cycle ? (layout.rows - 1) : 0;
   if (layout.current_row >= layout.rows)
-    layout.current_row = layout.rows - 1;
+    layout.current_row = cycle ? 0 : (layout.rows - 1);
 
   i = layout.grid[layout.current_row * layout.cols + layout.current_col];
 
diff -Nurd metacity-2.21.13/src/include/prefs.h metacity-2.21.13.new/src/include/prefs.h
--- metacity-2.21.13/src/include/prefs.h	2008-02-03 05:49:11.000000000 +0100
+++ metacity-2.21.13.new/src/include/prefs.h	2008-02-13 06:01:37.000000000 +0100
@@ -58,7 +58,8 @@
   META_PREF_GNOME_ACCESSIBILITY,
   META_PREF_CURSOR_THEME,
   META_PREF_CURSOR_SIZE,
-  META_PREF_COMPOSITING_MANAGER
+  META_PREF_COMPOSITING_MANAGER,
+  META_PREF_CYCLE_WORKSPACES
 } MetaPreference;
 
 typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -110,6 +111,7 @@
 const char* meta_prefs_get_cursor_theme      (void);
 int         meta_prefs_get_cursor_size       (void);
 gboolean    meta_prefs_get_compositing_manager (void);
+gboolean    meta_prefs_get_cycle_workspaces (void);
 
 /* Screen bindings */
 #define META_KEYBINDING_WORKSPACE_1              "switch_to_workspace_1"
diff -Nurd metacity-2.21.13/src/metacity.schemas.in metacity-2.21.13.new/src/metacity.schemas.in
--- metacity-2.21.13/src/metacity.schemas.in	2008-02-03 05:49:22.000000000 +0100
+++ metacity-2.21.13.new/src/metacity.schemas.in	2008-02-13 06:03:08.000000000 +0100
@@ -321,6 +321,20 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/general/cycle_workspaces</key>
+      <applyto>/apps/metacity/general/cycle_workspaces</applyto>
+      <owner>metacity</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Cycle workspaces</short>
+        <long>
+          Determines whether Metacity cycles after the last (or before the first) workspace.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/metacity/workspace_names/name</key>
       <applyto>/apps/metacity/workspace_names/name_1</applyto>
       <applyto>/apps/metacity/workspace_names/name_2</applyto>
