*** gui/Source/NSView.m	2002-10-27 14:16:00.000000000 +0100
--- gui/Source/NSView.m.new	2002-10-27 14:20:58.000000000 +0100
***************
*** 115,120 ****
--- 115,227 ----
    
  @implementation NSView
  
+ #define GS_BREADTH_FIRST_VALID_KEY_VIEWS
+ #ifdef GS_BREADTH_FIRST_VALID_KEY_VIEWS
+ /* breadth first search in a graph of views ... */
+ /* ... until one is found that acceptsFirstResponder */
+ 
+ typedef struct _edge_q edge_q;
+ struct _edge_q
+ {
+   edge_q   *prev;
+   edge_q   *next;
+   NSView   *from; // do I really need this ?
+   unsigned  index;
+   GSIArray  to;
+ };
+ 
+ static void enqueue(edge_q *queue, NSView *node, BOOL previous)
+ {
+   GSIArray  to;
+   edge_q   *qelt;
+ 
+   to = previous ? pKV(node) : nKV(node);
+ 
+   if (to && GSIArrayCount(to))
+   {
+     qelt = malloc(sizeof(edge_q));
+     qelt->next = queue;
+     qelt->prev = queue->prev;
+     qelt->next->prev = qelt;
+     qelt->prev->next = qelt;
+     qelt->from = RETAIN(node);
+     qelt->index = 0;
+     qelt->to = to;
+   }
+ }
+ 
+ static void dequeue(edge_q *queue)
+ {
+   edge_q *qelt;
+ 
+   qelt = queue->next;
+   qelt->next->prev = qelt->prev;
+   qelt->prev->next = qelt->next;
+   RELEASE(qelt->from);
+   free(qelt);
+ }
+ 
+ static inline BOOL is_queue_empty(edge_q *queue)
+ {
+   return queue == queue->next;
+ }
+ 
+ static NSView *bfs(NSView *start, BOOL previous)
+ {
+   NSMutableSet  *visited;
+   NSView        *to;
+   edge_q        *qelt;
+   edge_q         queue[1];
+ 
+   visited = [[NSMutableSet alloc] initWithObjects:start, nil];
+ 
+   // dummy queue element
+   queue->prev = queue; // tail
+   queue->next = queue; // head
+   queue->from = nil;
+   queue->index = 0;
+   queue->to = 0;
+ 
+   enqueue(queue, start, previous);
+ 
+   while (!is_queue_empty(queue))
+     {
+       qelt = queue->next;
+ 
+       if (qelt->index >= GSIArrayCount(qelt->to))
+         {
+           dequeue(queue);
+         }
+       else
+         {
+           to = GSIArrayItemAtIndex(qelt->to, qelt->index).obj;
+           qelt->index += 1;
+ 
+           if (![visited containsObject:to])
+             {
+               if ([to acceptsFirstResponder])
+                 {
+                   while (!is_queue_empty(queue))
+                     dequeue(queue);
+     
+                   RELEASE(visited);
+     
+                   return to;
+                 }
+ 
+               [visited addObject:to];
+               enqueue(queue, to, previous);
+             }
+         }
+     }
+ 
+   RELEASE(visited);
+ 
+   return nil;
+ }
+ 
+ #endif
+ 
  /*
   * Class variables */
  static Class	rectClass;
***************
*** 2758,2763 ****
--- 2865,2873 ----
   */
  - (NSView *) nextValidKeyView
  {
+ #ifdef GS_BREADTH_FIRST_VALID_KEY_VIEWS
+   return bfs(self, NO);
+ #else
    NSView *theView;
  
    theView = [self nextKeyView];
***************
*** 2770,2775 ****
--- 2880,2886 ----
  	}
        theView = [theView nextKeyView];
      }
+ #endif
  }
  
  /**
***************
*** 2813,2818 ****
--- 2924,2932 ----
   */
  - (NSView *) previousValidKeyView
  {
+ #ifdef GS_BREADTH_FIRST_VALID_KEY_VIEWS
+   return bfs(self, YES);
+ #else
    NSView *theView;
  
    theView = [self previousKeyView];
***************
*** 2825,2830 ****
--- 2939,2945 ----
  	}
        theView = [theView previousKeyView];
      }
+ #endif
  }
  
  /*
