diff --git a/libgnome-desktop/gnome-rr-config.c b/libgnome-desktop/gnome-rr-config.c
index 900f144..01d2c1d 100644
--- a/libgnome-desktop/gnome-rr-config.c
+++ b/libgnome-desktop/gnome-rr-config.c
@@ -189,6 +189,7 @@ handle_start_element (GMarkupParseContext *context,
 	}	
 	parser->output->connected = FALSE;
 	parser->output->on = FALSE;
+	parser->output->primary = FALSE;
     }
     else if (strcmp (name, "configuration") == 0)
     {
@@ -344,6 +345,13 @@ handle_text (GMarkupParseContext *context,
 	    parser->output->rotation |= GNOME_RR_REFLECT_Y;
 	}
     }
+    else if (stack_is (parser, "primary", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
+    {
+	if (strcmp (text, "yes") == 0)
+	{
+	    parser->output->primary = TRUE;
+	}
+    }
     else
     {
 	/* Ignore other properties so we can expand the format in the future */
@@ -555,6 +563,8 @@ gnome_rr_config_new_current (GnomeRRScreen *screen)
 		output->pref_height = 768;
 	    }
 	}
+
+        output->primary = gnome_rr_output_get_primary (rr_output);
  
 	g_ptr_array_add (a, output);
     }
@@ -985,6 +995,8 @@ emit_configuration (GnomeRRConfig *config,
 		string, "          <reflect_x>%s</reflect_x>\n", get_reflect_x (output->rotation));
 	    g_string_append_printf (
 		string, "          <reflect_y>%s</reflect_y>\n", get_reflect_y (output->rotation));
+            g_string_append_printf (
+                string, "          <primary>%s</primary>\n", yes_no (output->primary));
 	}
 	
 	g_string_append_printf (string, "      </output>\n");
@@ -998,6 +1010,7 @@ gnome_rr_config_sanitize (GnomeRRConfig *config)
 {
     int i;
     int x_offset, y_offset;
+    gboolean found;
 
     /* Offset everything by the top/left-most coordinate to
      * make sure the configuration starts at (0, 0)
@@ -1024,6 +1037,23 @@ gnome_rr_config_sanitize (GnomeRRConfig *config)
 	    output->y -= y_offset;
 	}
     }
+
+    /* Only one primary, please */
+    found = FALSE;
+    for (i = 0; config->outputs[i]; ++i)
+    {
+        if (config->outputs[i]->primary)
+        {
+            if (found)
+            {
+                config->outputs[i]->primary = FALSE;
+            }
+            else
+            {
+                found = TRUE;
+            }
+        }
+    }
 }
 
 
