Index: src/file-manager/fm-icon-view.c
===================================================================
--- src/file-manager/fm-icon-view.c	(revision 12868)
+++ src/file-manager/fm-icon-view.c	(working copy)
@@ -2167,6 +2167,7 @@
 	char *position_string;
 	char *scale_string;
 	char *locale;
+	gboolean is_rtl = (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL);
 
 	g_assert (FM_IS_ICON_VIEW (icon_view));
 	g_assert (container == get_icon_container (icon_view));
@@ -2197,7 +2198,7 @@
 	/* Store the new position of the icon in the metadata. */
 	if (!fm_icon_view_using_auto_layout (icon_view)) {
 		position_string = g_strdup_printf
-			("%d,%d", position->x, position->y);
+			("%d,%d", is_rtl ? nautilus_icon_container_get_x (container, position->x, position->y, 0) : position->x, position->y);
 		nautilus_file_set_metadata
 			(file, NAUTILUS_METADATA_KEY_ICON_POSITION, 
 			 NULL, position_string);
Index: src/file-manager/fm-desktop-icon-view.c
===================================================================
--- src/file-manager/fm-desktop-icon-view.c	(revision 12868)
+++ src/file-manager/fm-desktop-icon-view.c	(working copy)
@@ -522,6 +522,7 @@
 	NautilusIconContainer *icon_container;
 	GtkAllocation *allocation;
 	GtkAdjustment *hadj, *vadj;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(get_icon_container(desktop_icon_view))) == GTK_TEXT_DIR_RTL;
 
 	if (desktop_directory == NULL) {
 		eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR,
@@ -568,6 +569,8 @@
 	
 	/* Set our default layout mode */
 	nautilus_icon_container_set_layout_mode (icon_container,
+						 is_rtl ? 
+						 NAUTILUS_ICON_LAYOUT_T_B_R_L :
 						 NAUTILUS_ICON_LAYOUT_T_B_L_R);
 
 	g_signal_connect_object (icon_container, "middle_click",
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 12868)
+++ ChangeLog	(working copy)
@@ -1,3 +1,42 @@
+2007-04-16  Suresh Chandrasekharan <suresh.chandrasekharan@sun.com>
+	Fix for Bug 342009 – nautilus icon arrangement in RTL mode
+
+	* src/file-manager/fm-icon-view.c (icon_position_changed_callback)
+	  Convert the RTL icon position to LTR before saving.
+	* src/file-manager/fm-desktop-icon-view.c (fm_desktop_icon_view_init)
+	  Set the default icon view mode to NAUTILUS_ICON_LAYOUT_T_B_R_L
+	  for RTL mode.
+	* libnautilus-private/nautilus-icon-container.c 
+	  (nautilus_icon_container_update_scroll_region) Move scrollbar to 
+	  right if displayed.
+	  (lay_down_one_line) Enable setting icons in RTL mode for a line
+	  (find_empty_location) Changes for finding out empty position to 
+	  place icon in RTL mode.
+	  (nautilus_icon_container_get_x) New function defined to get
+	  RTL/LTR icons x positions as needed.
+	  (safe_x_y) New static function for trimming down the x/y values
+	  within boundaries.
+	  (x_compare_func) New sort function for icon list sort.
+	  (nautilus_icon_container_get_rtl) New function to convert the RTL
+	  positions from LTR positions read from the .xml positions file
+	  (lay_down_icons_tb) Renamed lay_down_icons_tblr. New code to
+	  get the rtl_x positions.
+	  (lay_down_icons) Add NAUTILUS_ICON_LAYOUT_R_L_T_B, change
+	  lay_down_icons_tblr to lay_down_icons_tb.
+	  (set_rtl_icon_positions) Get the RTL x position from LTR x position
+	  for an icon to display the icon in RTL mode.
+	  (redo_layout_internal) Calculate the RTL icon positions from the
+	  LTR positions read from the the xml position files under 
+	  ~/.nautilus/metafiles and redisplay icons.
+	  (reload_icon_positions) When re-reading from xml positions file,
+	  calculate RTL positions if we are in RTL locale.
+	  (finish_adding_new_icons) Set the new icons flag if all the desktop
+	  icons are new. Make the function return the flag.
+
+	* libnautilus-private/nautilus-icon-container.h: Added 
+	  NAUTILUS_ICON_LAYOUT_R_L_T_B and declaration for 
+	  nautilus_icon_container_get_x
+
 2007-04-11  Alexander Larsson  <alexl@redhat.com>
 
         * src/file-manager/fm-directory-view.c:
Index: libnautilus-private/nautilus-icon-container.c
===================================================================
--- libnautilus-private/nautilus-icon-container.c	(revision 12868)
+++ libnautilus-private/nautilus-icon-container.c	(working copy)
@@ -146,6 +146,7 @@
 #define SNAP_NEAREST_HORIZONTAL(x) SNAP_HORIZONTAL (eel_round, x)
 #define SNAP_NEAREST_VERTICAL(y) SNAP_VERTICAL (eel_round, y)
 
+#define SNAP_FLOOR_HORIZONTAL(x) SNAP_HORIZONTAL (floor, x)
 #define SNAP_CEIL_HORIZONTAL(x) SNAP_HORIZONTAL (ceil, x)
 #define SNAP_CEIL_VERTICAL(y) SNAP_VERTICAL (ceil, y)
 
@@ -163,6 +164,12 @@
 	char *action_descriptions[LAST_ACTION];
 } NautilusIconContainerAccessiblePrivate;
 
