Bug 67167

Summary: Can't enter *capital* umlauts when using Swiss keyboard - ch(fr)
Product: libxkbcommon Reporter: Gatis Paeglis <gatis.paeglis>
Component: GeneralAssignee: Daniel Stone <daniel>
Status: RESOLVED FIXED QA Contact: Ran Benita <ran234>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: 0001-keysym-add-xkb_keysym_to_-lower-upper.patch
0002-test-interactive-use-xkb_state_key_get_one_sym-when-.patch
0003-state-apply-capitalization-transformation-on-keysyms.patch

Description Gatis Paeglis 2013-07-22 11:49:54 UTC
Test case:

1) First I had to update xkb config data in libxkbcommon/test/data, which i 
retrieved from http://cgit.freedesktop.org/xkeyboard-config/

2) Generate a swiss keymap file:
   setxkbmap -layout ch -v fr -print > test.xkb

3) Run the 'interactive' test from libxkbcommon/test:
   sudo ./test/interactive -k test.xkb

a) Enter the following characters:

ö, ä and ü (to enter these hold down the shift button)
é à and è 

The above works as expected. 

b) Switch on 'Caps Lock'

Regular characters are capitalized -> expected.
Type a -> A
Type b -> B

The charecers from the step a) are not capitalized -> not expected. 
Type ö -> ö

This was reported in Qt5 https://bugreports.qt-project.org/browse/QTBUG-31712
Comment 1 Gatis Paeglis 2013-07-22 12:21:20 UTC
Output:

keysyms [ egrave           ] unicode [ è ] group [ French (Switzerland) (0) ] mods [ Lock ] leds [ Caps Lock ] 
keysyms [ eacute           ] unicode [ é ] group [ French (Switzerland) (0) ] mods [ Lock ] leds [ Caps Lock ] 
keysyms [ A                ] unicode [ A ] group [ French (Switzerland) (0) ] mods [ -Lock ] leds [ Caps Lock ] 
keysyms [ S                ] unicode [ S ] group [ French (Switzerland) (0) ] mods [ -Lock ] leds [ Caps Lock ]
Comment 2 Ran Benita 2013-07-22 19:27:23 UTC
Hmm, this is this thing here:
http://www.x.org/releases/current/doc/kbproto/xkbproto.html#default_symbol_transformations

And the Xlib implementation:
http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/xkb/XKBBind.c?id=6d926088d80a08e13e6d6c4ff207b81ad52e667f#n572

In short: if Caps Lock is active and was not consumed, the keysym needs to be capitalized... how unfortunate.

I was under the impression that this was not an issue, since all of the capitalization rules were already present in the xkeyboard-config keymaps themselves (i.e. written in a level the layout). But I guess not.

Note that the spec allows two ways of doing this transformation: locate sensitive and locale insensitive. We already have the tables for the latter (in keysym.c) as the are given in the spec; but Xlib does the former as far as I can tell.

Also note that Xlib separates the two things (at least in some functions), i.e. you can get the untransformed keysym with e.g.
    XkbLookupKeysym, XkbTranslateKeyCode
and then you can transform them separately (you need to pass the mods though), e.g. with
    XkbTranslateKeySym.

I'm not entirely sure what best to do here..

- Use the built-in tables or do some locale sensitive lookups with glibc or whatever?

- Always do the transformation, or with a keymap flag, or another function? (note that xkb_keymap_key_get_syms returns a const array so it'd be hard to change that).

- Or we can punt this entirely to the application. Expose xkb_keysym_to_upper/lower. And then the logic can be implemented outside with

   if (mod_index_is_active(CAPS) && !mod_index_is_consumed(CAPS))
        keysym = xkb_keysym_to_upper(keysym)
   etc.

- Or we can do nothing and ask that all of these rules be put directly in the xkeyboard-config symbols files.

Daniel, what do you think?
Comment 3 Ran Benita 2013-08-13 13:02:11 UTC
Since we can't touch the return value of xkb_state_key_get_syms() (because it returns a pointer to const data), and this functionality doesn't make much sense for multiple-keysyms anyway, one option would be:

- xkb_state_key_get_one_sym() does the transformation.

- xkb_state_key_get_syms() doesn't do the transformation, i.e. it returns "raw" keysyms (hopefully, hmm, when mutliple-keysyms become useful, the keymap authors would have the good sense to not rely on the CapsLock "feature").

- xkb_state_mod_index_is_consumed() - to me it makes sense to report Caps consumed when the keysym is changed, but Xlib doesn't, and there's also the Control thing. So probably should stay unconsumed.

Of course we'd need to document this, since then _get_one_sym() becomes more than just a convenience.
Comment 4 Ran Benita 2013-08-13 17:29:50 UTC
Created attachment 84022 [details] [review]
0001-keysym-add-xkb_keysym_to_-lower-upper.patch

Here are patches along the comment above. I'll apply them unless there's a problem.

Gatis, QT uses xkb_state_key_get_one_sym(), if I remember correctly, so that should be fine. Other people who use xkb_state_key_get_syms() and want this functionality would have to adapt I'm afraid.
Comment 5 Ran Benita 2013-08-13 17:30:20 UTC
Created attachment 84023 [details] [review]
0002-test-interactive-use-xkb_state_key_get_one_sym-when-.patch
Comment 6 Ran Benita 2013-08-13 17:30:39 UTC
Created attachment 84024 [details] [review]
0003-state-apply-capitalization-transformation-on-keysyms.patch
Comment 7 Ran Benita 2013-08-15 07:30:24 UTC
These are now in master.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.