Index: modules/overlay/overlay.css
===================================================================
RCS file: modules/overlay/overlay.css
diff -N modules/overlay/overlay.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/overlay/overlay.css	29 Aug 2010 21:45:56 -0000
@@ -0,0 +1,4 @@
+#disable-overlay {
+  position:absolute;
+  top:-9999px;
+}
Index: modules/overlay/overlay.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay.module,v
retrieving revision 1.30
diff -u -p -r1.30 overlay.module
--- modules/overlay/overlay.module	11 Aug 2010 02:08:09 -0000	1.30
+++ modules/overlay/overlay.module	29 Aug 2010 21:45:57 -0000
@@ -30,6 +30,14 @@ function overlay_menu() {
     'access arguments' => array('access overlay'),
     'type' => MENU_CALLBACK,
   );
+
+  // @todo: maybe expose an overlay toggle rather than just a disable link
+  $items['overlay/disable/%'] = array(
+    'type' => MENU_CALLBACK,
+    'access arguments' => array('access overlay'),
+    'page callback' => 'overlay_user_disable',
+    'page arguments' => array(2),
+  );
   return $items;
 }
 
@@ -257,6 +265,51 @@ function overlay_page_alter(&$page) {
   if (overlay_get_mode() == 'child') {
     // Add the overlay wrapper before the html wrapper.
     array_unshift($page['#theme_wrappers'], 'overlay');
+  } 
+  else {
+    global $user;
+    // Only display link if the user has access to the overlay (mode was not already set or it has been set to true).
+    // @todo: if we only want to show this until a decision has been made change it to !isset($user->data['overlay'])
+    $use_overlay = !isset($user->data['overlay']) || $user->data['overlay'];
+    if ( user_access('access overlay') && $use_overlay ) {
+      // Insert the disable link as far as possible to the top and wrap it in a <div> to keep it similar to "skip-link"
+      $disable_link_html = '<div id="disable-overlay">' . l(t('Disable administrative overlay'), 'overlay/disable/' . drupal_get_token('overlay'), array( 'query' => drupal_get_destination())) . '</div>';
+      $page['page_top']['disable_overview'] = array(
+        '#markup' => $disable_link_html,  
+        '#weight' => -99
+      );
+      // @todo: There must be a better way than include a css file for just one line, but overlay-parent.css is *not* included on admin pages
+      // and otherwise we'd have to put #disable-overlay (like #skip-link) in all themes css files.
+      // Using a class "element-invisible" apparently is not ok (@see http://drupal.org/node/716612#comment-3383342).
+      drupal_add_css( drupal_get_path('module', 'overlay') . '/overlay.css' ) ;
+    }
+  }
+}
+
+/**
+ * Menu callback disabling the overlay and redirecting back to the last page.
+ * If no page/destination was given, this redirects to the user edit page.
+ */
+function overlay_user_disable($token) {
+  if ($token != drupal_get_token('overlay')) {
+    drupal_access_denied();
+  } 
+  else {
+    global $user;
+    if ( $user->data['overlay'] || !isset($user->data['overlay']) )  {
+      if ( user_save( user_load($user->uid), array('data' => array('overlay' => 0))) ) {
+        drupal_set_message(t('The overlay has been disabled.'));
+      }
+      else {
+        drupal_set_message(t('The overlay could not be disabled. Please try again.'), 'warning');
+      }
+    }
+    if (isset($_GET['destination']) && $_GET['destination']) {
+      drupal_goto(drupal_get_destination());
+    } 
+    else {
+      drupal_goto('user/' . $user->uid . '/edit');
+    }
   }
 }
 
