diff --git a/interface/wx/event.h b/interface/wx/event.h index 9dde8ccf63..2744138c18 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1321,20 +1321,26 @@ enum wxKeyCategoryFlags This event class contains information about key press and release events. The main information carried by this event is the key being pressed or - released. It can be accessed using either GetKeyCode() function or - GetUnicodeKey(). For the printable characters, the latter should be used as - it works for any keys, including non-Latin-1 characters that can be entered - when using national keyboard layouts. GetKeyCode() should be used to handle + released. It can be accessed using one of GetUnicodeKey(), GetKeyCode() + or GetRawKeyCode() functions. + For the printable characters, GetUnicodeKey() should be used as it works + for any keys, including non-Latin-1 characters that can be entered when + using national keyboard layouts. GetKeyCode() should be used to handle special characters (such as cursor arrows keys or @c HOME or @c INS and so on) which correspond to ::wxKeyCode enum elements above the @c WXK_START constant. While GetKeyCode() also returns the character code for Latin-1 keys for compatibility, it doesn't work for Unicode characters in general - and will return @c WXK_NONE for any non-Latin-1 ones. For this reason, it's - recommended to always use GetUnicodeKey() and only fall back to GetKeyCode() - if GetUnicodeKey() returned @c WXK_NONE meaning that the event corresponds - to a non-printable special keys. + and will return @c WXK_NONE for any non-Latin-1 ones. + If both GetUnicodeKey() and GetKeyCode() return @c WXK_NONE then the key + has no @c WXK_xxx mapping and GetRawKeyCode() can be used to distinguish + between keys, but raw key codes are platform specific. + For these reasons, it is recommended to always use GetUnicodeKey() and + only fall back to GetKeyCode() if GetUnicodeKey() returned @c WXK_NONE, + meaning that the event corresponds to a non-printable special keys, then + optionally check GetRawKeyCode() if GetKeyCode() also returned @c WXK_NONE + or simply ignore that key. - While both of these functions can be used with the events of @c + While these three functions can be used with the events of @c wxEVT_KEY_DOWN, @c wxEVT_KEY_UP and @c wxEVT_CHAR types, the values returned by them are different for the first two events and the last one. For the latter, the key returned corresponds to the character that would @@ -1368,6 +1374,10 @@ enum wxKeyCategoryFlags can be used to retrieve the key code as GetKeyCode() just returns @c WXK_NONE in this case. + Also, note that @c wxEVT_CHAR events are not generated for keys which do + not have a wxWidgets mapping, so GetRawKeyCode() should never be required + for this event. + To summarize: you should handle @c wxEVT_CHAR if you need the translated key and @c wxEVT_KEY_DOWN if you only need the value of the key itself, independent of the current keyboard state. diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index e5027a5423..91be0c33c3 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -974,7 +974,7 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event, } -static bool +static void wxTranslateGTKKeyEventToWx(wxKeyEvent& event, wxWindowGTK *win, GdkEventKey *gdk_event) @@ -1093,18 +1093,16 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, event.m_uniChar = event.m_keyCode; } - // sending unknown key events doesn't really make sense + // sending a WXK_NONE key and let app deal with it the RawKeyCode if required if ( !key_code && !event.m_uniChar ) - return false; + event.m_keyCode = WXK_NONE; #else if (!key_code) - return false; + event.m_keyCode = WXK_NONE; #endif // wxUSE_UNICODE // now fill all the other fields wxFillOtherKeyEventFields(event, win, gdk_event); - - return true; } @@ -1194,55 +1192,46 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), wxKeyEvent event( wxEVT_KEY_DOWN ); bool ret = false; - bool return_after_IM = false; - if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) + wxTranslateGTKKeyEventToWx(event, win, gdk_event); + // Send the CHAR_HOOK event first + if ( SendCharHookEvent(event, win) ) { - // Send the CHAR_HOOK event first - if ( SendCharHookEvent(event, win) ) - { - // Don't do anything at all with this event any more. - return TRUE; - } + // Don't do anything at all with this event any more. + return TRUE; + } - // Next check for accelerators. + // Next check for accelerators. #if wxUSE_ACCEL - wxWindowGTK *ancestor = win; - while (ancestor) + wxWindowGTK *ancestor = win; + while (ancestor) + { + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) { - int command = ancestor->GetAcceleratorTable()->GetCommand( event ); - if (command != -1) + wxCommandEvent menu_event( wxEVT_MENU, command ); + ret = ancestor->HandleWindowEvent( menu_event ); + + if ( !ret ) { - wxCommandEvent menu_event( wxEVT_MENU, command ); - ret = ancestor->HandleWindowEvent( menu_event ); - - if ( !ret ) - { - // if the accelerator wasn't handled as menu event, try - // it as button click (for compatibility with other - // platforms): - wxCommandEvent button_event( wxEVT_BUTTON, command ); - ret = ancestor->HandleWindowEvent( button_event ); - } - - break; + // if the accelerator wasn't handled as menu event, try + // it as button click (for compatibility with other + // platforms): + wxCommandEvent button_event( wxEVT_BUTTON, command ); + ret = ancestor->HandleWindowEvent( button_event ); } - if (ancestor->IsTopNavigationDomain(wxWindow::Navigation_Accel)) - break; - ancestor = ancestor->GetParent(); + + break; } + if (ancestor->IsTopNavigationDomain(wxWindow::Navigation_Accel)) + break; + ancestor = ancestor->GetParent(); + } #endif // wxUSE_ACCEL - // If not an accelerator, then emit KEY_DOWN event - if ( !ret ) - ret = win->HandleWindowEvent( event ); - } - else - { - // Return after IM processing as we cannot do - // anything with it anyhow. - return_after_IM = true; - } + // If not an accelerator, then emit KEY_DOWN event + if ( !ret ) + ret = win->HandleWindowEvent( event ); if ( !ret ) { @@ -1265,9 +1254,6 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), } } - if (return_after_IM) - return FALSE; - // Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x // will only be sent if it is not in an accelerator table. if (!ret) @@ -1395,11 +1381,7 @@ gtk_window_key_release_callback( GtkWidget * WXUNUSED(widget), wxPROCESS_EVENT_ONCE(GdkEventKey, gdk_event); wxKeyEvent event( wxEVT_KEY_UP ); - if ( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) - { - // unknown key pressed, ignore (the event would be useless anyhow) - return FALSE; - } + wxTranslateGTKKeyEventToWx(event, win, gdk_event); return win->GTKProcessEvent(event); }