=== modified file 'includes/view.inc'
--- includes/view.inc	2008-04-02 15:17:11 +0000
+++ includes/view.inc	2008-04-02 18:57:51 +0000
@@ -165,12 +165,32 @@ class view extends views_db_object {
   }
 
   /**
+   * Get the first display that is accessible to the user.
+   *
+   * @param $displays
+   *   Either a single display id or an array of display ids.
+   */
+  function choose_display($displays) {
+    if (!is_array($displays)) {
+      return $displays;
+    }
+    foreach ($displays as $display_id) {
+      if (views_access(array($this->name, $display_id))) {
+        return $display_id;
+      }
+    }
+    return 'default';
+  }
+
+  /**
    * Set the display as current.
    *
    * @param $display_id
    *   The id of the display to mark as current.
    */
   function set_display($display_id = NULL) {
+    $display_id = $this->choose_display($display_id);
+
     // If we have not already initialized the display, do so. But be careful.
     if (empty($this->current_display)) {
       $this->init_display();
@@ -604,7 +624,7 @@ class view extends views_db_object {
    * such as a page callback, hook_block, etc.
    */
   function execute_display($display_id = NULL, $args = array()) {
-    if (empty($this->current_display) || $this->current_display != $display_id) {
+    if (empty($this->current_display) || $this->current_display != $this->choose_display($display_id)) {
       if (!$this->set_display($display_id)) {
         return FALSE;
       }
@@ -682,7 +702,7 @@ class view extends views_db_object {
    * Determine if the given user has access to the view. Note that
    * this sets the display handler if it hasn't been.
    */
-  function access($display_id = NULL, $account = NULL) {
+  function access($displays = NULL, $account = NULL) {
     if (!isset($this->current_display)) {
       $this->init_display();
     }
@@ -691,9 +711,18 @@ class view extends views_db_object {
       $account = $GLOBALS['user'];
     }
 
-    if (!empty($this->display[$display_id]->handler)) {
-      return $this->display[$display_id]->handler->access($account);
+    // We can't use choose_display() here because that function
+    // calls this one.
+    $displays = (array)$displays;
+    foreach ($displays as $display_id) {
+      if (!empty($this->display[$display_id]->handler)) {
+        if ($this->display[$display_id]->handler->access($account)) {
+          return TRUE;
+        }
+      }
     }
+
+    return FALSE;
   }
 
   /**

=== modified file 'views.module'
--- views.module	2008-04-02 15:17:11 +0000
+++ views.module	2008-04-02 18:55:41 +0000
@@ -110,18 +110,9 @@ function views_help($path, $arg) {
 
 /**
  * Implementation of hook_menu().
- *
- * This probably needs to actually be hook_menu_alter or something.
  */
 function views_menu() {
   $items = array();
-  foreach (views_get_page_views() as $data) {
-    list($view, $display_id) = $data;
-    $result = $view->execute_hook_menu($display_id);
-    if (is_array($result)) {
-      $items = array_merge($items, $result);
-    }
-  }
   $items['views/ajax'] = array(
     'title' => t('Views'),
     'page callback' => 'views_ajax',
@@ -134,6 +125,38 @@ function views_menu() {
 }
 
 /**
+ * Implementation of hook_menu_alter().
+ */
+function views_menu_alter(&$callbacks) {
+  foreach (views_get_page_views() as $data) {
+    list($view, $display_id) = $data;
+    $result = $view->execute_hook_menu($display_id);
+    if (is_array($result)) {
+      $regex = '#'. preg_replace('#%views_arg#', '%[^/]*', implode('|', array_keys($result))) .'#';
+      $matches = preg_grep($regex, array_keys($callbacks));
+      foreach ($matches as $path) {
+        if (preg_match('#%#', $path) && !preg_match('#%views_arg(/|$)#', $path)) {
+          unset($callbacks[$path]);
+        }
+      }
+      foreach ($result as $path => $item) {
+        if (isset($callbacks[$path])) {
+          $callbacks[$path]['page arguments'][1] = (array)$callbacks[$path]['page arguments'][1];
+          $callbacks[$path]['page arguments'][1][] = $display_id;
+          $callbacks[$path]['access arguments'][0][1] = (array)$callbacks[$path]['access arguments'][0][1];
+          $callbacks[$path]['access arguments'][0][1][] = $display_id;
+          $callbacks[$path]['load arguments'][1] = (array)$callbacks[$path]['load arguments'][1];
+          $callbacks[$path]['load arguments'][1][] = $display_id;
+        }
+        else {
+          $callbacks[$path] = $item;
+        }
+      }
+    }
+  }
+}
+
+/**
  * Helper function for menu loading. This will automatically be
  * called in order to 'load' a views argument; primarily it
  * will be used to perform validation.

