From: Vadim Zeitlin Date: Tue, 23 Jul 2013 12:44:29 +0000 (+0000) Subject: Fix tab navigation bug with static boxes without enabled children. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/dee22e3198c17e325ff4862520aec104d40b9948?ds=inline 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 --- diff --git a/include/wx/containr.h b/include/wx/containr.h index 3783578f40..3f91f3e6a3 100644 --- a/include/wx/containr.h +++ b/include/wx/containr.h @@ -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; diff --git a/src/common/containr.cpp b/src/common/containr.cpp index a194041631..ba1ffd220e 100644 --- a/src/common/containr.cpp +++ b/src/common/containr.cpp @@ -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; }