]> git.saurik.com Git - wxWidgets.git/commitdiff
Generate unshifted Unicode key codes in wxEVT_KEY_XXX events in wxGTK.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Sep 2010 10:19:07 +0000 (10:19 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Sep 2010 10:19:07 +0000 (10:19 +0000)
wxGTK generated wxEVT_KEY_XXX with key codes corresponding to the unshifted
state of the key (except for the letters) but Unicode key codes corresponding
to the current shift state. This was inconsistent with wxMSW and also with the
idea that key events, unlike char ones, don't depend on the modifiers states.

Change wxGTK to behave as wxMSW and use unshifted values for Unicode key codes
as well.

Remove the now unnecessary workaround for different key event Unicode codes
from test.

Also try to explain the difference between normal and Unicode keys and key and
char events even better and mention that the Unicode key codes for the key
events are also untranslated in the documentation.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65526 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

interface/wx/event.h
src/gtk/window.cpp
tests/events/keyboard.cpp

index d7fd625ae01e39135eabbaee9f620447d802feb3..fa47fbbafac194841f8e39bd758e34fa644e4f08 100644 (file)
@@ -1181,49 +1181,81 @@ enum wxKeyCategoryFlags
 
     This event class contains information about key press and release events.
 
-    Notice that there are three different kinds of keyboard events in wxWidgets:
-    key down and up events and char events. The difference between the first two
-    is clear - the first corresponds to a key press and the second to a key
-    release - otherwise they are identical. Just note that if the key is
-    maintained in a pressed state you will typically get a lot of (automatically
-    generated) down events but only one up so it is wrong to assume that there is
-    one up event corresponding to each down one.
-
-    Both key down and up events provide untranslated key codes while the char
-    event carries the translated one. The untranslated code for alphanumeric
-    keys is always an upper case value. For the other keys it is one of @c
-    WXK_XXX values from the ::wxKeyCode enumeration. The translated key is, in
-    general, the character the user expects to appear as the result of the key
-    combination when typing the text into a text entry zone, for example.
-
-    A few examples to clarify this (all assume that CAPS LOCK is unpressed
-    and the standard US keyboard): when the @c 'A' key is pressed, the key down
-    event key code is equal to @c ASCII A == 65. But the char event key code
-    is @c ASCII a == 97. On the other hand, if you press both SHIFT and
-    @c 'A' keys simultaneously , the key code in key down event will still be
-    just @c 'A' while the char event key code parameter will now be @c 'A'
-    as well.
-
-    Although in this simple case it is clear that the correct key code could be
-    found in the key down event handler by checking the value returned by
-    wxKeyEvent::ShiftDown(), in general you should use @c EVT_CHAR if you need
-    the translated key as for non-alphanumeric keys the translation is
-    keyboard-layout dependent and can only be done properly by the system
-    itself.
-
-    Another kind of translation is done when the control key is pressed: for
-    example, for CTRL-A key press the key down event still carries the
-    same key code @c 'a' as usual but the char event will have key code of 1,
-    the ASCII value of this key combination.
-
-    Notice that while pressing any key will generate a key down event (except
-    in presence of IME perhaps) a few special keys don't generate a char event:
-    currently, Shift, Control (or Command), Alt (or Menu or Meta) and Caps, Num
-    and Scroll Lock keys don't do it. For all the other keys you have the
-    choice about whether to choose key down or char event for handling it and
-    either can be used. However it is advised to use char events only for the
-    keys that are supposed to generate characters on screen and key down events
-    for all the rest.
+    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
+    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.
+
+    While both of these 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
+    appear in e.g. a text zone if the user pressed the key in it. As such, its
+    value depends on the current state of the Shift key and, for the letters,
+    on the state of Caps Lock modifier. For example, if @c A key is pressed
+    without Shift being held down, wxKeyEvent of type @c wxEVT_CHAR generated
+    for this key press will return (from either GetKeyCode() or GetUnicodeKey()
+    as their meanings coincide for ASCII characters) key code of 97
+    corresponding the ASCII value of @c a. And if the same key is pressed but
+    with Shift being held (or Caps Lock being active), then the key could would
+    be 65, i.e. ASCII value of capital @c A.
+
+    However for the key down and up events the returned key code will instead
+    be @c A independently of the state of the modifier keys i.e. it depends
+    only on physical key being pressed and is not translated to its logical
+    representation using the current keyboard state. Such untranslated key
+    codes are defined as follows:
+        - For the letters they correspond to the @e upper case value of the
+        letter.
+        - For the other alphanumeric keys (e.g. @c 7 or @c +), the untranslated
+        key code corresponds to the character produced by the key when it is
+        pressed without Shift. E.g. in standard US keyboard layout the
+        untranslated key code for the key @c =/+ in the upper right corner of
+        the keyboard is 61 which is the ASCII value of @c =.
+        - For the rest of the keys (i.e. special non-printable keys) it is the
+        same as the normal key code as no translation is used anyhow.
+
+    Notice that the first rule applies to all Unicode letters, not just the
+    usual Latin-1 ones. However for non-Latin-1 letters only GetUnicodeKey()
+    can be used to retrieve the key code as GetKeyCode() just returns @c
+    WXK_NONE in this case.
+
+    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.
+
+    @note Not all key down events may be generated by the user. As an example,
+        @c wxEVT_KEY_DOWN with @c = key code can be generated using the
+        standard US keyboard layout but not using the German one because the @c
+        = key corresponds to Shift-0 key combination in this layout and the key
+        code for it is @c 0, not @c =. Because of this you should avoid
+        requiring your users to type key events that might be impossible to
+        enter on their keyboard.
+
+
+    Another difference between key and char events is that another kind of
+    translation is done for the latter ones when the Control key is pressed:
+    char events for ASCII letters in this case carry codes corresponding to the
+    ASCII value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until
+    26 for Ctrl-Z. This is convenient for terminal-like applications and can be
+    completely ignored by all the other ones (if you need to handle Ctrl-A it
+    is probably a better idea to use the key event rather than the char one).
+    Notice that currently no translation is done for the presses of @c [, @c
+    \\, @c ], @c ^ and @c _ keys which might be mapped to ASCII values from 27
+    to 31.
+
+    Finally, modifier keys only generate key events but no char events at all.
+    The modifiers keys are @c WXK_SHIFT, @c WXK_CONTROL, @c WXK_ALT and various
+    @c WXK_WINDOWS_XXX from ::wxKeyCode enum.
 
 
     You may discover how the other keys on your system behave interactively by
index d208b4eae430ab771bcfe48b4e6e9fcb710bbb7b..d51777f3e0f88ed33c6de20ce937025663794579 100644 (file)
@@ -686,16 +686,6 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event,
     event.m_metaDown = (gdk_event->state & GDK_META_MASK) != 0;
     event.m_rawCode = (wxUint32) gdk_event->keyval;
     event.m_rawFlags = 0;
-#if wxUSE_UNICODE
-    event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval);
-    if ( !event.m_uniChar && event.m_keyCode <= WXK_DELETE )
-    {
-        // Set Unicode key code to the ASCII equivalent for compatibility. E.g.
-        // let RETURN generate the key event with both key and Unicode key
-        // codes of 13.
-        event.m_uniChar = event.m_keyCode;
-    }
-#endif // wxUSE_UNICODE
     wxGetMousePosition( &x, &y );
     win->ScreenToClient( &x, &y );
     event.m_x = x;
