Fix bug with TAB being able to switch focus between MDI frames.
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
This commit is contained in:
@@ -176,6 +176,11 @@ public:
|
|||||||
// level windows too
|
// level windows too
|
||||||
virtual bool IsTopLevel() const { return false; }
|
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:
|
protected:
|
||||||
wxMDIParentFrame *m_mdiParent;
|
wxMDIParentFrame *m_mdiParent;
|
||||||
};
|
};
|
||||||
|
@@ -282,6 +282,7 @@ public:
|
|||||||
// override some base class virtuals
|
// override some base class virtuals
|
||||||
virtual bool Destroy();
|
virtual bool Destroy();
|
||||||
virtual bool IsTopLevel() const { return true; }
|
virtual bool IsTopLevel() const { return true; }
|
||||||
|
virtual bool IsTopNavigationDomain() const { return true; }
|
||||||
virtual bool IsVisible() const { return IsShown(); }
|
virtual bool IsVisible() const { return IsShown(); }
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
|
@@ -1422,6 +1422,15 @@ public:
|
|||||||
virtual wxWindow *GetMainWindowOfCompositeControl()
|
virtual wxWindow *GetMainWindowOfCompositeControl()
|
||||||
{ return (wxWindow*)this; }
|
{ 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:
|
protected:
|
||||||
// helper for the derived class Create() methods: the first overload, with
|
// helper for the derived class Create() methods: the first overload, with
|
||||||
// validator parameter, should be used for child windows while the second
|
// validator parameter, should be used for child windows while the second
|
||||||
|
@@ -475,8 +475,11 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
|
|||||||
wxWindow *focusedParent = m_winParent;
|
wxWindow *focusedParent = m_winParent;
|
||||||
while ( parent )
|
while ( parent )
|
||||||
{
|
{
|
||||||
// we don't want to tab into a different dialog or frame
|
// We don't want to tab into a different dialog or frame or
|
||||||
if ( focusedParent->IsTopLevel() )
|
// 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;
|
break;
|
||||||
|
|
||||||
event.SetCurrentFocus( focusedParent );
|
event.SetCurrentFocus( focusedParent );
|
||||||
|
Reference in New Issue
Block a user