GNOME Bugzilla – Bug 165385
Win32 keyboard handling still incomplete
Last modified: 2017-01-23 19:05:07 UTC
Even after fixing bug #161814, which was relatively simple, and corrected the behaviour of the CapsLock key on French keyboards and others where CapsLock simply acts as as ShiftLock, there are still some keyboard layouts that aren't properly handled. For more information about Windows and keyboards, see for instance http://weblogs.asp.net/michkap/archive/2005/01/25/360240.aspx and http://www.microsoft.com/globaldev/handson/dev/Unicode-KbdsonWindows.pdf . With IE, one can use the on-line keyboard layout demo at http://www.microsoft.com/globaldev/reference/keyboards.aspx . Or just add more keyboard layouts (input locales) in the Control Panel's Regional Settings, and switch to them in WordPad, for instance. Try for instance the Czech keyboard layout, and check the behaviour of the keys in the top ("digits") row with respect to Shift and CapsLock. The current mechanism in gdkkeys-win32.c is not enough to describe their behaviour. There is no way in a GTK+ application (well, except the hex unicode code point mechanism) to enter for instance LATIN CAPITAL LETTER S WITH CARON with the Czech keyboard. Presumably for Czech users this can be a real problem. In correctly behaving Windows applications it is generated by toggling CapsLock and typing the "3" key. (In the base state, this key generates LATIN SMALL LETTER S WITH CARON. With Shift, it generates DIGIT THREE. And with CapsLock, it generates LATIN CAPITAL LETTER S WITH CARON. With both Shift and CapsLock, you also get DIGIT THREE. According to the pdf file above, it is tecnically possible to have three additional "shift" keys (in addition to Shift, Control, AltGr and CapsLock, presumably), but only the Canadian Multilingual keyboard uses even one additional shift key. (It seems to be the right Control key, check it out in the on-line demo.) So the goal should be to make the Canadian Multilingual keyboard work fully ;-)
When fixing keyboard handling fully, remember to also check that 3rd party keyboard layouts like those apparently popular in India work. (See bug #165723). I also recall that there is a bug report mentioning some "KeyMan" software, look for that, too.
Btw, the keyboard layout demo is now at http://www.microsoft.com/globaldev/reference/keyboards.mspx
*** Bug 588131 has been marked as a duplicate of this bug. ***
*** Bug 634746 has been marked as a duplicate of this bug. ***
Tor, the "KeyMan" Bug you referred to in comment #c1 is acually bug#129295. I am no c/c++ dev, but I'm willing to try to help if I somehow can. I'm not using the Canadian Multilingual keyboard, but neo2 (http://www.neo-layout.org/) - a layout that also uses additional "shift-keys" to get 6 layers per key. Maybe I could somehow help getting this to work...
Is it legitimate to up-vote or something like that? So far I could stay away from GTK, but now I discovered an application I would really like to use. I'm in the same position as Nils Andresen -> I will help, if there is anything I could do (but also not a c dev).
Still not fixed :-( Just test it with gtk3-demo.exe from http://www.gtk.org/download/win32.php.
Please fix it - for more description look at bug 715061 (link is bellow this form in details of the bug) or ask me. I am Czech, so I can answer your questions about this bug or test it for you.
Please fix it. GIMP, Inkscape, Geany and other GTK+ software is unusable in Windows for entering longer texts in capital letters in languages such as Czech. It is difficult to explain to newbie users of GTK+ apps under Windows, that such monstrous bug is not fixed for so many years...
I did change keyboard handling code in gtk-3-22 (it should be in the latest release by now; i can confirm that gtk+-3.22.4 has the changes) and gtk-2-24 (relatively recently, not yet released, unless you get hold of a build from git). These changes might or might not have resulted in this bug being fixed. GIMP, Inkscape and other pieces of cross-platform software tend to use very outdated GTK+-2.x builds, so good luck finding a way to confirm whether this is fixed or not. Your best bet for just confirming the status of this bug is to install MSYS2 and install gtk+-3.22.4 package in it, then run gtk3-demo or gtk3-widget-factory and see if keyboard input works correctly there. If it does, it likely works in gtk2 as well, and you can go nag application developers to update their bundled gtk+ binaries. If it doesn't, then you will be able to tell me exactly which keys to press (mind, my physical keyboard has only English markings, so explain things to me in terms of English (US) layout), in which layout (layouts available on Windows 10 from MS are preferable; custom 3rd-party layouts are not, unless you also explain how to install them) what is the expected result, and what you actually get.
I installed MSYS2 in Win10 (32bit) and mingw-w64-i686-gtk3 into it, but no gtk3-demo or gtk3-widget-factory is available...
Sorry, I used wrong menu-item. When I started shell by "32-bit" menu-item, then gtk3-* commands became available. So I tried all (gimp, gtk3-demo, gtk3-widget-factory) in MSYS2 with mingw-w64-i686-gtk3 3.22.4, but the behavior of CAPS-LOCK is still wrong. Reproduction: Windows 10 - default Czech keyboard: --- Correct behavior --- US-key "4" should type "č" (caps-lock off), "Č" (caps-lock on), US-key "5" should type "ř" (caps-lock off), "Ř" (caps-lock on), US-key "6" should type "ž" (caps-lock off), "Ž" (caps-lock on), US-key "7" should type "ý" (caps-lock off), "Ý" (caps-lock on). --- Current GTK+/Win behavior --- US-key "4" types "č" (caps-lock off), "č" (caps-lock on), US-key "5" types "ř" (caps-lock off), "ř" (caps-lock on), US-key "6" types "ž" (caps-lock off), "ž" (caps-lock on), US-key "7" types "ý" (caps-lock off), "ý" (caps-lock on).
Hello, I can confirm this bad behaviour on Windows 7 (keyboard Czech(Default)) and mingw-w64-i686-gtk3 3.22.4 (tested in gtk3-demo) US key: 2 3 4 5 6 7 8 9 0 CAPS LOCK off: ě š č ř ž ý á í é <<< on czech keyboard CAPS LOCK on: Ě Š Č Ř Ž Ý Á Í É <<< correct behaviour CAPS LOCK on: ě š č ř ž ý á í é <<< current buggy behaviour
Okay, i see. Usually, GDK-W32 handles CapsLock like this: If CapsLock does not behave as ShiftLock (Czech keyboard layout does not; ShiftLock is mostly for writing systems that do not have uppercase characters, and where CapsLock is used to produce completely different characters, instead of just uppercasing, AFAIU) AND Shift is not pressed AND CapsLock is toggled AND AltGr is not pressed: take the character produced by the <key> and uppercase it. If uppercase character is the same as we would get with Shift+<key>, use that uppercase character instead. This test is clearly insufficient to correctly identify the cases where a character should be uppercased by a toggled CapsLock. I think that the simplest fix is to just extend the keymap levels with CapsLock. This will make keymap table twice as large, and will probably increase the initialization time (as we would need twice as much W32 API calls), but should produce the right behaviour. As long as i don't screw up the logic. Levels would look like this: GDK_WIN32_LEVEL_NONE = 0, GDK_WIN32_LEVEL_SHIFT, GDK_WIN32_LEVEL_CAPSLOCK, GDK_WIN32_LEVEL_SHIFT_CAPSLOCK, GDK_WIN32_LEVEL_ALTGR, GDK_WIN32_LEVEL_SHIFT_ALTGR, GDK_WIN32_LEVEL_CAPSLOCK_ALTGR, GDK_WIN32_LEVEL_SHIFT_CAPSLOCK_ALTGR, GDK_WIN32_LEVEL_COUNT That way level+1 means "same thing, just with Shift", and level+2 means "same thing, just with CapsLock", and level+3 is "same thing, but with both Shift and CapsLock".
Created attachment 342808 [details] [review] GDK W32: Handle CapsLock as part of the key shift level (gtk-3-22) v1 Instead of using some kind of flawed logic about modifying a keypress result when CapsLock is toggled, just add a CapsLock shift level (and all derived shift levels, i.e. Shift+CapsLock and CapsLock+AltGr and Shift+CapsLock+AltGr) and query Windows keyboard layout API about the result of keypresses involving CapsLock. Keysym table is going to be (roughly) twice as large now, but CapsLock'ed keypresses will give correct results for some keyboard layouts (such as Czech keyboard layout, which without this change produces lowercase letters for CapsLock->[0,2,3,4...] instead of uppercase ones). Keymap update time also increases accordingly.
Sorry guys I forgot to mention another two keys with 'ú' and 'ů', my bad. So complete keyset is: US key: 2 3 4 5 6 7 8 9 0 [ ; Czech keyboard NONE: ě š č ř ž ý á í é ú ů <<< correct SHIFT: 2 3 4 5 6 7 8 9 0 / " <<< correct CAPSLOCK: Ě Š Č Ř Ž Ý Á Í É Ú Ů <<< correct CAPSLOCK: ě š č ř ž ý á í é ú ů <<< current buggy behaviour SHIFT_CAPSLOCK: 2 3 4 5 6 7 8 9 0 / " <<< correct Another note: [0,2,3,4...] keys are bellow F-keys, not those at numeric keyboard . Please take it into account before designing the solution. And once again sorry for incomplete bug description.
(In reply to Michal Vašut from comment #16) > > Another note: [0,2,3,4...] keys are bellow F-keys, not those at numeric > keyboard . > > Please take it into account before designing the solution. And once again > sorry for incomplete bug description. Don't worry, i do understand which numeric keys you mean. Also, i don't do narrow keyboard-input handling code and don't hardcode any keyboard layout behaviour. The patch above is not Czech-specific or anything, it just asks Windows Keyboard API more questions, stores the answers and uses them to handle keyboard input. It does display correct (as you've described above) behaviour for Czech keyboard layout, including the Shift+CapsLock case and the '/' and '"' keys.
Note, Gtk+ under Linux works correctly - with the same (Czech default) layout. Aren't those levels already defined somewhere in Gtk+? Or perhaps in X11?
I don't know X11 backend [well enough/at all] to give you a precise answer, but my understanding is that GDK does have good enough keyboard layout maps and/or code that can give pretty good answers about key->character relations at runtime. Problem is, Windows keyboard layouts are, AFAIU, 100% table-based, and it is not possible to 100%-correctly reflect that with just code. This is why GTK+ was unable (for years!) to handle US-International keyboard layout correctly (GDK produced special characters for some dead key combinations where Windows did not), until i've switched it to a more table-like approach last year. So the answer, it seems, that GTK+ can either do everything on its own, or it can reproduce the peculiarities of the native OS input, but not both at the same time.
Review of attachment 342808 [details] [review]: No comments from my side. if it works go for it.
The tricky part here is to fix *this* problem *and* not cause any new problems for other layouts. I only use two layouts on a regular basis, so it's not possible for me to notice that some other layout was broken due to the changes i've made. That said, i'm pretty sure that this change does not break anything. Still, i'll CC this to fanc just to be extra sure.
Hi LRN, In fact I use a QWERTY layout myself, and this is what the Chinese (Taiwan) IME is built upon, but I can say that this patch does work correctly for me, so I'd say go for it too. My take on this. With blessings, thank you, and cheers!
Attachment 342808 [details] pushed into gtk-3-22 as ca79296061e2ddc0a2738a1fba4e9aa495d71d56
Unfortunately, at least GIMP and Geany developers stated that Windows builds are based on Gtk+ 2 and this wouldn't be changed in near future. While this is not ideal state - almost 6 years after Gtk+ 3 first release, it is where we are. So, could this issue be also fixed for Gtk+ 2 please?
Yeah, i never intended this to be gtk3-only fix, just forgot to backport it. The same code is now pushed into gtk-2-24 branch as commit 516c1ba159137462dbd7709801e9aa212b05f29c.