@@ -800,6 +790,17 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event,
 
     event.m_keyCode = key_code;
 
+#if wxUSE_UNICODE
+    event.m_uniChar = gdk_keyval_to_unicode(key_code ? key_code : keysym);
+    if ( !event.m_uniChar && event.m_keyCode <= WXK_DELETE )
+    {
+        // Set Unicode key code to the ASCII equivalent for compatibility. E.g.
+        // let RETURN generate the key event with both key and Unicode key
+        // codes of 13.
+        event.m_uniChar = event.m_keyCode;
+    }
+#endif // wxUSE_UNICODE
+
     // now fill all the other fields
     wxFillOtherKeyEventFields(event, win, gdk_event);
 
index 9fe9a531e8a1fd7a38b0761f36ee6766fea6aa17..d319eeabd68ff8eafe1334343a0207ed3348fbf0 100644 (file)
@@ -188,27 +188,16 @@ void TestEvent(int line, const wxKeyEvent& ev, const KeyDesc& desc)
                                   ev.GetKeyCode() );
 
 #if wxUSE_UNICODE
-    if ( desc.m_keycode < 0x80 )
+    if ( desc.m_keycode < WXK_START )
     {
-        // FIXME: Currently wxMSW generates 'A' key code for key down/up events
-        // for the 'a' physical key while wxGTK and wxOSX/Cocoa generate them
-        // with 'a' and it's not clear which behaviour is more correct so don't
-        // test this for those events, only test it for EVT_CHAR where the
-        // correct behaviour is clear.
-
-        if ( t == wxEVT_CHAR )
-        {
-            // For 7-bit ASCII Unicode keys are the same as normal key codes.
-            CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong Unicode key in " + msg,
-                                          (char)desc.m_keycode,
-                                          (char)ev.GetUnicodeKey() );
-        }
+        // For Latin-1 our key code is the same as Unicode character value.
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong Unicode key in " + msg,
+                                      (char)desc.m_keycode,
+                                      (char)ev.GetUnicodeKey() );
     }
-    else
+    else // Special key
     {
-        // In this test we don't use any really Unicode characters so far so
-        // anything above 0x80 must be special keys (e.g. WXK_CONTROL &c) which
-        // don't have any Unicode equivalent.
+        // Key codes above WXK_START don't correspond to printable characters.
         CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong non-zero Unicode key in " + msg,
                                       0,
                                       (int)ev.GetUnicodeKey() );