diff --git a/cursive-core/src/views/fixed_layout.rs b/cursive-core/src/views/fixed_layout.rs index def2c9a..05f5183 100644 --- a/cursive-core/src/views/fixed_layout.rs +++ b/cursive-core/src/views/fixed_layout.rs @@ -140,6 +140,21 @@ impl FixedLayout { } } + fn circular_mut<'a>( + start: usize, + children: &'a mut [Child], + ) -> impl Iterator + 'a { + let (head, tail) = children.split_at_mut(start); + + let head = head.iter_mut().enumerate(); + let tail = tail + .iter_mut() + .enumerate() + .map(move |(i, c)| (i + start, c)); + + tail.chain(head) + } + fn move_focus_rel(&mut self, target: Relative) -> EventResult { let source = Direction::Rel(target.swap()); for (i, c) in @@ -229,7 +244,6 @@ impl View for FixedLayout { } fn on_event(&mut self, event: Event) -> EventResult { - eprintln!("Self focus: {:?}", self.focus); if self.is_empty() { return EventResult::Ignored; } @@ -275,13 +289,17 @@ impl View for FixedLayout { } fn take_focus(&mut self, source: Direction) -> bool { - // TODO: what if source = None? - eprintln!("Self focus: {:?}", self.focus); match source { Direction::Abs(Absolute::None) => { - // For now, take focus if any view is focusable. - for child in &mut self.children { - if child.view.take_focus(source) { + // We want to guarantee: + // * If the current focus _is_ focusable, keep it + // * If it isn't, find _any_ focusable view, and focus it + // * Otherwise, we can't take focus. + for (i, c) in + Self::circular_mut(self.focus, &mut self.children) + { + if c.view.take_focus(source) { + self.focus = i; return true; } } diff --git a/cursive-core/src/views/stack_view.rs b/cursive-core/src/views/stack_view.rs index 5235c55..cb99c29 100644 --- a/cursive-core/src/views/stack_view.rs +++ b/cursive-core/src/views/stack_view.rs @@ -648,7 +648,7 @@ impl View for StackView { // The text view takes focus because it's scrolling, but it only // knows that after a call to `layout()`. if layer.virgin { - layer.view.take_focus(Direction::front()); + layer.view.take_focus(Direction::none()); layer.virgin = false; } }