[BUG]? keyboard events deliver unicode = 0 on release (regression after 1.2.9 release)

Hi,

not sure if it is a bug, but there’s a significant change in keyboard
events from version 1.2.9 to 1.2.10, and it’s not mentioned in WhatsNew.

Linux 2.6.16.7 (x86/P4)
libc 2.3.5 (20050802)
gcc 4.0.2 20050901 (prerelease) (SUSE Linux)
Xorg X11R6.9 (6.8.99.904)
KDE (svn/head)

I’ve put this message in a polling event loop under branches SDL_KEYDOWN
and SDL_KEYUP:

cerr << e.key.keysym.unicode << ’ ’ << e.key.keysym.sym << ’ ’ << (e.key.state == SDL_PRESSED) << endl;

and got these results for pressing an releasing the b-key, the [-key, and
the {-key == shift-[-key (with SDL_EnableUNICODE(1)):

     1.2.9           1.2.10/cvs====================================

b 98 98 1 98 98 1
98 98 0 0 98 0

[ 91 91 1 91 91 1
91 91 0 0 91 0

{ 0 303 1 0 303 1 right shift press
123 91 1 123 91 1 [ press
123 91 0 0 91 0 [ release
0 303 0 0 303 0 right shift release

The fact that now the unicode member is 0 on release doesn’t make sense
to me, so I assume it’s a bug. Especially the fact that the 123-release
doesn’t even contain number 123 in either unicode or sym makes 1.2.10/cvs
barely usable. (Or did I miss something?)

m.

Melchior FRANZ wrote:

The fact that now the unicode member is 0 on release doesn’t make sense
to me, so I assume it’s a bug.

As far as I know, this is the intended behavior, and the previous
behavior was a bug. It makes perfect sense to me that way - after all,
key releases don’t generate characters, and the unicode field is meant
to answer “what character, if any, does that event generate?”.

What does your code do that is broken by the new behavior?

-Christian

  • Christian Walther – Thursday 27 April 2006 12:46:

Melchior FRANZ wrote:

The fact that now the unicode member is 0 on release doesn’t make sense
to me, so I assume it’s a bug.

As far as I know, this is the intended behavior, and the previous
behavior was a bug.

What does your code do that is broken by the new behavior?

It’s the FlightGear flight simulator (http://www.flightgear.org/). We
use the previous (“sane”) behavior to detect, for example, when the {-key
was pressed and when it was released. Now we only get the {-pressed message
followed by an [-released message, which is, of course, nonsense. How
would we now detect {-released? Write some extra code that knows that
Shift-[ is the same as { on some platforms/keyboards? Isn’t this the
job of a cross-platform library, to free us from such worries?

It makes perfect sense to me that way - after all,
key releases don’t generate characters, and the unicode field is meant
to answer “what character, if any, does that event generate?”.

And in which way would the new (“insane”) behavior be an advantage?
To protect programmers from interpreting a key-release as key-press?

     1.2.9           1.2.10/cvs====================================

{ 0 303 1 0 303 1 right shift press
123 91 1 123 91 1 [ press
123 91 0 0 91 0 [ release
0 303 0 0 303 0 right shift release

m.

And in which way would the new (“insane”) behavior be an advantage?
To protect programmers from interpreting a key-release as key-press?

The new behaviour isn’t “insane”, it just stopped being English-centric.

If it takes three keypresses to produce, say, a specific Japanese
character, which unicode value should we report when the user starts
taking fingers off keys? Or even: what should we report when someone
lets go of shift before ‘[’? Should it be a ‘{’ press and a ‘[’ release?
In this case, there’s stick a “stuck” key to be dealt with.

There was concern that changing it would break someone’s code, and
unfortunately, you seem to be one of the unlucky ones.

What you want to do is avoid event.key.keysym.unicode when you really
want event.key.keysym.sym, which corresponds to individual physical
keys. The unicode field is only useful when the user is entering actual
text that you are concerned about, and not when using the keyboard as a
101-button joystick.

–ryan.

  • Ryan C. Gordon – Thursday 27 April 2006 13:35:
    Thanks for the explanation. That makes some sense, but …

What you want to do is avoid event.key.keysym.unicode when you really
want event.key.keysym.sym, which corresponds to individual physical
keys.

but we still need to refer to the symbols printed on the key caps.
Shift-[ isn’t the same as { on all keyboard. Now, this would be
English-centric, if we assumed that. So using the unicode symbol
made fgfs aware of other non-English keyboards. And that stopped
working. How are others handling this?

m.

  • Ryan C. Gordon – Thursday 27 April 2006 13:35:>

Or even: what should we report when someone
lets go of shift before ‘[’? Should it be a ‘{’ press and a ‘[’ release?

Well, the same that I’ll have to implement in FlightGear now: keep
track of key states and send the missing release/press messages on
modifier changes etc. And other projects will have to re-invent that
wheel. Kind of defeats the purpose of a “cross-platform multimedia
library”. But for now we’ll just require SDL <1.2.10 or glut (SDL is
a compile time option. Glut is default.)

m. :expressionless:

Just as a side note:

Ryan C. Gordon wrote:

… event.key.keysym.sym, which corresponds to individual physical
keys.

Unfortunately, that’s not true. It is in the DirectX backend, but not in
the Quartz and X11 backends (not sure about windib - it wasn’t either
when I tested it, but it may have changed since). In the latter, it
corresponds to the symbol printed on the key cap (according to the OS’s
keymap), not to the physical key. As far as I understand, that’s how Sam
wants it to work, although I’d find the other behavior more useful.

(Here are some of the threads in which the issue has been discussed:
http://search.gmane.org/?query=key&email=cwalther%40gmx.ch&group=gmane.comp.lib.sdl)

-Christian

Hello !

Unfortunately, that’s not true. It is in the DirectX backend, but not in
the Quartz and X11 backends (not sure about windib - it wasn’t either when
I tested it, but it may have changed since). In the latter, it
corresponds to the symbol printed on the key cap (according to the OS’s
keymap), not to the physical key. As far as I understand, that’s how Sam
wants it to work, although I’d find the other behavior more useful.

Personally for me it is also more important to make sure
that if i print “user please press z” that user presses the
key with the “z” on it. For me it is not important if this is the
same physical key as on my keyboard. Even the simple difference
with “y” and “z” on a german and american keyboard can confuse
users, when i print “press z” and they have to press “y”.

CU

Torsten Giebl wrote:

Personally for me it is also more important to make sure
that if i print “user please press z” that user presses the
key with the “z” on it. For me it is not important if this is the
same physical key as on my keyboard. Even the simple difference
with “y” and “z” on a german and american keyboard can confuse
users, when i print “press z” and they have to press “y”.

Sure. Don’t do that. Here’s what you would do if SDL had the physical
key codes I would prefer:

SDL_scancode keyForActionXYZ = SDL_sc_Y; //this constant would refer to
the Y key on a US keyboard and to the Z key on a german keyboard, it
could also be called something like SDL_sc_alphanum_row2_key6
//ideally, this variable should be user-customizable

print(“please press the %s key”, SDL_KeyDescription(keyForActionXYZ));

while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.scancode) {
case keyForActionXYZ:
doXYZ();
break;
}
break;
}
}

Alternatively, if what you want the user to do is better described by
"enter a ‘z’ character" than by “press the middle key of the second
row”, use the unicode field.

-Christian

Hello !

Okay, it would be nice to have a physical key way.
But is this really necessary ?

In a Text App you use Unicode and in a game
you use just a few buttons like TAB, CTRL and so on.

Row 6, … could also confuse users that have many EXTRA
keys, like on todays modern keyboards.

CU

Torsten Giebl wrote:

Okay, it would be nice to have a physical key way.
But is this really necessary ?

For one, it would be useful for people developing emulators (of devices
with PC-style keyboards). Right now, they usually use
event.key.keysym.scancode (which is hardware/OS dependent) and map it to
a universal code using platform-specific lookup tables. Which means the
keyboard only works properly on platforms for which they have lookup
tables. It would be nice if SDL would take that work off them.

Also, in games: Say the game’s developer, working on a US keyboard, has
chosen the default key configuration to be A for “forward” and Z for
"backward". It would be nice if this would automatically adjust to A and
Y on my Swiss German keyboard, where the key below A is Y, and Z is in a
completely different place.

In a Text App you use Unicode and in a game
you use just a few buttons like TAB, CTRL and so on.

Most games I know use lots of letter keys…

Row 6, … could also confuse users that have many EXTRA
keys, like on todays modern keyboards.

I’m not saying that you should present anything about “Row 6” to the
user. When you talk to the user, you refer to a key by “A”, “Z”, “tab”,
“1”, “ctrl”, “space”. This is what you get from the hypothetical
SDL_KeyDescription() function. (One problem is that these descriptions
should be localized. Do we put the burden of mapping these english
strings to localized versions on the app developer?)

(It’s probably high time I start delivering some code on this topic
instead of just whining about it…)

-Christian

Also, in games: Say the game’s developer, working on a US keyboard, has
chosen the default key configuration to be A for “forward” and Z for
"backward". It would be nice if this would automatically adjust to A and
Y on my Swiss German keyboard, where the key below A is Y, and Z is in a
completely different place.

By the way, most games simply have a localized key mapping file to handle this.

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment