Index: src/theme.c
===================================================================
--- src/theme.c	(revision 3239)
+++ src/theme.c	(working copy)
@@ -596,14 +596,11 @@
   
   n_left = 0;
   n_right = 0;
-  for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++)
-    {
-      /* NULL all unused */
-      left_func_rects[i] = NULL;
-      right_func_rects[i] = NULL;
 
+  if (!layout->hide_buttons)
+    {
       /* Try to fill in rects */
-      if (button_layout->left_buttons[i] != META_BUTTON_FUNCTION_LAST && !layout->hide_buttons)
+      for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
         {
           left_func_rects[n_left] = rect_for_function (fgeom, flags,
                                                        button_layout->left_buttons[i],
@@ -612,7 +609,7 @@
             ++n_left;
         }
       
-      if (button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST && !layout->hide_buttons)
+      for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
         {
           right_func_rects[n_right] = rect_for_function (fgeom, flags,
                                                          button_layout->right_buttons[i],
Index: src/prefs.c
===================================================================
--- src/prefs.c	(revision 3239)
+++ src/prefs.c	(working copy)
@@ -109,20 +109,7 @@
 static gboolean compositing_manager = FALSE;
 
 static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
-static MetaButtonLayout button_layout = {
-  {
-    META_BUTTON_FUNCTION_MENU,
-    META_BUTTON_FUNCTION_LAST,
-    META_BUTTON_FUNCTION_LAST,
-    META_BUTTON_FUNCTION_LAST
-  },
-  {
-    META_BUTTON_FUNCTION_MINIMIZE,
-    META_BUTTON_FUNCTION_MAXIMIZE,
-    META_BUTTON_FUNCTION_CLOSE,
-    META_BUTTON_FUNCTION_LAST
-  }
-};
+static MetaButtonLayout button_layout;
 
 /* The screenshot commands are at the end */
 static char *commands[MAX_COMMANDS] = { NULL, };
@@ -195,6 +182,7 @@
 static void     init_bindings             (void);
 static void     init_commands             (void);
 static void     init_workspace_names      (void);
+static void     init_button_layout        (void);
 
        
 typedef struct
@@ -530,6 +518,8 @@
    */
   titlebar_font = pango_font_description_from_string ("Sans Bold 10");
   current_theme = g_strdup ("Atlanta");
+  
+  init_button_layout();
 #endif /* HAVE_GCONF */
   
   /* Load keybindings prefs */
@@ -1461,14 +1451,6 @@
   if (value == NULL)
     return FALSE;
   
-  i = 0;
-  while (i < MAX_BUTTONS_PER_CORNER)
-    {
-      new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
-      new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
-      ++i;
-    }
-
   /* We need to ignore unknown button functions, for
    * compat with future versions
    */
@@ -1515,6 +1497,8 @@
           ++b;
         }
 
+      new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
+      
       g_strfreev (buttons);
     }
 
@@ -1558,11 +1542,32 @@
           ++b;
         }
 
+      new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
+      
       g_strfreev (buttons);
     }
 
   g_strfreev (sides);
   
+  /* Invert the button layout for RTL languages */
+  if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
+  {
+    MetaButtonLayout rtl_layout;
+    int j;
+    
+    for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
+    for (j = 0; j < i; j++)
+	  rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
+    rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
+      
+    for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
+    for (j = 0; j < i; j++)
+      rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
+    rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
+
+    new_layout = rtl_layout;
+  }
+  
   changed = !button_layout_equal (&button_layout, &new_layout);
 
   button_layout = new_layout;
@@ -3036,3 +3041,39 @@
 {
   return compositing_manager;
 }
+
+static void
+init_button_layout(void)
+{
+  MetaButtonLayout button_layout_ltr = {
+    {    
+      /* buttons in the group on the left side */
+      META_BUTTON_FUNCTION_MENU,
+      META_BUTTON_FUNCTION_LAST
+    },
+    {
+      /* buttons in the group on the right side */
+      META_BUTTON_FUNCTION_MINIMIZE,
+      META_BUTTON_FUNCTION_MAXIMIZE,
+      META_BUTTON_FUNCTION_CLOSE,
+      META_BUTTON_FUNCTION_LAST
+    }
+  };
+  MetaButtonLayout button_layout_rtl = {
+    {    
+      /* buttons in the group on the left side */
+      META_BUTTON_FUNCTION_CLOSE,
+      META_BUTTON_FUNCTION_MAXIMIZE,
+      META_BUTTON_FUNCTION_MINIMIZE,
+      META_BUTTON_FUNCTION_LAST
+    },
+    {
+      /* buttons in the group on the right side */
+      META_BUTTON_FUNCTION_MENU,
+      META_BUTTON_FUNCTION_LAST
+    }
+  };
+
+  button_layout = meta_ui_get_direction() == META_UI_DIRECTION_LTR ?
+    button_layout_ltr : button_layout_rtl;
+};
Index: src/main.c
===================================================================
--- src/main.c	(revision 3239)
+++ src/main.c	(working copy)
@@ -293,15 +293,16 @@
   
   g_type_init ();
 
+  meta_ui_init (&argc, &argv);  
+
+  /* must be after UI init so we can override GDK handlers */
+  meta_errors_init ();
+
   /* Load prefs */
   meta_prefs_init ();
   meta_prefs_add_listener (prefs_changed_callback, NULL);
 
-  meta_ui_init (&argc, &argv);  
 
-  /* must be after UI init so we can override GDK handlers */
-  meta_errors_init ();
-
 #if 1
   g_log_set_handler (NULL,
                      G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