+typedef struct {
+	int ltr_x;
+	int rtl_x;
+	int y;
+} ltrx_rtlx_y;
+
 static GType         nautilus_icon_container_accessible_get_type (void);
 
 static void          activate_selected_items                        (NautilusIconContainer *container);
@@ -182,7 +189,7 @@
 static void          end_renaming_mode                              (NautilusIconContainer *container,
 								     gboolean               commit);
 static NautilusIcon *get_icon_being_renamed                         (NautilusIconContainer *container);
-static void          finish_adding_new_icons                        (NautilusIconContainer *container);
+static  gboolean     finish_adding_new_icons                        (NautilusIconContainer *container);
 static void          update_label_color                             (EelBackground         *background,
 								     NautilusIconContainer *icon_container);
 static void          icon_get_bounding_box                          (NautilusIcon          *icon,
@@ -206,6 +213,8 @@
 static void          nautilus_icon_container_update_visible_icons   (NautilusIconContainer *container);
 static void          reveal_icon                                    (NautilusIconContainer *container,
 								     NautilusIcon *icon);
+static int item_event_callback (EelCanvasItem *item, GdkEvent *event, gpointer data);
+static void finish_adding_icon (NautilusIconContainer *container, NautilusIcon *icon);
 
 
 static gpointer accessible_parent_class;
@@ -810,6 +819,7 @@
 	float step_increment;
 	GtkAllocation *allocation;
 	gboolean reset_scroll_region;
+	gboolean is_rtl = (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL);
 
 	if (nautilus_icon_container_get_is_fixed_size (container)) {
 		pixels_per_unit = EEL_CANVAS (container)->pixels_per_unit;
@@ -887,6 +897,14 @@
 	 */
 	eel_gtk_adjustment_clamp_value (hadj);
 	eel_gtk_adjustment_clamp_value (vadj);
+
+	/*
+	 * For RTL move the scrollbar to right
+	 */
+
+	if (is_rtl) {
+		gtk_adjustment_set_value (hadj, hadj->upper - hadj->page_size);
+	}
 }
 
 static int
@@ -951,11 +969,14 @@
 	double x, y_offset;
 	IconPositions *position;
 	int i;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
+	double canvas_width = (GTK_WIDGET (container)->allocation.width
+			- container->details->left_margin
+			- container->details->right_margin)
+			/ EEL_CANVAS (container)->pixels_per_unit;
 
-	/* FIXME: Should layout differently when in RTL base mode */
-
 	/* Lay out the icons along the baseline. */
-	x = ICON_PAD_LEFT;
+	x = is_rtl ? canvas_width : ICON_PAD_LEFT;
 	i = 0;
 	for (p = line_start; p != line_end; p = p->next) {
 		icon = p->data;
@@ -968,12 +989,13 @@
 			y_offset = position->y_offset;
 		}
 
-		icon_set_position
-			(icon,
-			 x + position->x_offset,
-			 y + y_offset);
+		if (is_rtl)
+			x -= position->width;
 
-		x += position->width;
+		icon_set_position (icon, x + position->x_offset, y + y_offset);
+
+		if (!is_rtl)
+			x += position->width;
 	}
 }
 
