From ef325d5161083badb5c9b0ff74a492b35a6165b0 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Wed, 15 Mar 2023 17:08:43 -0400 Subject: [PATCH] Found a flaw in the focusing model, rectifying. Still need to fix on X backend window, that will be in the next commit. --- elements/container.go | 10 +++++++++- elements/core/propagator.go | 37 +++++++++++++++++++++++++++++++++++++ elements/core/selectable.go | 3 +-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/elements/container.go b/elements/container.go index 1001e7c..ec09d8a 100644 --- a/elements/container.go +++ b/elements/container.go @@ -18,7 +18,15 @@ type FocusableParent interface { // keyboard focus. If the parent grants the request, the method will // return true and the child element should behave as if a HandleFocus // call was made. - RequestFocus (child Focusable, direction input.KeynavDirection) (granted bool) + RequestFocus (child Focusable) (granted bool) + + // RequestFocusMotion notifies the parent that a child element wants the + // focus to be moved to the next focusable element. + RequestFocusNext (child Focusable) + + // RequestFocusMotion notifies the parent that a child element wants the + // focus to be moved to the previous focusable element. + RequestFocusPrevious (child Focusable) } // FlexibleParent represents a parent that accounts for elements with diff --git a/elements/core/propagator.go b/elements/core/propagator.go index 33ba869..76284d6 100644 --- a/elements/core/propagator.go +++ b/elements/core/propagator.go @@ -122,6 +122,43 @@ func (propagator *Propagator) HandleFocus (direction input.KeynavDirection) (acc return false } +// RequestFocus notifies the parent that a child element is requesting +// keyboard focus. If the parent grants the request, the method will +// return true and the child element should behave as if a HandleFocus +// call was made. +func (propagator *Propagator) RequestFocus ( + child elements.Focusable, +) ( + granted bool, +) { + // TODO implement this, and also implement it for the x backend window + if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok { + if parent.RequestFocus(propagator) { + propagator.focused = true + granted = true + } + } + return +} + +// RequestFocusMotion notifies the parent that a child element wants the +// focus to be moved to the next focusable element. +func (propagator *Propagator) RequestFocusNext (child elements.Focusable) { + if !propagator.focused { return } + if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok { + parent.RequestFocusNext(propagator) + } +} + +// RequestFocusMotion notifies the parent that a child element wants the +// focus to be moved to the previous focusable element. +func (propagator *Propagator) RequestFocusPrevious (child elements.Focusable) { + if !propagator.focused { return } + if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok { + parent.RequestFocusPrevious(propagator) + } +} + // HandleDeselection causes this element to mark itself and all of its children // as unfocused. func (propagator *Propagator) HandleUnfocus () { diff --git a/elements/core/selectable.go b/elements/core/selectable.go index c8fc30e..903841a 100644 --- a/elements/core/selectable.go +++ b/elements/core/selectable.go @@ -44,8 +44,7 @@ func (core *FocusableCore) Focus () { parent := core.core.Parent() if parent, ok := parent.(elements.FocusableParent); ok && parent != nil { core.focused = parent.RequestFocus ( - core.core.Outer().(elements.Focusable), - input.KeynavDirectionNeutral) + core.core.Outer().(elements.Focusable)) } }