After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 165385 - Win32 keyboard handling still incomplete
Win32 keyboard handling still incomplete
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Win32
unspecified
Other Windows
: Normal normal
: Medium fix
Assigned To: gtk-win32 maintainers
gtk-bugs
: 588131 634746 (view as bug list)
Depends on: 371371
Blocks: 715061
 
 
Reported: 2005-01-27 08:41 UTC by Tor Lillqvist
Modified: 2017-01-23 19:05 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GDK W32: Handle CapsLock as part of the key shift level (gtk-3-22) v1 (18.97 KB, patch)
2017-01-04 04:39 UTC, LRN
committed Details | Review

Description Tor Lillqvist 2005-01-27 08:41: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 ;-)
Comment 1 Tor Lillqvist 2005-03-02 08:19:24 UTC
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.
Comment 2 Tor Lillqvist 2007-04-12 14:24:02 UTC
Btw, the keyboard layout demo is now at
http://www.microsoft.com/globaldev/reference/keyboards.mspx
Comment 3 Tor Lillqvist 2009-09-28 18:06:39 UTC
*** Bug 588131 has been marked as a duplicate of this bug. ***
Comment 4 Tor Lillqvist 2010-11-15 08:01:12 UTC
*** Bug 634746 has been marked as a duplicate of this bug. ***
Comment 5 Nils Andresen 2012-08-16 12:18:22 UTC
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...
Comment 6 el.nexo 2013-05-05 22:27:49 UTC
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).
Comment 7 kai.reichert 2014-06-26 08:36:29 UTC
Still not fixed :-(

Just test it with gtk3-demo.exe from http://www.gtk.org/download/win32.php.
Comment 8 Michal Vašut 2014-11-04 14:30:51 UTC
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.
Comment 9 Roman Polach 2016-12-28 18:33:57 UTC
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...
Comment 10 LRN 2016-12-28 19:22:14 UTC
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.
Comment 11 Roman Polach 2017-01-03 08:23:25 UTC
I installed MSYS2 in Win10 (32bit) and mingw-w64-i686-gtk3 into it,
but no gtk3-demo or gtk3-widget-factory is available...
Comment 12 Roman Polach 2017-01-03 16:15:20 UTC
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).
Comment 13 Michal Vašut 2017-01-03 17:08:57 UTC
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
Comment 14 LRN 2017-01-04 02:23:09 UTC
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".
Comment 15 LRN 2017-01-04 04:39:09 UTC
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.
Comment 16 Michal Vašut 2017-01-04 06:59:32 UTC
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.
Comment 17 LRN 2017-01-04 07:33:06 UTC
(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.
Comment 18 Roman Polach 2017-01-04 07:38:34 UTC
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?
Comment 19 LRN 2017-01-04 07:50:41 UTC
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.
Comment 20 Ignacio Casal Quinteiro (nacho) 2017-01-06 10:14:41 UTC
Review of attachment 342808 [details] [review]:

No comments from my side. if it works go for it.
Comment 21 LRN 2017-01-06 10:27:34 UTC
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.
Comment 22 Fan, Chun-wei 2017-01-10 07:19:35 UTC
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!
Comment 23 LRN 2017-01-10 08:09:01 UTC
Attachment 342808 [details] pushed into gtk-3-22 as ca79296061e2ddc0a2738a1fba4e9aa495d71d56
Comment 24 Roman Polach 2017-01-23 07:48:48 UTC
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?
Comment 25 LRN 2017-01-23 19:05:07 UTC
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.