diff --git a/include/wx/mdi.h b/include/wx/mdi.h index 37f0fa5208..6425de2253 100644 --- a/include/wx/mdi.h +++ b/include/wx/mdi.h @@ -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; }; diff --git a/include/wx/toplevel.h b/include/wx/toplevel.h index bf8123e5ab..28a56fe596 100644 --- a/include/wx/toplevel.h +++ b/include/wx/toplevel.h @@ -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 diff --git a/include/wx/window.h b/include/wx/window.h index 07f1f084bb..31ffe5332b 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -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 diff --git a/src/common/containr.cpp b/src/common/containr.cpp index 910804bc4d..2fda844c96 100644 --- a/src/common/containr.cpp +++ b/src/common/containr.cpp @@ -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 );