@@ -1341,6 +1363,7 @@
 	ArtIRect icon_position;
 	ArtDRect pixbuf_rect;
 	gboolean collision;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
 
 	/* Get container dimensions */
 	canvas_width  = (GTK_WIDGET (container)->allocation.width
@@ -1380,7 +1403,7 @@
 		if (!placement_grid_position_is_free (grid, grid_position)) {
 			icon_position.y0 += SNAP_SIZE_Y;
 			icon_position.y1 = icon_position.y0 + icon_height;
-			
+
 			if (icon_position.y1 + DESKTOP_PAD_VERTICAL > canvas_height) {
 				/* Move to the next column */
 				icon_position.y0 = DESKTOP_PAD_VERTICAL + SNAP_SIZE_Y - (pixbuf_rect.y1 - pixbuf_rect.y0);
@@ -1389,13 +1412,13 @@
 				}
 				icon_position.y1 = icon_position.y0 + icon_height;
 				
-				icon_position.x0 += SNAP_SIZE_X;
+				icon_position.x0 = is_rtl ? icon_position.x0 - SNAP_SIZE_X : icon_position.x0 + SNAP_SIZE_X;
 				icon_position.x1 = icon_position.x0 + icon_width;
 			}
 				
 			collision = TRUE;
 		}
-	} while (collision && (icon_position.x1 < canvas_width));
+	} while (collision && (icon_position.x1 < canvas_width && icon_position.x0 > 0));
 
 	*x = icon_position.x0;
 	*y = icon_position.y0;
@@ -1440,15 +1463,161 @@
 	placement_grid_free (grid);
 }
 
+static GArray *result = NULL;
+
+int
+nautilus_icon_container_get_x (NautilusIconContainer *container,
+					int x, int y, int rtl_flag) {
+
+	int i, total = g_list_length (container->details->icons);
+
+	if (result == NULL)
+		return x;
+
+	for (i=0; i<total; i++) {
+		if (!rtl_flag && g_array_index (result, ltrx_rtlx_y, i).rtl_x == x
+			      && g_array_index (result, ltrx_rtlx_y, i).y == y)
+			return g_array_index (result, ltrx_rtlx_y, i).ltr_x;
+
+		else if (rtl_flag && g_array_index (result, ltrx_rtlx_y, i).ltr_x == x
+			      && g_array_index (result, ltrx_rtlx_y, i).y == y)
+			return g_array_index (result, ltrx_rtlx_y, i).rtl_x;
+	}
+	return x;
+}
+
 static void
