Fix regression with MDI children accelerators
Since the changes of 8034e35391
(see #16870)
accelerators, including the standard ones such as Ctrl-F4 under MSW, didn't
work any longer inside the MDI children.
Fix this by extending IsTopNavigationDomain() to allow for checking whether
the given window should stop propagation of all keyboard events, as wxTLW
does, or only TAB navigation ones as wxMDIChildFrame and wxAuiFloatingFrame
do.
This commit is contained in:
@@ -44,7 +44,7 @@ public:
|
|||||||
wxAuiManager* GetOwnerManager() const;
|
wxAuiManager* GetOwnerManager() const;
|
||||||
|
|
||||||
// Allow processing accelerators to the parent frame
|
// Allow processing accelerators to the parent frame
|
||||||
virtual bool IsTopNavigationDomain() const wxOVERRIDE { return false; }
|
virtual bool IsTopNavigationDomain(NavigationKind kind) const wxOVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnMoveStart();
|
virtual void OnMoveStart();
|
||||||
|
@@ -182,7 +182,21 @@ public:
|
|||||||
// In all ports keyboard navigation must stop at MDI child frame level and
|
// 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
|
// can't cross its boundary. Indicate this by overriding this function to
|
||||||
// return true.
|
// return true.
|
||||||
virtual bool IsTopNavigationDomain() const wxOVERRIDE { return true; }
|
virtual bool IsTopNavigationDomain(NavigationKind kind) const wxOVERRIDE
|
||||||
|
{
|
||||||
|
switch ( kind )
|
||||||
|
{
|
||||||
|
case Navigation_Tab:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Navigation_Accel:
|
||||||
|
// Parent frame accelerators should work inside MDI child, so
|
||||||
|
// don't block their processing by returning true for them.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Raising any frame is supposed to show it but wxFrame Raise()
|
// Raising any frame is supposed to show it but wxFrame Raise()
|
||||||
// implementation doesn't work for MDI child frames in most forms so
|
// implementation doesn't work for MDI child frames in most forms so
|
||||||
|
@@ -246,7 +246,7 @@ public:
|
|||||||
// override some base class virtuals
|
// override some base class virtuals
|
||||||
virtual bool Destroy() wxOVERRIDE;
|
virtual bool Destroy() wxOVERRIDE;
|
||||||
virtual bool IsTopLevel() const wxOVERRIDE { return true; }
|
virtual bool IsTopLevel() const wxOVERRIDE { return true; }
|
||||||
virtual bool IsTopNavigationDomain() const wxOVERRIDE { return true; }
|
virtual bool IsTopNavigationDomain(NavigationKind kind) const wxOVERRIDE;
|
||||||
virtual bool IsVisible() const { return IsShown(); }
|
virtual bool IsVisible() const { return IsShown(); }
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
|
@@ -1537,13 +1537,23 @@ public:
|
|||||||
virtual wxWindow *GetMainWindowOfCompositeControl()
|
virtual wxWindow *GetMainWindowOfCompositeControl()
|
||||||
{ return (wxWindow*)this; }
|
{ return (wxWindow*)this; }
|
||||||
|
|
||||||
// If this function returns true, keyboard navigation events shouldn't
|
enum NavigationKind
|
||||||
|
{
|
||||||
|
Navigation_Tab,
|
||||||
|
Navigation_Accel
|
||||||
|
};
|
||||||
|
|
||||||
|
// If this function returns true, keyboard events of the given kind can't
|
||||||
// escape from it. A typical example of such "navigation domain" is a top
|
// 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
|
// 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
|
// 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()
|
// children frames are not top level windows (and their IsTopLevel()
|
||||||
// returns false) but still are self-contained navigation domains as well.
|
// returns false) but still are self-contained navigation domains for the
|
||||||
virtual bool IsTopNavigationDomain() const { return false; }
|
// purposes of TAB navigation -- but not for the accelerators.
|
||||||
|
virtual bool IsTopNavigationDomain(NavigationKind WXUNUSED(kind)) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -165,6 +165,22 @@ wxAuiManager* wxAuiFloatingFrame::GetOwnerManager() const
|
|||||||
return m_ownerMgr;
|
return m_ownerMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxAuiFloatingFrame::IsTopNavigationDomain(NavigationKind kind) const
|
||||||
|
{
|
||||||
|
switch ( kind )
|
||||||
|
{
|
||||||
|
case Navigation_Tab:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Navigation_Accel:
|
||||||
|
// Floating frames are often used as tool palettes and it's
|
||||||
|
// convenient for the accelerators defined in the parent frame to
|
||||||
|
// work in them, so don't block their propagation.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxAuiFloatingFrameBaseClass::IsTopNavigationDomain(kind);
|
||||||
|
}
|
||||||
|
|
||||||
void wxAuiFloatingFrame::OnSize(wxSizeEvent& WXUNUSED(event))
|
void wxAuiFloatingFrame::OnSize(wxSizeEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
|
@@ -505,7 +505,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
|
|||||||
// even an MDI child frame, so test for this explicitly
|
// even an MDI child frame, so test for this explicitly
|
||||||
// (and in particular don't just use IsTopLevel() which
|
// (and in particular don't just use IsTopLevel() which
|
||||||
// would return false in the latter case).
|
// would return false in the latter case).
|
||||||
if ( focusedParent->IsTopNavigationDomain() )
|
if ( focusedParent->IsTopNavigationDomain(wxWindow::Navigation_Tab) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
event.SetCurrentFocus( focusedParent );
|
event.SetCurrentFocus( focusedParent );
|
||||||
|
@@ -370,6 +370,22 @@ void wxTopLevelWindowBase::SetIcon(const wxIcon& icon)
|
|||||||
// event handlers
|
// event handlers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTopLevelWindowBase::IsTopNavigationDomain(NavigationKind kind) const
|
||||||
|
{
|
||||||
|
// This switch only exists to generate a compiler warning and force us to
|
||||||
|
// revisit this code if any new kinds of navigation are added in the
|
||||||
|
// future, but for now we block of them by default (some derived classes
|
||||||
|
// relax this however).
|
||||||
|
switch ( kind )
|
||||||
|
{
|
||||||
|
case Navigation_Tab:
|
||||||
|
case Navigation_Accel:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// default resizing behaviour - if only ONE subwindow, resize to fill the
|
// default resizing behaviour - if only ONE subwindow, resize to fill the
|
||||||
// whole client area
|
// whole client area
|
||||||
void wxTopLevelWindowBase::DoLayout()
|
void wxTopLevelWindowBase::DoLayout()
|
||||||
|
@@ -1109,7 +1109,7 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ancestor->IsTopNavigationDomain())
|
if (ancestor->IsTopNavigationDomain(wxWindow::Navigation_Accel))
|
||||||
break;
|
break;
|
||||||
ancestor = ancestor->GetParent();
|
ancestor = ancestor->GetParent();
|
||||||
}
|
}
|
||||||
|
@@ -134,10 +134,8 @@ bool wxGUIEventLoop::PreProcessMessage(WXMSG *msg)
|
|||||||
if ( wnd->MSWTranslateMessage((WXMSG *)msg))
|
if ( wnd->MSWTranslateMessage((WXMSG *)msg))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// stop at first top level window, i.e. don't try to process the key
|
// stop at top navigation domain, i.e. typically a top level window
|
||||||
// strokes originating in a dialog using the accelerators of the parent
|
if ( wnd->IsTopNavigationDomain(wxWindow::Navigation_Accel) )
|
||||||
// frame - this doesn't make much sense
|
|
||||||
if ( wnd->IsTopNavigationDomain() )
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +149,7 @@ bool wxGUIEventLoop::PreProcessMessage(WXMSG *msg)
|
|||||||
// if we don't do this, pressing ESC on a modal dialog shown as child
|
// if we don't do this, pressing ESC on a modal dialog shown as child
|
||||||
// of a modal dialog with wxID_CANCEL will cause the parent dialog to
|
// of a modal dialog with wxID_CANCEL will cause the parent dialog to
|
||||||
// be closed, for example
|
// be closed, for example
|
||||||
if ( wnd->IsTopNavigationDomain() )
|
if ( wnd->IsTopNavigationDomain(wxWindow::Navigation_Accel) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2662,7 +2662,7 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ancestor->IsTopNavigationDomain())
|
if (ancestor->IsTopNavigationDomain(wxWindow::Navigation_Accel))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ancestor = ancestor->GetParent();
|
ancestor = ancestor->GetParent();
|
||||||
|
Reference in New Issue
Block a user