Re: [D4E] KeyboardEvent.code and KeyboardEvent.queryKeyCap() are very strange spec

On Wed, Feb 27, 2013 at 7:10 PM, Masayuki Nakano <masayuki@d-toybox.com>wrote:

> Hello.
>
> 1. KeyboardEvent.code value is named from the unshifted character of en-US
> keyboard layout. However, this is not useful information for other locale
> developers. I think that the purpose of this value is, making identified
> value for each physical key. If so, it's not problem even if it's a just
> opaque number value. For example, it's easier to implement that UA sets
> scan code value on Windows, hardware_keycode value on GTK, native virtual
> keycode value on Mac.
>

I agree that it could just as easily be a numeric value. We originally
proposed this, but received comments that a descriptive string is more in
desirable in W3C specifications.

For context, see Mounir's "web-ier" comments in
http://lists.w3.org/Archives/Public/www-dom/2012OctDec/0030.html and my
response to Florian in
http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0176.html

With regards to the naming, note that this is pretty much what the USB spec
does - they needed a name for each key and they standardized on the en-US
names for the keys. A key difference is that the USB name was just for
descriptive purposes (since the actual codes were numeric) whereas we're
using the name as the code.

2. KeyboardEvent.queryKeyCap() works with local identifier. However, it
> doesn't make sense. For example, we can say both locales of Standard US
> keyboard layout and Dvorak keyboard layout are "en-US". Similarly, some
> other locales have two or more keyboard layouts. So, using locale
> identifier for specifying keyboard layout is really wrong idea.
>

Based on
http://unicode-inc.blogspot.com/2012/06/cldr-2102-new-t-extensions-for.html,
I would expect the dvorak layout to have a BCP-47 value of "en-t-k0-dvorak".

But you bring up a larger issue in that we're relying a lot on the BCP-47
locale values, which are more than simple keyboard layout identifiers. My
(perhaps naive) hope is that we could send these values to the OS to
resolve the lookup. Something like the following (for Windows, but I
haven't tested this):
   win_scancode = <lookup table to map from event.code to windows scancode>
   lcid = LocaleNameToLCID(locale)
   hkl = LoadKeyboardLayout(lcid)
   vk = MapVirtualKeyEx(win_scancode, MAP_VSC_TO_VK_EX)
   ch = MapVirtualKeyEx(vk, MAP_VK_TO_CHAR)

3. KeyboardEvent.queryKeyCap() takes any KeyboardEvent.code value. So, this
> method works like static class method of C++, not an instance's method.


Yes, we discussed the best location for this API, and a static method was
suggested as the best approach since a primary use-case is in a preference
dialog where there is no KeyboardEvent instance.

See Hallvord's comments in
http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0183.html

i wish that IDL had a way to mark static methods, but I didn't see a way to
do that.


> I think that this is overspec for web developers. I don't think such high
> level API is required. I think that the spec should remove
> KeyboardEvent.code attribute.


Such an API is the only way to get the information needed for a webapp to
display the character associated with a particular key. Florian discusses
some of the motivation for this in
http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0170.html and
describes why 'code' is needed to store these preferences in
http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0174.html

As for KeyboardEvent.code, it has a number of documented uses and is fairly
trivial to implement (lookup table from local scancode to "web" code).

And KeyboardEvent.queryKeyCap() works with the key of the cause of the
> event.


The 'key' value is too ambiguous to use as an identifier for a physical
key. For example, on a French keyboard a 'key' value of '2' can be
generated by the numpad '2' key or by Shift-'é'.  The keycap value returned
should be '2' and 'é', respectively.

5. I'd like to suggest KeyboardEvent.queryChar() instead of
> KeyboardEvent.code and KeyboardEvent.queryKeyCap().
> KeyboardEvent.queryChar() has two arguments, one is modifier key state
> (space separated modifier key list, if there is unknown modifier key, it
> should raise an exception). The other is a bool value whether it specifies
> current keyboard layout or current ASCII capable keyboard layout. This
> method should work only with trusted key event because untrusted key event
> cannot have raw key information internally.


Making queryXxx an instance method ignores the use case where people need
to get the char associated with a key when they don't have a KeyboardEvent
instance (for example, when showing a preferences dialog that allows a user
to set their key mappings for a game).

The whole point of the 'code' attribute is to make the "raw key
information" available *externally* in cross-platform way. There are
use-cases (most notably, games) that need this information since 'char' and
'key' are inadequate.


> If the user is using ASCII capable keyboard layout such as Japanese
> keyboard layout, then, the bool argument makes no difference for the result.
>
> Then, If KeyboardEvent.char is same as (a) and KeyboardEvent.key is same
> as (b) without any modifier key, then, https://www.w3.org/Bugs/**
> Public/show_bug.cgi?id=18341<https://www.w3.org/Bugs/Public/show_bug.cgi?id=18341>and
> https://www.w3.org/Bugs/**Public/show_bug.cgi?id=18867<https://www.w3.org/Bugs/Public/show_bug.cgi?id=18867>will be fixed simply.


If I understand it correctly, 18867 is about making char = '' (empty) for
non-printable characters (like when ctrl is held).  I don't think that's
related to this topic, but FWIW it sounds like a reasonable idea to me.

For 18341, the issues you raise are more complex (mostly to do with
documentation in the spec), but I think that the comment "The scancode
doesn't help it because the alternative key meaning cannot be resolved from
physical keycode" is now longer applicable if you consider that queryKeyCap
would be able to translate from "KeyV" to either 'v' or to 'ر' based on the
locale specified.

-Gary

Received on Friday, 1 March 2013 23:32:48 UTC