Fix tab navigation bug with static boxes without enabled children.

wxControlContainer::AcceptsFocusFromKeyboard() returned true even if the
control didn't have any currently enabled -- and hence accepting focus --
children. This resulted in strange wxEVT_NAVIGATION_KEY propagation as it
unexpectedly wasn't handled in the control which pretended to accept focus and
instead bubbled up back into the parent, resulting in the focus returning to
the first child of the parent instead of skipping the static box with disabled
children and going to the next enabled child.

Fix this by checking that we have children that can be focused right now and
not only children that are focusable. Notice that this doesn't take care of
calling wxWindow::SetCanFocus() correctly when the children enabled/disabled
state changes so there might still be other problems, notably under wxGTK
where SetCanFocus() does something non-trivial, but it at least improves
things under wxMSW.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74585 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2013-07-23 12:44:29 +00:00
parent be1f902405
commit dee22e3198
2 changed files with 30 additions and 1 deletions

View File

@ -80,7 +80,8 @@ public:
// Returns whether we or one of our children accepts focus.
bool AcceptsFocusRecursively() const
{ return m_acceptsFocusSelf || m_acceptsFocusChildren; }
{ return m_acceptsFocusSelf ||
(m_acceptsFocusChildren && HasAnyChildrenAcceptingFocus()); }
// We accept focus from keyboard if we accept it at all.
bool AcceptsFocusFromKeyboard() const { return AcceptsFocusRecursively(); }
@ -97,6 +98,10 @@ protected:
// return true if we have any children accepting focus
bool HasAnyFocusableChildren() const;
// return true if we have any children that do accept focus right now
bool HasAnyChildrenAcceptingFocus() const;
// the parent window we manage the children for
wxWindow *m_winParent;

View File

@ -81,6 +81,30 @@ bool wxControlContainerBase::HasAnyFocusableChildren() const
if ( !m_winParent->IsClientAreaChild(child) )
continue;
// Here we check whether the child can accept the focus at all, as we
// want to try focusing it later even if it can't accept it right now.
if ( child->AcceptsFocusRecursively() )
return true;
}
return false;
}
bool wxControlContainerBase::HasAnyChildrenAcceptingFocus() const
{
const wxWindowList& children = m_winParent->GetChildren();
for ( wxWindowList::const_iterator i = children.begin(),
end = children.end();
i != end;
++i )
{
const wxWindow * const child = *i;
if ( !m_winParent->IsClientAreaChild(child) )
continue;
// Here we check if the child accepts focus right now as we need to
// know if we can give the focus to it or not.
if ( child->CanAcceptFocus() )
return true;
}