Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1245
diff -u -r1.1245 node.module
--- modules/node/node.module	8 Mar 2010 02:41:46 -0000	1.1245
+++ modules/node/node.module	8 Mar 2010 07:07:20 -0000
@@ -255,19 +255,35 @@
  * Implements hook_admin_paths().
  */
 function node_admin_paths() {
-  $paths = array(
-    'node/*/edit' => TRUE,
-    'node/*/delete' => TRUE,
-    'node/*/revisions' => TRUE,
-    'node/*/revisions/*/revert' => TRUE,
-    'node/*/revisions/*/delete' => TRUE,
-    'node/add' => TRUE,
-    'node/add/*' => TRUE,
-  );
+  $paths = array();
+  if (variable_get('node_admin_theme')) {
+    $paths += array(
+      'node/*/edit' => TRUE,
+      'node/*/delete' => TRUE,
+      'node/*/revisions' => TRUE,
+      'node/*/revisions/*/revert' => TRUE,
+      'node/*/revisions/*/delete' => TRUE,
+      'node/add' => TRUE,
+      'node/add/*' => TRUE,
+    );
+  }
   return $paths;
 }
 
 /**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Add the "node_admin_theme" checkbox to the admin theme selection form.
+ */
+function node_form_system_themes_admin_form_alter(&$form, &$form_state) {
+  $form['admin_theme']['node_admin_theme'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use the administration theme when editing or creating content'),
+    '#default_value' => variable_get('node_admin_theme', 0),
+  );
+}
+
+/**
  * Gather a listing of links to nodes.
  *
  * @param $result
@@ -1852,7 +1868,6 @@
     'access callback' => '_node_add_access',
     'weight' => 1,
     'menu_name' => 'management',
-    'theme callback' => '_node_custom_theme',
     'file' => 'node.pages.inc',
   );
   $items['rss.xml'] = array(
@@ -1896,7 +1911,6 @@
     'page arguments' => array(1),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
-    'theme callback' => '_node_custom_theme',
     'weight' => 0,
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
@@ -1908,7 +1922,6 @@
     'page arguments' => array('node_delete_confirm', 1),
     'access callback' => 'node_access',
     'access arguments' => array('delete', 1),
-    'theme callback' => '_node_custom_theme',
     'weight' => 1,
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_INLINE,
@@ -1987,17 +2000,6 @@
 }
 
 /**
- * Theme callback for creating and editing nodes.
- */
-function _node_custom_theme() {
-  // Use the administration theme if the site is configured to use it for
-  // nodes.
-  if (variable_get('node_admin_theme')) {
-    return variable_get('admin_theme');
-  }
-}
-
-/**
  * Implements hook_init().
  */
 function node_init() {
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.381
diff -u -r1.381 menu.inc
--- includes/menu.inc	7 Mar 2010 07:44:18 -0000	1.381
+++ includes/menu.inc	8 Mar 2010 07:07:18 -0000
@@ -1517,22 +1517,22 @@
   // Skip this if the site is offline or being installed or updated, since the
   // menu system may not be correctly initialized then.
   if ($initialize && !_menu_site_is_offline(TRUE) && (!defined('MAINTENANCE_MODE') || (MAINTENANCE_MODE != 'update' && MAINTENANCE_MODE != 'install'))) {
-    // First allow modules to dynamically set a custom theme for the current
-    // page. Since we can only have one, the last module to return a valid
-    // theme takes precedence.
-    $custom_themes = array_filter(module_invoke_all('custom_theme'), 'drupal_theme_access');
-    if (!empty($custom_themes)) {
-      $custom_theme = array_pop($custom_themes);
+    // First check if the current page requires a particular theme.
+    $router_item = menu_get_item();
+    if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && function_exists($router_item['theme_callback'])) {
+      $theme_name = call_user_func_array($router_item['theme_callback'], $router_item['theme_arguments']);
+      if (drupal_theme_access($theme_name)) {
+        $custom_theme = $theme_name;
+      }
     }
-    // Otherwise, execute the theme callback function for the current page, if
-    // there is one, in order to determine the custom theme to set.
+
+    // Otherwise, allow modules to dynamically set a custom theme for the
+    // current page. Since we can only have one, the last module to return a
+    // valid theme takes precedence.
     if (!isset($custom_theme)) {
-      $router_item = menu_get_item();
-      if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && function_exists($router_item['theme_callback'])) {
-        $theme_name = call_user_func_array($router_item['theme_callback'], $router_item['theme_arguments']);
-        if (drupal_theme_access($theme_name)) {
-          $custom_theme = $theme_name;
-        }
+      $custom_themes = array_filter(module_invoke_all('custom_theme'), 'drupal_theme_access');
+      if (!empty($custom_themes)) {
+        $custom_theme = array_pop($custom_themes);
       }
     }
   }
Index: modules/simpletest/tests/menu.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/menu.test,v
retrieving revision 1.28
diff -u -r1.28 menu.test
--- modules/simpletest/tests/menu.test	30 Jan 2010 03:38:22 -0000	1.28
+++ modules/simpletest/tests/menu.test	8 Mar 2010 07:07:20 -0000
@@ -116,26 +116,19 @@
   }
 
   /**
-   * Test that the result of hook_custom_theme() overrides the theme callback.
+   * Test that the theme callback overrides the result of hook_custom_theme().
    */
   function testHookCustomTheme() {
     // Trigger hook_custom_theme() to dynamically request the Stark theme for
     // the requested page.
     variable_set('menu_test_hook_custom_theme_name', 'stark');
+    theme_enable(array('stark'));
 
-    // Request a page whose theme callback returns the Seven theme. Since Stark
-    // is not a currently enabled theme, our above request should be ignored,
-    // and Seven should still be used.
+    // The menu "theme callback" should take precedence over a value set in
+    // hook_custom_theme().
     $this->drupalGet('menu-test/theme-callback/use-admin-theme');
-    $this->assertText('Custom theme: seven. Actual theme: seven.', t('The result of hook_custom_theme() does not override a theme callback when it returns a theme that is not enabled.'));
+    $this->assertText('Custom theme: seven. Actual theme: seven.', t('The result of hook_custom_theme() does not override what was set in a theme callback.'));
     $this->assertRaw('seven/style.css', t("The Seven theme's CSS appears on the page."));
-
-    // Now enable the Stark theme and request the same page as above. This
-    // time, we expect hook_custom_theme() to prevail.
-    theme_enable(array('stark'));
-    $this->drupalGet('menu-test/theme-callback/use-admin-theme');
-    $this->assertText('Custom theme: stark. Actual theme: stark.', t('The result of hook_custom_theme() overrides what was set in a theme callback.'));
-    $this->assertRaw('stark/layout.css', t("The Stark theme's CSS appears on the page."));
   }
 
   /**
Index: modules/overlay/overlay.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay.module,v
retrieving revision 1.11
diff -u -r1.11 overlay.module
--- modules/overlay/overlay.module	7 Mar 2010 06:31:48 -0000	1.11
+++ modules/overlay/overlay.module	8 Mar 2010 07:07:20 -0000
@@ -54,8 +54,6 @@
  * @see overlay_set_mode()
  */
 function overlay_init() {
-  // @todo: custom_theme does not exist anymore.
-  global $custom_theme;
   // Only act if the user has access to administration pages. Other modules can
   // also enable the overlay directly for other uses of the JavaScript.
   if (user_access('access overlay')) {
@@ -71,13 +69,7 @@
       if (!path_is_admin($_GET['q'])) {
         overlay_close_dialog();
       }
-      // If system module did not switch the theme yet (i.e. this is not an
-      // admin page, per se), we should switch the theme here.
-      $admin_theme = variable_get('admin_theme', 0);
-      if ($custom_theme != $admin_theme) {
-        $custom_theme = $admin_theme;
-        drupal_add_css(drupal_get_path('module', 'system') . '/admin.css');
-      }
+
       // Indicate that we are viewing an overlay child page.
       overlay_set_mode('child');
 
Index: modules/overlay/overlay.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay.api.php,v
retrieving revision 1.1
diff -u -r1.1 overlay.api.php
--- modules/overlay/overlay.api.php	2 Dec 2009 07:28:22 -0000	1.1
+++ modules/overlay/overlay.api.php	8 Mar 2010 07:07:20 -0000
@@ -32,13 +32,8 @@
  * within the confines of the overlay.
  */
 function hook_overlay_child_initialize() {
-  // Use a different theme for content administration pages.
-  if (arg(0) == 'admin' && arg(1) == 'content') {
-    if ($theme = variable_get('content_administration_pages_theme', FALSE)) {
-      global $custom_theme;
-      $custom_theme = $theme;
-    }
-  }
+  // Add our custom JavaScript.
+  drupal_add_js(drupal_get_path('module', 'hook') . '/hook-overlay-child.js');
 }
 
 /**
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.411
diff -u -r1.411 block.module
--- modules/block/block.module	7 Mar 2010 23:14:20 -0000	1.411
+++ modules/block/block.module	8 Mar 2010 07:07:18 -0000
@@ -134,8 +134,8 @@
       'type' => MENU_CALLBACK,
       'access callback' => '_block_themes_access',
       'access arguments' => array($theme),
-      'theme callback' => '_block_custom_theme',
-      'theme arguments' => array($key),
+      'theme callback' => 'arg',
+      'theme arguments' => array('4'),
       'file' => 'block.admin.inc',
     );
   }
@@ -150,22 +150,6 @@
 }
 
 /**
- * Theme callback for the block configuration pages.
- *
- * @param $theme
- *   The theme whose blocks are being configured. If not set, the default theme
- *   is assumed.
- * @return
- *   The theme that should be used for the block configuration page, or NULL
- *   to indicate that the default theme should be used.
- */
-function _block_custom_theme($theme = NULL) {
-  // We return exactly what was passed in, to guarantee that the page will
-  // always be displayed using the theme whose blocks are being configured.
-  return $theme;
-}
-
-/**
  * Implements hook_block_info().
  */
 function block_block_info() {
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.898
diff -u -r1.898 system.module
--- modules/system/system.module	8 Mar 2010 02:41:46 -0000	1.898
+++ modules/system/system.module	8 Mar 2010 07:07:23 -0000
@@ -518,8 +518,6 @@
     'page callback' => 'system_main_admin_page',
     'weight' => 9,
     'menu_name' => 'management',
-    'theme callback' => 'variable_get',
-    'theme arguments' => array('admin_theme'),
     'file' => 'system.admin.inc',
   );
   $items['admin/compact'] = array(
@@ -1717,9 +1715,6 @@
  */
 function system_init() {
   // Add the CSS for this module.
-  if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit' || arg(2) == 'delete'))) {
-    drupal_add_css(drupal_get_path('module', 'system') . '/admin.css', array('weight' => CSS_SYSTEM));
-  }
   drupal_add_css(drupal_get_path('module', 'system') . '/system.css', array('weight' => CSS_SYSTEM));
   drupal_add_css(drupal_get_path('module', 'system') . '/system-behavior.css', array('weight' => CSS_SYSTEM));
   drupal_add_css(drupal_get_path('module', 'system') . '/system-menus.css', array('weight' => CSS_SYSTEM));
@@ -1749,6 +1744,16 @@
 }
 
 /**
+ * Implements hook_custom_theme().
+ */
+function system_custom_theme() {
+  if (path_is_admin(current_path())) {
+    drupal_add_css(drupal_get_path('module', 'system') . '/admin.css', array('weight' => CSS_SYSTEM));
+    return variable_get('admin_theme');
+  }
+}
+
+/**
  * Implements hook_form_FORM_ID_alter().
  */
 function system_form_user_profile_form_alter(&$form, &$form_state) {
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.262
diff -u -r1.262 system.admin.inc
--- modules/system/system.admin.inc	7 Mar 2010 07:36:27 -0000	1.262
+++ modules/system/system.admin.inc	8 Mar 2010 07:07:21 -0000
@@ -340,26 +340,17 @@
     '#description' => t('Choose "Default theme" to always use the same theme as the rest of the site.'),
     '#default_value' => variable_get('admin_theme', 0),
   );
-  $form['admin_theme']['node_admin_theme'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use the administration theme when editing or creating content'),
-    '#default_value' => variable_get('node_admin_theme', '0'),
-  );
-  $form['admin_theme']['actions'] = array('#type' => 'container', '#attributes' => array('class' => array('form-actions')));
-  $form['admin_theme']['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save configuration'),
-  );
-  return $form;
+  $form['#submit'][] = 'system_themes_admin_form_submit';
+  return system_settings_form($form);
 }
 
 /**
  * Process system_themes_admin_form form submissions.
  */
 function system_themes_admin_form_submit($form, &$form_state) {
-  drupal_set_message(t('The configuration options have been saved.'));
-  variable_set('admin_theme', $form_state['values']['admin_theme']);
-  variable_set('node_admin_theme', $form_state['values']['node_admin_theme']);
+  // A menu rebuild is needed in case admin paths might be different because
+  // of changed administration theme settings.
+  variable_set('menu_rebuild_needed', TRUE);
 }
 
 /**