-lay_down_icons_tblr (NautilusIconContainer *container, GList *icons)
+safe_x_y (int width, int height, int x, int y, int *x_ret, int *y_ret) {
+				
+	if (x > width - DESKTOP_ICON_SAFETY_PAD) {
+		*x_ret = width - DESKTOP_ICON_SAFETY_PAD;
+	}
+	
+	if (x < 0) {
+		*x_ret = 0;
+	}
+
+	if (y > height - DESKTOP_ICON_SAFETY_PAD) {
+		*y_ret = height - DESKTOP_ICON_SAFETY_PAD;
+	}
+
+	if (y < 0) {
+		*y_ret = 0;
+	}		
+}
+
+static int
+x_compare_func (gconstpointer  a, gconstpointer  b)
 {
+	NautilusIcon *aa, *bb; 
+	aa = (NautilusIcon *)a;
+	bb = (NautilusIcon *)b;
+
+	if (aa->x > bb->x) return 1;
+	else if (aa->x < bb->x) return -1;
+	else if (aa->x == bb->x) {
+		if (aa->y > bb->y) return 1;
+		else if (aa->y < bb->y) return -1;
+		else return 0;
+	}
+}
+
+gboolean
+nautilus_icon_container_get_rtl (NautilusIconContainer *container, GList *icons)
+{
+	GList *p, *placed_icons, *unplaced_icons, *l, *srt;
+	NautilusIcon *icon;
+	ArtDRect icon_rect;
+	PlacementGrid *grid;
+	int width, max_width, rtl_column_width, icon_width, index = 0;
+	int x, rtl_x, y, x1, x2, y1, y2;
+	int startx, j;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
+
+	/* Get container width */
+	width  = GTK_WIDGET (container)->allocation.width /
+		EEL_CANVAS (container)->pixels_per_unit
+		- container->details->left_margin
+		- container->details->right_margin;
+
+	srt = g_list_copy (container->details->icons);
+	srt = g_list_sort (srt, x_compare_func);
+
+	icon = srt->data;
+	startx = icon->x;
+	rtl_x = width - DESKTOP_PAD_HORIZONTAL;
+
+	if (result) {
+		g_warning("result != NULL");
+		g_array_free (result, TRUE);
+	}
+
+	result = g_array_new (FALSE, TRUE, sizeof (ltrx_rtlx_y));
+	result = g_array_set_size (result, g_list_length (container->details->icons));
+
+	while (srt != NULL) {
+		max_width = 0;
+		j = 0;
+
+		for (l = srt; l != NULL; l = l->next) {
+			icon = l->data;
+			icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
+			icon_width = x2 - x1;
+
+			if (j++ !=0 && icon->x > (startx + DESKTOP_PAD_HORIZONTAL + SNAP_SIZE_X/2)) {
+				break;
+			}
+
+			if (startx < icon->x) {
+				startx = icon->x;
+			}
+
+			if (max_width < icon_width) {
+				max_width = icon_width;
+			}
+		}
+
+		rtl_column_width = max_width;
+
+		for (l = srt; l != NULL; l = l->next) {
+			int rtl_center_x;
+			icon = l->data;
+			icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
+			icon_width = x2 - x1;
+
+			if (icon->x > startx) {
+				rtl_x = rtl_x - ( rtl_column_width + DESKTOP_PAD_HORIZONTAL );
+				break;
+			}
+			x = icon->x;
+			y = icon->y;
+
+			rtl_center_x = SNAP_FLOOR_HORIZONTAL (rtl_x -  max_width / 2);
+			icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
+			rtl_column_width = rtl_x - rtl_center_x + max_width / 2;
+
+			g_array_index (result, ltrx_rtlx_y, index).ltr_x = x;
+			g_array_index (result, ltrx_rtlx_y, index).rtl_x = rtl_center_x - (icon_rect.x1 - icon_rect.x0) / 2;
+			g_array_index (result, ltrx_rtlx_y, index).y = y;
+			index++;
+		}
+		srt = l;
+	}
+
+	return 1;
+}
+
+static void
+lay_down_icons_tb (NautilusIconContainer *container, GList *icons)
+{
 	GList *p, *placed_icons, *unplaced_icons;
 	int total, new_length, placed;
 	NautilusIcon *icon;
 	int width, height, max_width, column_width, icon_width, icon_height;
 	int x, y, x1, x2, y1, y2;
+	int rtl_x, rtl_y, rtl_column_width, place_x, rtl_place_x, index = 0;
 	ArtDRect icon_rect;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
 
 	/* Get container dimensions */
 	width  = GTK_WIDGET (container)->allocation.width /
@@ -1467,6 +1636,8 @@
 	total = g_list_length (container->details->icons);
 	new_length = g_list_length (icons);
 	placed = total - new_length;
+	if (!result)
+		result = g_array_new (FALSE, TRUE, sizeof (ltrx_rtlx_y));
 	if (placed > 0) {
 		PlacementGrid *grid;
 		/* Add only placed icons in list */
@@ -1493,22 +1664,52 @@
 			
 			/* Place unplaced icons in the best locations */
 			for (p = unplaced_icons; p != NULL; p = p->next) {
+				ltrx_rtlx_y elem;
+
 				icon = p->data;
 				
 				icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
+				icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
+				icon_width = x2 - x1;
 				
 				/* Start the icon in the first column */
 				x = DESKTOP_PAD_HORIZONTAL + (SNAP_SIZE_X / 2) - ((icon_rect.x1 - icon_rect.x0) / 2);
-				y = DESKTOP_PAD_VERTICAL + SNAP_SIZE_Y - (icon_rect.y1 - icon_rect.y0);
+				if (is_rtl)
+					rtl_x = width - (DESKTOP_PAD_HORIZONTAL + (SNAP_SIZE_X / 2) - ((icon_rect.x1 - icon_rect.x0) / 2)) - icon_width;
+				rtl_y = y = DESKTOP_PAD_VERTICAL + SNAP_SIZE_Y - (icon_rect.y1 - icon_rect.y0);
+				if (is_rtl) {
+					find_empty_location (container,
+						     grid,
+						     icon,
+						     rtl_x, rtl_y,
+						     &rtl_x, &rtl_y);
 
-				find_empty_location (container,
+					safe_x_y (width, height, rtl_x, rtl_y, &rtl_x, &rtl_y);
+					x = width - rtl_x - icon_width;
+				} else {
+
+					find_empty_location (container,
 						     grid,
 						     icon,
 						     x, y,
 						     &x, &y);
-				
-				icon_set_position (icon, x, y);
+					safe_x_y (width, height, x, y, &x, &y);
+				}
+
+				icon_set_position (icon, is_rtl ? 
+							 rtl_x : x, 
+							 is_rtl ?
+							 rtl_y : y);
+
 				placement_grid_mark_icon (grid, icon);
+
+				if (is_rtl) {
+					elem.ltr_x = x;
+					elem.rtl_x = rtl_x;
+					elem.y = y;
+				}
+
+				g_array_append_val (result, elem);
 			}
 
 			placement_grid_free (grid);
@@ -1519,9 +1720,18 @@
 	} else {
 		/* There are no placed icons.  Just lay them down using our rules */		
 		x = DESKTOP_PAD_HORIZONTAL;
+		if (is_rtl) {
+			rtl_x = width - DESKTOP_PAD_HORIZONTAL;
 
+			if (result) 
+				g_array_free (result, TRUE);
+
+			result = g_array_new (FALSE, TRUE, sizeof (ltrx_rtlx_y));
+			result = g_array_set_size (result, g_list_length (container->details->icons));
+		}
+
 		while (icons != NULL) {
-			int center_x;
+			int center_x, rtl_center_x;
 			int baseline;
 			gboolean should_snap;
 			
@@ -1563,10 +1773,21 @@
 
 			center_x = x + max_width / 2;
 			column_width = max_width;
+
+			if (is_rtl) {
+				rtl_center_x = rtl_x - max_width / 2;
+				rtl_column_width = max_width;
+			}
+
 			if (should_snap) {
 				/* Find the grid column to center on */
 				center_x = SNAP_CEIL_HORIZONTAL (center_x);
 				column_width = (center_x - x) + (max_width / 2);
+
+				if (is_rtl) {
+					rtl_center_x = SNAP_FLOOR_HORIZONTAL (rtl_center_x);
+					rtl_column_width = rtl_x - rtl_center_x + max_width/2;
+				}
 			}
 			
 			/* Lay out column */
@@ -1589,11 +1810,25 @@
 				    /* Make sure we lay out at least one icon per column, to make progress */
 				    p != icons) {
 					x += column_width + DESKTOP_PAD_HORIZONTAL;
+					if (is_rtl)
+						rtl_x = rtl_x - ( rtl_column_width + DESKTOP_PAD_HORIZONTAL );
 					break;
 				}
 				
+				place_x = center_x - (icon_rect.x1 - icon_rect.x0) / 2,
+				safe_x_y (width, height, place_x, y, &place_x, &y);
+				if (is_rtl) {
+					rtl_place_x = rtl_center_x - (icon_rect.x1 - icon_rect.x0) / 2;
+					safe_x_y (width, height, rtl_place_x, y, &rtl_place_x, &y);
+
+					g_array_index (result, ltrx_rtlx_y, index).ltr_x = place_x;
+					g_array_index (result, ltrx_rtlx_y, index).rtl_x = rtl_place_x;
+					g_array_index (result, ltrx_rtlx_y, index).y = y;
+					index++;
+				}
+
 				icon_set_position (icon,
-						   center_x - (icon_rect.x1 - icon_rect.x0) / 2,
+						   is_rtl ? rtl_place_x : place_x,
 						   y);
 				
 				y += icon_height + DESKTOP_PAD_VERTICAL;
@@ -1602,43 +1837,73 @@
 		}
 	}
 
-	/* These modes are special. We freeze all of our positions
-	 * after we do the layout.
-	 */
-	/* FIXME bugzilla.gnome.org 42478: 
-	 * This should not be tied to the direction of layout.
-	 * It should be a separate switch.
-	 */
 	nautilus_icon_container_freeze_icon_positions (container);
 }
 
