Make wxEVT_CHAR_HOOK behave in wxGTK as in wxMSW.

Send wxEVT_CHAR_HOOK before wxEVT_KEY_DOWN and avoid generating both
wxEVT_KEY_DOWN and wxEVT_CHAR if the hook event was handled.

This makes wxGTK behave consistently with wxMSW and wxOSX/Cocoa as can be seen
in the keyboard sample.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69892 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-12-02 00:50:22 +00:00
parent e45d90901d
commit f47a359113
2 changed files with 27 additions and 20 deletions

View File

@@ -1357,7 +1357,9 @@ enum wxKeyCategoryFlags
@beginEventTable{wxKeyEvent} @beginEventTable{wxKeyEvent}
@event{EVT_KEY_DOWN(func)} @event{EVT_KEY_DOWN(func)}
Process a @c wxEVT_KEY_DOWN event (any key has been pressed). Process a @c wxEVT_KEY_DOWN event (any key has been pressed). If this
event is handled and not skipped, @c wxEVT_CHAR will not be generated
at all for this key press (but @c wxEVT_KEY_UP will be).
@event{EVT_KEY_UP(func)} @event{EVT_KEY_UP(func)}
Process a @c wxEVT_KEY_UP event (any key has been released). Process a @c wxEVT_KEY_UP event (any key has been released).
@event{EVT_CHAR(func)} @event{EVT_CHAR(func)}
@@ -1368,8 +1370,9 @@ enum wxKeyCategoryFlags
or wxApp global object if there is no active window before any other or wxApp global object if there is no active window before any other
keyboard events are generated giving the parent window the opportunity keyboard events are generated giving the parent window the opportunity
to intercept all the keyboard entry. If the event is handled, i.e. the to intercept all the keyboard entry. If the event is handled, i.e. the
handler doesn't call wxEvent::Skip(), no further keyboard events are handler doesn't call wxEvent::Skip(), neither @c wxEVT_KEY_DOWN nor @c
generated. Notice that this event is not generated when the mouse is 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 captured as it is considered that the window which has the capture
should receive all the keyboard events too without allowing its parent should receive all the keyboard events too without allowing its parent
wxTopLevelWindow to interfere with their processing. wxTopLevelWindow to interfere with their processing.

View File

@@ -830,11 +830,9 @@ struct wxGtkIMData
namespace namespace
{ {
// Send wxEVT_CHAR_HOOK event to the parent of the window and if it wasn't // Send wxEVT_CHAR_HOOK event to the parent of the window and return true only
// processed, send wxEVT_CHAR to the window itself. Return true if either of // if it was processed (and not skipped).
// them was handled. bool SendCharHookEvent(const wxKeyEvent& event, wxWindow *win)
bool
SendCharHookAndCharEvents(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 the top level parent window to allow it
// 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
@@ -854,10 +852,7 @@ SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win)
} }
} }
// As above, make a copy of the event first. return false;
wxKeyEvent eventChar(event);
eventChar.SetEventType(wxEVT_CHAR);
return win->HandleWindowEvent(eventChar);
} }
} // anonymous namespace } // anonymous namespace
@@ -879,6 +874,13 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) )
{ {
// Send the CHAR_HOOK event first
if ( SendCharHookEvent(event, win) )
{
// Don't do anything at all with this event any more.
return TRUE;
}
// Emit KEY_DOWN event // Emit KEY_DOWN event
ret = win->HandleWindowEvent( event ); ret = win->HandleWindowEvent( event );
} }
@@ -962,25 +964,27 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
if ( key_code ) if ( key_code )
{ {
wxKeyEvent eventChar(wxEVT_CHAR, event);
wxLogTrace(TRACE_KEYS, wxT("Char event: %ld"), key_code); wxLogTrace(TRACE_KEYS, wxT("Char event: %ld"), key_code);
event.m_keyCode = key_code; eventChar.m_keyCode = key_code;
// To conform to the docs we need to translate Ctrl-alpha // To conform to the docs we need to translate Ctrl-alpha
// characters to values in the range 1-26. // characters to values in the range 1-26.
if ( event.ControlDown() && if ( eventChar.ControlDown() &&
( wxIsLowerChar(key_code) || wxIsUpperChar(key_code) )) ( wxIsLowerChar(key_code) || wxIsUpperChar(key_code) ))
{ {
if ( wxIsLowerChar(key_code) ) if ( wxIsLowerChar(key_code) )
event.m_keyCode = key_code - 'a' + 1; eventChar.m_keyCode = key_code - 'a' + 1;
if ( wxIsUpperChar(key_code) ) if ( wxIsUpperChar(key_code) )
event.m_keyCode = key_code - 'A' + 1; eventChar.m_keyCode = key_code - 'A' + 1;
#if wxUSE_UNICODE #if wxUSE_UNICODE
event.m_uniChar = event.m_keyCode; eventChar.m_uniChar = event.m_keyCode;
#endif #endif
} }
ret = SendCharHookAndCharEvents(event, win); ret = win->HandleWindowEvent(eventChar);
} }
} }
@@ -994,7 +998,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
const gchar *str, const gchar *str,
wxWindow *window) wxWindow *window)
{ {
wxKeyEvent event( wxEVT_KEY_DOWN ); wxKeyEvent event( wxEVT_CHAR );
// take modifiers, cursor position, timestamp etc. from the last // take modifiers, cursor position, timestamp etc. from the last
// key_press_event that was fed into Input Method: // key_press_event that was fed into Input Method:
@@ -1039,7 +1043,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
#endif #endif
} }
SendCharHookAndCharEvents(event, window); window->HandleWindowEvent(event);
} }
} }
} }