Make wxEVT_CHAR_HOOK propagate upwards and send it to the window itself.
Send wxEVT_CHAR_HOOK events to the focused window itself but make them propagatable to ensure that the parent windows (including the top level parent) still get it. This still allows the TLW parent to intercept keyboard handling in its child but allows the child (or an intermediate parent window) to have some say in the matter. See #9102. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69893 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1744,6 +1744,14 @@ public:
|
|||||||
wxUint32 m_rawFlags;
|
wxUint32 m_rawFlags;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Set the event to propagate if necessary, i.e. if it's of wxEVT_CHAR_HOOK
|
||||||
|
// type. This is used by all ctors.
|
||||||
|
void InitPropagation()
|
||||||
|
{
|
||||||
|
if ( m_eventType == wxEVT_CHAR_HOOK )
|
||||||
|
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy only the event data present in this class, this is used by
|
// Copy only the event data present in this class, this is used by
|
||||||
// AssignKeyData() and copy ctor.
|
// AssignKeyData() and copy ctor.
|
||||||
void DoAssignMembers(const wxKeyEvent& evt)
|
void DoAssignMembers(const wxKeyEvent& evt)
|
||||||
|
@@ -1365,17 +1365,21 @@ enum wxKeyCategoryFlags
|
|||||||
@event{EVT_CHAR(func)}
|
@event{EVT_CHAR(func)}
|
||||||
Process a @c wxEVT_CHAR event.
|
Process a @c wxEVT_CHAR event.
|
||||||
@event{EVT_CHAR_HOOK(func)}
|
@event{EVT_CHAR_HOOK(func)}
|
||||||
Process a @c wxEVT_CHAR_HOOK event which is sent to the active
|
Process a @c wxEVT_CHAR_HOOK event. Unlike all the other key events,
|
||||||
wxTopLevelWindow (i.e. the one containing the currently focused window)
|
this event is propagated upwards the window hierarchy which allows
|
||||||
or wxApp global object if there is no active window before any other
|
intercepting it in the parent window of the focused window to which it
|
||||||
keyboard events are generated giving the parent window the opportunity
|
is sent initially (if there is no focused window, this event is sent to
|
||||||
to intercept all the keyboard entry. If the event is handled, i.e. the
|
the wxApp global object). It is also generated before any other key
|
||||||
handler doesn't call wxEvent::Skip(), neither @c wxEVT_KEY_DOWN nor @c
|
events and so gives the parent window an opportunity to modify the
|
||||||
wxEVT_CHAR events will be generated (although @c wxEVT_KEY_UP still
|
keyboard handling of its children, e.g. it is used internally by
|
||||||
will be). Notice that this event is not generated when the mouse is
|
wxWidgets in some ports to intercept pressing Esc key in any child of a
|
||||||
captured as it is considered that the window which has the capture
|
dialog to close the dialog itself when it's pressed. If the event is
|
||||||
should receive all the keyboard events too without allowing its parent
|
handled, i.e. the handler doesn't call wxEvent::Skip(), neither @c
|
||||||
wxTopLevelWindow to interfere with their processing.
|
wxEVT_KEY_DOWN nor @c wxEVT_CHAR events will be generated (although @c
|
||||||
|
wxEVT_KEY_UP still will be). Notice that this event is not generated
|
||||||
|
when the mouse is captured as it is considered that the window which
|
||||||
|
has the capture should receive all the keyboard events too without
|
||||||
|
allowing its parent wxTopLevelWindow to interfere with their processing.
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@see wxKeyboardState
|
@see wxKeyboardState
|
||||||
|
@@ -735,6 +735,8 @@ wxKeyEvent::wxKeyEvent(wxEventType type)
|
|||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
m_uniChar = WXK_NONE;
|
m_uniChar = WXK_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
InitPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
|
wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
|
||||||
@@ -742,6 +744,8 @@ wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
|
|||||||
wxKeyboardState(evt)
|
wxKeyboardState(evt)
|
||||||
{
|
{
|
||||||
DoAssignMembers(evt);
|
DoAssignMembers(evt);
|
||||||
|
|
||||||
|
InitPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt)
|
wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt)
|
||||||
@@ -751,6 +755,8 @@ wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt)
|
|||||||
DoAssignMembers(evt);
|
DoAssignMembers(evt);
|
||||||
|
|
||||||
m_eventType = eventType;
|
m_eventType = eventType;
|
||||||
|
|
||||||
|
InitPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxKeyEvent::IsKeyInCategory(int category) const
|
bool wxKeyEvent::IsKeyInCategory(int category) const
|
||||||
|
@@ -834,23 +834,16 @@ namespace
|
|||||||
// if it was processed (and not skipped).
|
// if it was processed (and not skipped).
|
||||||
bool SendCharHookEvent(const wxKeyEvent& event, wxWindow *win)
|
bool SendCharHookEvent(const wxKeyEvent& event, wxWindow *win)
|
||||||
{
|
{
|
||||||
// wxEVT_CHAR_HOOK must be sent to the top level parent window to allow it
|
// wxEVT_CHAR_HOOK must be sent to allow the parent windows (e.g. a dialog
|
||||||
|
// which typically closes when Esc key is pressed in any of its controls)
|
||||||
// to handle key events in all of its children unless the mouse is captured
|
// to handle key events in all of its children unless the mouse is captured
|
||||||
// in which case we consider that the keyboard should be "captured" too.
|
// in which case we consider that the keyboard should be "captured" too.
|
||||||
if ( !g_captureWindow )
|
if ( !g_captureWindow )
|
||||||
{
|
{
|
||||||
wxWindow * const parent = wxGetTopLevelParent(win);
|
wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event);
|
||||||
if ( parent )
|
if ( win->HandleWindowEvent(eventCharHook) )
|
||||||
{
|
|
||||||
// We need to make a copy of the event object because it is
|
|
||||||
// modified while it's handled, notably its WasProcessed() flag
|
|
||||||
// is set after it had been processed once.
|
|
||||||
wxKeyEvent eventCharHook(event);
|
|
||||||
eventCharHook.SetEventType(wxEVT_CHAR_HOOK);
|
|
||||||
if ( parent->HandleWindowEvent(eventCharHook) )
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -6622,7 +6622,14 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
|
|||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const wxWindow * const win = wxGetActiveWindow();
|
wxWindow const* win = wxWindow::DoFindFocus();
|
||||||
|
if ( !win )
|
||||||
|
{
|
||||||
|
// Even if the focus got lost somehow, still send the event
|
||||||
|
// to the top level parent to allow a wxDialog to always
|
||||||
|
// close on Escape.
|
||||||
|
win = wxGetActiveWindow();
|
||||||
|
}
|
||||||
|
|
||||||
wxKeyEvent event(wxEVT_CHAR_HOOK);
|
wxKeyEvent event(wxEVT_CHAR_HOOK);
|
||||||
MSWInitAnyKeyEvent(event, wParam, lParam, win);
|
MSWInitAnyKeyEvent(event, wParam, lParam, win);
|
||||||
|
@@ -1616,20 +1616,16 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers
|
|||||||
|
|
||||||
#if wxOSX_USE_CARBON
|
#if wxOSX_USE_CARBON
|
||||||
long keyval = event.m_keyCode ;
|
long keyval = event.m_keyCode ;
|
||||||
wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ;
|
|
||||||
|
|
||||||
if (tlw)
|
|
||||||
{
|
{
|
||||||
event.SetEventType( wxEVT_CHAR_HOOK );
|
wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event);
|
||||||
handled = tlw->HandleWindowEvent( event );
|
handled = focus->HandleWindowEvent( eventCharHook );
|
||||||
if ( handled && event.GetSkipped() )
|
if ( handled && eventCharHook.GetSkipped() )
|
||||||
handled = false ;
|
handled = false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !handled )
|
if ( !handled )
|
||||||
{
|
{
|
||||||
event.SetEventType( wxEVT_CHAR );
|
|
||||||
event.Skip( false ) ;
|
|
||||||
handled = focus->HandleWindowEvent( event ) ;
|
handled = focus->HandleWindowEvent( event ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2305,9 +2305,8 @@ bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event)
|
|||||||
// changed by SetupKeyEvent() so it can be wxEVT_KEY_UP too by now).
|
// changed by SetupKeyEvent() so it can be wxEVT_KEY_UP too by now).
|
||||||
if ( wxevent.GetEventType() == wxEVT_KEY_DOWN )
|
if ( wxevent.GetEventType() == wxEVT_KEY_DOWN )
|
||||||
{
|
{
|
||||||
wxKeyEvent eventHook(wxevent);
|
wxKeyEvent eventHook(wxEVT_CHAR_HOOK, wxevent);
|
||||||
eventHook.SetEventType(wxEVT_CHAR_HOOK);
|
if ( GetWXPeer()->OSXHandleKeyEvent(eventHook) )
|
||||||
if ( wxGetTopLevelParent(GetWXPeer())->OSXHandleKeyEvent(eventHook) )
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user