]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix bug with TAB being able to switch focus between MDI frames.
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Aug 2011 00:45:42 +0000 (00:45 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Aug 2011 00:45:42 +0000 (00:45 +0000)
The keyboard navigation code correctly checked that TAB was not propagated
above the TLW containing the window in which the key was pressed to avoid
switching focus between different TLWs by pressing TAB.

However wxMDIChildFrame is not a TLW and so it was possible to switch focus
between two different MDI child frames by pressing TAB. This was unexpected
and counterintuitive, especially because the frame receiving focus was not
even activated (which might be another bug).

Fix this by adding a new wxWindow::IsTopNavigationDomain() virtual method that
can be overridden to indicate that a window is a self-contained "keyboard
navigation domain" and that keyboard events shouldn't propagate outside of it
and override it in both wxTopLevelWindow and wxMDIChildFrame to ensure that it
behaves correctly.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68502 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/mdi.h
include/wx/toplevel.h
include/wx/window.h
src/common/containr.cpp

index 37f0fa5208677d9605435a08d77c46a56c7ecb9b..6425de22536aeafd4bc9026714346494e38858cf 100644 (file)
@@ -176,6 +176,11 @@ public:
     // level windows too
     virtual bool IsTopLevel() const { return false; }
 
+    // In all ports keyboard navigation must stop at MDI child frame level and
+    // can't cross its boundary. Indicate this by overriding this function to
+    // return true.
+    virtual bool IsTopNavigationDomain() const { return true; }
+
 protected:
     wxMDIParentFrame *m_mdiParent;
 };
index bf8123e5ab4cd95cc375ee629458207367d05902..28a56fe5966f9e0c669f0c8376b87f33442dd686 100644 (file)
@@ -282,6 +282,7 @@ public:
     // override some base class virtuals
     virtual bool Destroy();
     virtual bool IsTopLevel() const { return true; }
+    virtual bool IsTopNavigationDomain() const { return true; }
     virtual bool IsVisible() const { return IsShown(); }
 
     // event handlers
index 07f1f084bbfaf9d60159c1b5b5ff9562e28205b1..31ffe5332bee472d641a4647e022ffd1d30f87bc 100644 (file)
@@ -1422,6 +1422,15 @@ public:
     virtual wxWindow *GetMainWindowOfCompositeControl()
         { return (wxWindow*)this; }
 
+    // If this function returns true, keyboard navigation events shouldn't
+    // escape from it. A typical example of such "navigation domain" is a top
+    // level window because pressing TAB in one of them must not transfer focus
+    // to a different top level window. But it's not limited to them, e.g. MDI
+    // children frames are not top level windows (and their IsTopLevel()
+    // returns false) but still are self-contained navigation domains as well.
+    virtual bool IsTopNavigationDomain() const { return false; }
+
+
 protected:
     // helper for the derived class Create() methods: the first overload, with
     // validator parameter, should be used for child windows while the second
index 910804bc4d811c9630da4b0db13ba604c6ef3975..2fda844c9620a456882a0212a4857535c6624edb 100644 (file)
@@ -475,8 +475,11 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
                 wxWindow *focusedParent = m_winParent;
                 while ( parent )
                 {
-                    // we don't want to tab into a different dialog or frame
-                    if ( focusedParent->IsTopLevel() )
+                    // We don't want to tab into a different dialog or frame or
+                    // even an MDI child frame, so test for this explicitly
+                    // (and in particular don't just use IsTopLevel() which
+                    // would return false in the latter case).
+                    if ( focusedParent->IsTopNavigationDomain() )
                         break;
 
                     event.SetCurrentFocus( focusedParent );