-
 static void
 lay_down_icons (NautilusIconContainer *container, GList *icons, double start_y)
 {
 	switch (container->details->layout_mode)
 	{
 	case NAUTILUS_ICON_LAYOUT_L_R_T_B:
+	case NAUTILUS_ICON_LAYOUT_R_L_T_B:
 		lay_down_icons_horizontal (container, icons, start_y);
 		break;
 		
 	case NAUTILUS_ICON_LAYOUT_T_B_L_R:
 	case NAUTILUS_ICON_LAYOUT_T_B_R_L:
-		/* FIXME bugzilla.gnome.org 42479: 
-		 * Need to handle T_B_R_L differently. */
-		lay_down_icons_tblr (container, icons);
+		lay_down_icons_tb (container, icons);
 		break;
-		
 	default:
 		g_assert_not_reached ();
 	}
 }
 
 static void
+set_rtl_icon_positions (NautilusIconContainer *container)
+{
+	GList *p, *icons;
+	NautilusIcon *icon;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
+	
+	p = container->details->icons;
+	if (!p)
+		return;	
+
+	/* Position most icons (not unpositioned manual-layout icons). */
+	for (; p != NULL; p = p->next) {
+		gboolean have_stored_position;
+		NautilusIconPosition position;
+		icon = p->data;
+
+		/* Get the stored position. */
+		have_stored_position = FALSE;
+		position.scale = 1.0;
+		g_signal_emit (container,
+				 signals[GET_STORED_ICON_POSITION], 0,
+				 icon->data,
+				 &position,
+				 &have_stored_position);
+		icon->scale = position.scale;
+		if (have_stored_position) {
+			position.x = nautilus_icon_container_get_x (container, position.x, position.y, 1);
+			icon_set_position (icon, position.x, position.y);
+		}
+	}
+}
+static void
 redo_layout_internal (NautilusIconContainer *container)
 {
-	finish_adding_new_icons (container);
 
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
+	gboolean new_icon_flg = 0;
+
+	new_icon_flg = finish_adding_new_icons (container);
+	if (is_rtl && new_icon_flg && !container->details->auto_layout) {
+		if (nautilus_icon_container_get_rtl (container, container->details->new_icons))
+			set_rtl_icon_positions (container);
+	}
+
 	/* Don't do any re-laying-out during stretching. Later we
 	 * might add smart logic that does this and leaves room for
 	 * the stretched icon, but if we do it we want it to be fast
@@ -1705,6 +1970,7 @@
 	ArtDRect bounds;
 	double bottom;
 	EelCanvasItem *item;
+	gboolean is_rtl = gtk_widget_get_direction (GTK_WIDGET(container)) == GTK_TEXT_DIR_RTL;
 
 	g_assert (!container->details->auto_layout);
 
@@ -1724,6 +1990,8 @@
 				 &position,
 				 &have_stored_position);
 		if (have_stored_position) {
+			if (is_rtl)
+				position.x = nautilus_icon_container_get_x (container, position.x, position.y, 1);
 			icon_set_position (icon, position.x, position.y);
 			item = EEL_CANVAS_ITEM (icon->item);
 			eel_canvas_item_get_bounds (item,
@@ -5845,18 +6113,25 @@
 	g_signal_emit (container, signals[ICON_ADDED], 0, icon->data);
 }
 
-static void
+static gboolean
 finish_adding_new_icons (NautilusIconContainer *container)
 {
 	GList *p, *new_icons, *no_position_icons, *semi_position_icons;
 	NautilusIcon *icon;
 	double bottom;
+	gboolean ret =  0;
 
 	new_icons = container->details->new_icons;
 	container->details->new_icons = NULL;
 
 	/* Position most icons (not unpositioned manual-layout icons). */
 	new_icons = g_list_reverse (new_icons);
+
+	/* All the desktop icons to be displayed are new */
+	if (new_icons != NULL) {
+		ret = (g_list_length (container->details->icons) == g_list_length (new_icons));
+	}
+
 	no_position_icons = semi_position_icons = NULL;
 	for (p = new_icons; p != NULL; p = p->next) {
 		icon = p->data;
@@ -5880,7 +6155,7 @@
 		semi_position_icons = g_list_reverse (semi_position_icons);
 
 		/* This is currently only used on the desktop.
-		 * Thus, we pass FALSE for tight, like lay_down_icons_tblr */
+		 * Thus, we pass FALSE for tight, like lay_down_icons_tb */
 		grid = placement_grid_new (container, FALSE);
 
 		for (p = container->details->icons; p != NULL; p = p->next) {
@@ -5925,6 +6200,7 @@
 		lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM);
 		g_list_free (no_position_icons);
 	}
+	return ret;
 }
 
 /**
Index: libnautilus-private/nautilus-icon-container.h
===================================================================
--- libnautilus-private/nautilus-icon-container.h	(revision 12868)
+++ libnautilus-private/nautilus-icon-container.h	(working copy)
@@ -56,6 +56,7 @@
 
 typedef enum {
 	NAUTILUS_ICON_LAYOUT_L_R_T_B,
+	NAUTILUS_ICON_LAYOUT_R_L_T_B,
 	NAUTILUS_ICON_LAYOUT_T_B_L_R,
 	NAUTILUS_ICON_LAYOUT_T_B_R_L
 } NautilusIconLayoutMode;
@@ -299,4 +300,5 @@
 void              nautilus_icon_container_set_allow_moves               (NautilusIconContainer  *container,
 									 gboolean                allow_moves);
 
+int               nautilus_icon_container_get_x               	(NautilusIconContainer *container, int x, int y, int rtl_flag);
 #endif /* NAUTILUS_ICON_CONTAINER_H */
