]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix tab navigation bug with static boxes without enabled children.
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Jul 2013 12:44:29 +0000 (12:44 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Jul 2013 12:44:29 +0000 (12:44 +0000)
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

include/wx/containr.h
src/common/containr.cpp

index 3783578f402e669102012da114e5a143d30521f5..3f91f3e6a37c6c6f524aab780f920365852c1dcd 100644 (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;
 
index a194041631a66f2dc03da0b8de97669ecd7233dc..ba1ffd220e7deed882b841587699f42c0899488f 100644 (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;
     }