From f47a3591130b79d82a851b7eb7a73382fd6d89c2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 2 Dec 2011 00:50:22 +0000 Subject: [PATCH] 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 --- interface/wx/event.h | 9 ++++++--- src/gtk/window.cpp | 38 +++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/interface/wx/event.h b/interface/wx/event.h index d715fac..db03625 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1357,7 +1357,9 @@ enum wxKeyCategoryFlags @beginEventTable{wxKeyEvent} @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)} Process a @c wxEVT_KEY_UP event (any key has been released). @event{EVT_CHAR(func)} @@ -1368,8 +1370,9 @@ enum wxKeyCategoryFlags or wxApp global object if there is no active window before any other keyboard events are generated giving the parent window the opportunity 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 - generated. Notice that this event is not generated when the mouse is + handler doesn't call wxEvent::Skip(), neither @c 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. diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 01c966f..3815c8e 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -830,11 +830,9 @@ struct wxGtkIMData namespace { -// Send wxEVT_CHAR_HOOK event to the parent of the window and if it wasn't -// processed, send wxEVT_CHAR to the window itself. Return true if either of -// them was handled. -bool -SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win) +// Send wxEVT_CHAR_HOOK event to the parent of the window and return true only +// if it was processed (and not skipped). +bool SendCharHookEvent(const wxKeyEvent& event, wxWindow *win) { // 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 @@ -854,10 +852,7 @@ SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win) } } - // As above, make a copy of the event first. - wxKeyEvent eventChar(event); - eventChar.SetEventType(wxEVT_CHAR); - return win->HandleWindowEvent(eventChar); + return false; } } // anonymous namespace @@ -879,6 +874,13 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), 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 ret = win->HandleWindowEvent( event ); } @@ -962,25 +964,27 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), if ( key_code ) { + wxKeyEvent eventChar(wxEVT_CHAR, event); + 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 // characters to values in the range 1-26. - if ( event.ControlDown() && + if ( eventChar.ControlDown() && ( wxIsLowerChar(key_code) || wxIsUpperChar(key_code) )) { if ( wxIsLowerChar(key_code) ) - event.m_keyCode = key_code - 'a' + 1; + eventChar.m_keyCode = key_code - 'a' + 1; if ( wxIsUpperChar(key_code) ) - event.m_keyCode = key_code - 'A' + 1; + eventChar.m_keyCode = key_code - 'A' + 1; #if wxUSE_UNICODE - event.m_uniChar = event.m_keyCode; + eventChar.m_uniChar = event.m_keyCode; #endif } - ret = SendCharHookAndCharEvents(event, win); + ret = win->HandleWindowEvent(eventChar); } } @@ -994,7 +998,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context), const gchar *str, wxWindow *window) { - wxKeyEvent event( wxEVT_KEY_DOWN ); + wxKeyEvent event( wxEVT_CHAR ); // take modifiers, cursor position, timestamp etc. from the last // key_press_event that was fed into Input Method: @@ -1039,7 +1043,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context), #endif } - SendCharHookAndCharEvents(event, window); + window->HandleWindowEvent(event); } } } -- 2.7.4