@@ -1179,7 +1209,7 @@ gnome_rr_config_apply_with_time (GnomeRRConfig *config,
     {
 	if (crtc_assignment_apply (assignment, timestamp, error))
 	    result = TRUE;
-	    
+
 	crtc_assignment_free (assignment);
 
 	gdk_flush ();
@@ -1340,6 +1370,7 @@ struct CrtcAssignment
 {
     GnomeRRScreen *screen;
     GHashTable *info;
+    GnomeRROutput *primary;
 };
 
 static gboolean
@@ -1366,6 +1397,7 @@ crtc_assignment_assign (CrtcAssignment   *assign,
 			int               x,
 			int               y,
 			GnomeRRRotation   rotation,
+                        gboolean          primary,
 			GnomeRROutput    *output)
 {
     CrtcInfo *info = g_hash_table_lookup (assign->info, crtc);
@@ -1387,6 +1419,11 @@ crtc_assignment_assign (CrtcAssignment   *assign,
 	{
 	    g_ptr_array_add (info->outputs, output);
 
+            if (primary && !assign->primary)
+            {
+                assign->primary = output;
+            }
+
 	    return TRUE;
 	}
     }
@@ -1404,6 +1441,11 @@ crtc_assignment_assign (CrtcAssignment   *assign,
 	
 	g_hash_table_insert (assign->info, crtc, info);
 	    
+        if (primary && !assign->primary)
+        {
+            assign->primary = output;
+        }
+
 	return TRUE;
     }
     
@@ -1421,6 +1463,11 @@ crtc_assignment_unassign (CrtcAssignment *assign,
     {
 	g_ptr_array_remove (info->outputs, output);
 
+        if (assign->primary == output)
+        {
+            assign->primary = NULL;
+        }
+
 	if (info->outputs->len == 0)
 	    g_hash_table_remove (assign->info, crtc);
     }
@@ -1541,6 +1588,7 @@ real_assign_crtcs (GnomeRRScreen *screen,
 			    assignment, crtc, modes[j],
 			    output->x, output->y,
 			    output->rotation,
+                            output->primary,
 			    gnome_rr_output))
 		    {
 			if (real_assign_crtcs (screen, outputs + 1, assignment))
@@ -1740,6 +1788,11 @@ crtc_assignment_apply (CrtcAssignment *assign, guint32 timestamp, GError **error
 	success = !state.has_error;
     }
 
+    if (assign->primary)
+    {
+        gnome_rr_output_set_primary (assign->primary);
+    }
+
     gdk_x11_display_ungrab (gdk_screen_get_display (assign->screen->gdk_screen));
 
     return success;
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
index 2484c1f..c968291 100644
--- a/libgnome-desktop/gnome-rr-private.h
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -19,6 +19,8 @@ struct ScreenInfo
     GnomeRRScreen *	screen;
 
     GnomeRRMode **	clone_modes;
+
+    RROutput            primary;
 };
 
 struct GnomeRRScreen
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index b788600..39d6e37 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -441,6 +441,17 @@ fill_out_screen_info (Display *xdisplay,
 					 &(info->max_height));
     }
 
+    info->primary = None;
+#if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
+    /* Runtime check for RandR 1.3 or higher */
+    if (info->screen->rr_major_version == 1 && info->screen->rr_minor_version >= 3) {
+        gdk_error_trap_push ();
+        info->primary = XRRGetOutputPrimary (xdisplay, xroot);
+	gdk_flush ();
+	gdk_error_trap_pop (); /* ignore error */
+    }
+#endif
+
     return TRUE;
 }
 
@@ -1129,6 +1140,24 @@ gnome_rr_output_can_clone (GnomeRROutput *output,
     return FALSE;
 }
 
+gboolean
+gnome_rr_output_get_primary (GnomeRROutput *output)
+{
+    return output->info->primary == output->id;
+}
+
+void
+gnome_rr_output_set_primary (GnomeRROutput *output)
+{
+    GnomeRRScreen *screen = output->info->screen;
+
+#if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
+        /* Runtime check for RandR 1.3 or higher */
+    if (screen->rr_major_version == 1 && screen->rr_minor_version >= 3)
+        XRRSetOutputPrimary (screen->xdisplay, screen->xroot, output->id);
+#endif
+}
+
 /* GnomeRRCrtc */
 typedef struct
 {
diff --git a/libgnome-desktop/libgnomeui/gnome-rr-config.h b/libgnome-desktop/libgnomeui/gnome-rr-config.h
index 7e54b09..d55a38c 100644
--- a/libgnome-desktop/libgnomeui/gnome-rr-config.h
+++ b/libgnome-desktop/libgnomeui/gnome-rr-config.h
@@ -61,6 +61,7 @@ struct GnomeOutputInfo
     int			pref_width;
     int			pref_height;
     char *		display_name;
+    gboolean            primary;
 
     gpointer		user_data;
 };
diff --git a/libgnome-desktop/libgnomeui/gnome-rr.h b/libgnome-desktop/libgnomeui/gnome-rr.h
index 02d8800..80147f6 100644
--- a/libgnome-desktop/libgnomeui/gnome-rr.h
+++ b/libgnome-desktop/libgnomeui/gnome-rr.h
@@ -115,6 +115,8 @@ GnomeRRMode **  gnome_rr_output_list_modes         (GnomeRROutput         *outpu
 GnomeRRMode *   gnome_rr_output_get_preferred_mode (GnomeRROutput         *output);
 gboolean        gnome_rr_output_supports_mode      (GnomeRROutput         *output,
 						    GnomeRRMode           *mode);
+gboolean        gnome_rr_output_get_primary        (GnomeRROutput         *output);
+void            gnome_rr_output_set_primary        (GnomeRROutput         *output);
 
 /* GnomeRRMode */
 guint32         gnome_rr_mode_get_id               (GnomeRRMode           *mode);
