Gecko Keypress Event

  • Revision slug: Gecko_Keypress_Event
  • Revision title: Gecko Keypress Event
  • Revision id: 167527
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment add minversion header

Revision Content

{{template.Fx_minversion_header(3)}} Gecko 1.9 key handling was changed drastic after Beta 5 ({{template.Bug(359638)}}, {{template.Bug(429510)}} and their blocker bugs). That was too risky changes, and too late changes. However, Gecko developers didn't have other ways for fixing the many key handling bugs.

charCode of DOM keypress event

If an keypress event is fired without any modifier keys (Ctrl/Alt(Option)/Meta(Win/Command)), the event details are not changed from Gecko1.8.1.

charCode property has an Unicode character that is inputted by the current keyboard layout of the current keyboard state (E.g., CapsLock state and NumLock state).

Otherwise, the charCode value is replaced to an ASCII characters as following rules.

First, the acceleration key depends on the platform. Ctrl key is an acceleration key on Windows and Linux. However, Meta key is an acceleration key on Mac (it is called "Command key" on Mac).

When the acceleration key is pressed, the charCode of the event may be replaced only when the character is not an ASCII character.

This behavior helps the internationalization of web applications that has some custom shortcut keys themselves. If Gecko don't replace the charCode to an ASCII character, the web application developers need to think the non-Latin keyboard layout users (E.g., Arabic, Greek, Hebrew and Russian).

The charCode value depends on the CapsLock state and NumLock state (They are ignored if Alt key is pressed on Mac, see {{template.Bug(432953)}}). And there are some differences between the platforms, see following sections.

Windows

The charCode is replaced only when Ctrl key is pressed but Alt key is not pressed.

However, if the inputting character cannot be inputted without Ctrl key, then, Gecko doesn't replace the character. E.g., Ctrl+Shift+'2' on Persian keyboard layout inputs a ZWNJ. But Shift+'2' inputs '@'. Therefore, if Gecko replaces the charCode at this case, the users cannot input ZWNJ ({{template.Bug(414130)}}).

Otherwise, Gecko can replace the charCode to an ASCII characters, basically. However, Gecko replaces the charCode only when the pressed key is an alphabet key (VK_A to VK_Z) or a numeric key (VK_0 to VK_9) or a Plus sign key (VK_OEM_PLUS) or a Minus sign key (VK_OEM_MINUS).

Note that the other characters that are inputted by the numeric key or the Plus sign key or the Minus sign key are not set to charCode if the key inputs non-ASCII character. So, there are some accessibility issues for non-Latin keyboard layout users. That means that the web application developers should only use alphabets, numeric, plus sign and minus sign for the custom shortcut keys.

Linux

The charCode is replaced only when Ctrl key is pressed but Alt key and Meta key are not pressed.

If the inputting character cannot be inputted without Ctrl key, then, Gecko doesn't replace the character, like Windows.

Mac

The charCode is replaced when Meta key (Command key) or Ctrl key is pressed. Note that the Alt key (Option key) doesn't suppress the replacing like other platforms. Because the Alt key of Mac is just changing the keyboard state like Shift key.

If the current keyboard layout is Dvorak-QWERTY layout or non-Latin layout, Command key switches the keyboard layout to US keyboard layout temporary. Gecko uses the switched keyboard layout for Ctrl key too.

However, when Ctrl key is pressed, Gecko 1.9 replaces the charCode only when the inputted key means an ASCII alphabet. This behavior is a bug, this behavior will be changed in future major release ({{template.Bug(432951)}}).

Alternative charCodes for internal

This section is a document only for Gecko internal keypress event handling, therefore, web application developers don't need to read this section.

Gecko replaces the charCode of DOM keypress event for acceleration key handling, however, that is not enough.

Problem 1

The Zoom-in shortcut key of Firefox defined as <key key="+" modifiers="accel"/>. However, Shift key is needed for inputting '+' on US keyboard layout. Therefore, only the key element, US keyboard layout users cannot use the shortcut. Therefore, we also defined <key key="=" modifiers="accel"/> for US keyboard layout. However, this is not enough for other keyboard layout users. E.g., on Japanese keyboard layout, '+' is inputted by Shift+';'. So, we cannot solve this issue with the key element duplication approach ({{template.Bug(339723)}}).

Problem 2

The access keys for the menu items are specified with the localized characters on some localized builds. These localized access keys work fine with the keyboard layout of the locale. However, same user cannot use access keys on En-US build that includes nightly builds ({{template.Bug(399939)}}).

Problem 3

The non-Latin keyboard layout users cannot use the Latin alphabet access keys on web contents ({{template.Bug(399939)}}).

Problem 4

Shift key is need to access the access keys of web contents on Windows and Linux. Therefore, the users cannot use some characters that are inputted without Shift key. So, the unusable characters depend on the keyboard layout ({{template.Bug(359638)}}).

Solution

There are following rules:

  • The key handlers should be able to know the all meanings of the event.
  • The inner element handler should consume the non-exact matching key event even if the outer element handler can match exactly ({{template.Bug(433192)}}).
  • At access key handling, the handlers should ignore the Shift key state. However, the character that can be inputted without Shift key is preferred.
  • At shortcut key handling, if the event is fired with Shift key, but the alternative charCode is not a case changeable character (i.e., it is not an alphabet), then, Shift key state should be ignored if there are not exact matching handler. (When Alt key of Mac is pressed, the behavior should be similar, but it is not implemented on Gecko 1.9, See {{template.Bug(306585)}}).
  • At shortcut key handling, if the inputted character is case changeable character (i.e., an alphabet), the Shift key should not be ignored always. I.e., Ctrl+Shift+'C' should not execute Ctrl+'C'.
  • At shortcut key handling, when Shift key is not pressed and the character without Shift key is not numeric but the character with Shift key is numeric, the key may be the numeric keys of AZERTY keyboard layout (E.g., French), then the numeric should be a low priority shortcut key candidate ({{template.Bug(429219)}}).

So, these conditions are too complex. And the handling rules will be improved if we find new problems. Therefore, XUL application developers should use key element for handling a shortcut key, so, they should not handle it on keypress event themselves. And also they should use accesskey attribute for access keys, so, they should not also handle it on keypress event too.

So, if XUL application developers handle themselves, they also need to change the handling code every time when the rules are changed. That is not smart implementation.

Implementation

The native keypress event has all meanings of the key. They are set to nsKeyEvent::alternativeCharCodes in nsGUIEvent.h. However, the most Gecko developers should not access to this directly. The priority between the alternative charCodes are too complex. The most Gecko developers should use nsContentUtils::GetAccelKeyCandidates() for shortcut keys handling, and nsContentUtils::GetAccessKeyCandidates() for access keys handling (See nsContentUtils.h and nsContentUtils.cpp).

Revision Source

<p>{{template.Fx_minversion_header(3)}}
Gecko 1.9 key handling was changed drastic after Beta 5 ({{template.Bug(359638)}}, {{template.Bug(429510)}} and their blocker bugs). That was too risky changes, and too late changes. However, Gecko developers didn't have other ways for fixing the many key handling bugs.
</p>
<h3 name="charCode_of_DOM_keypress_event"> <code>charCode</code> of DOM keypress event </h3>
<p>If an keypress event is fired without any modifier keys (<kbd>Ctrl</kbd>/<kbd>Alt</kbd>(<kbd>Option</kbd>)/<kbd>Meta</kbd>(<kbd>Win</kbd>/<kbd>Command</kbd>)), the event details are not changed from Gecko1.8.1.
</p><p><code>charCode</code> property has an Unicode character that is inputted by the current keyboard layout of the current keyboard state (E.g., <kbd>CapsLock</kbd> state and <kbd>NumLock</kbd> state).
</p><p>Otherwise, the <code>charCode</code> value is replaced to an ASCII characters as following rules.
</p><p>First, the acceleration key depends on the platform. <kbd>Ctrl</kbd> key is an acceleration key on Windows and Linux. However, <kbd>Meta</kbd> key is an acceleration key on Mac (it is called "Command key" on Mac).
</p><p>When the acceleration key is pressed, the <code>charCode</code> of the event may be replaced <b>only</b> when the character is not an ASCII character.
</p><p>This behavior helps the internationalization of web applications that has some custom shortcut keys themselves. If Gecko don't replace the <code>charCode</code> to an ASCII character, the web application developers need to think the non-Latin keyboard layout users (E.g., Arabic, Greek, Hebrew and Russian).
</p><p>The <code>charCode</code> value depends on the <kbd>CapsLock</kbd> state and <kbd>NumLock</kbd> state (They are ignored if <kbd>Alt</kbd> key is pressed on Mac, see {{template.Bug(432953)}}). And there are some differences between the platforms, see following sections.
</p>
<h4 name="Windows"> Windows </h4>
<p>The <code>charCode</code> is replaced only when <kbd>Ctrl</kbd> key is pressed but <kbd>Alt</kbd> key is <b>not</b> pressed.
</p><p>However, if the inputting character cannot be inputted without <kbd>Ctrl</kbd> key, then, Gecko doesn't replace the character. E.g., <kbd>Ctrl+Shift+'2'</kbd> on Persian keyboard layout inputs a ZWNJ. But <kbd>Shift+'2'</kbd> inputs '@'. Therefore, if Gecko replaces the <code>charCode</code> at this case, the users cannot input ZWNJ ({{template.Bug(414130)}}).
</p><p>Otherwise, Gecko can replace the <code>charCode</code> to an ASCII characters, basically. However, Gecko replaces the <code>charCode</code> only when the pressed key is an alphabet key (<code>VK_A</code> to <code>VK_Z</code>) or a numeric key (<code>VK_0</code> to <code>VK_9</code>) or a Plus sign key (<code>VK_OEM_PLUS</code>) or a Minus sign key (<code>VK_OEM_MINUS</code>).
</p><p>Note that the other characters that are inputted by the numeric key or the Plus sign key or the Minus sign key are not set to <code>charCode</code> if the key inputs non-ASCII character. So, there are some accessibility issues for non-Latin keyboard layout users. That means that the web application developers should only use alphabets, numeric, plus sign and minus sign for the custom shortcut keys.
</p>
<h4 name="Linux"> Linux </h4>
<p>The <code>charCode</code> is replaced only when <kbd>Ctrl</kbd> key is pressed but <kbd>Alt</kbd> key and <kbd>Meta</kbd> key are <b>not</b> pressed.
</p><p>If the inputting character cannot be inputted without <kbd>Ctrl</kbd> key, then, Gecko doesn't replace the character, like Windows.
</p>
<h4 name="Mac"> Mac </h4>
<p>The <code>charCode</code> is replaced when <kbd>Meta</kbd> key (<kbd>Command</kbd> key) or <kbd>Ctrl</kbd> key is pressed. Note that the <kbd>Alt</kbd> key (<kbd>Option</kbd> key) doesn't suppress the replacing like other platforms. Because the <kbd>Alt</kbd> key of Mac is just changing the keyboard state like <kbd>Shift</kbd> key.
</p><p>If the current keyboard layout is Dvorak-QWERTY layout or non-Latin layout, <kbd>Command</kbd> key switches the keyboard layout to US keyboard layout temporary. Gecko uses the switched keyboard layout for <kbd>Ctrl</kbd> key too.
</p><p>However, when <kbd>Ctrl</kbd> key is pressed, Gecko 1.9 replaces the <code>charCode</code> only when the inputted key means an ASCII alphabet. This behavior is a bug, this behavior will be changed in future major release ({{template.Bug(432951)}}).
</p>
<h3 name="Alternative_charCodes_for_internal"> Alternative <code>charCode</code>s for internal </h3>
<p>This section is a document only for Gecko internal keypress event handling, therefore, web application developers don't need to read this section.
</p><p>Gecko replaces the <code>charCode</code> of DOM keypress event for acceleration key handling, however, that is not enough.
</p>
<h4 name="Problem_1"> Problem 1 </h4>
<p>The Zoom-in shortcut key of Firefox defined as <code>&lt;key key="+" modifiers="accel"/&gt;</code>. However, <kbd>Shift</kbd> key is needed for inputting <kbd>'+'</kbd> on US keyboard layout. Therefore, only the key element, US keyboard layout users cannot use the shortcut. Therefore, we also defined <code>&lt;key key="=" modifiers="accel"/&gt;</code> for US keyboard layout. However, this is not enough for other keyboard layout users. E.g., on Japanese keyboard layout, <kbd>'+'</kbd> is inputted by <kbd>Shift+';'</kbd>. So, we cannot solve this issue with the key element duplication approach ({{template.Bug(339723)}}).
</p>
<h4 name="Problem_2"> Problem 2 </h4>
<p>The access keys for the menu items are specified with the localized characters on some localized builds. These localized access keys work fine with the keyboard layout of the locale. However, same user cannot use access keys on En-US build that includes nightly builds ({{template.Bug(399939)}}).
</p>
<h4 name="Problem_3"> Problem 3 </h4>
<p>The non-Latin keyboard layout users cannot use the Latin alphabet access keys on web contents ({{template.Bug(399939)}}).
</p>
<h4 name="Problem_4"> Problem 4 </h4>
<p><kbd>Shift</kbd> key is need to access the access keys of web contents on Windows and Linux. Therefore, the users cannot use some characters that are inputted without <kbd>Shift</kbd> key. So, the unusable characters depend on the keyboard layout ({{template.Bug(359638)}}).
</p>
<h4 name="Solution"> Solution </h4>
<p>There are following rules:
</p>
<ul><li> The key handlers should be able to know the all meanings of the event.
</li><li> The inner element handler should consume the non-exact matching key event even if the outer element handler can match exactly ({{template.Bug(433192)}}).
</li><li> At access key handling, the handlers should ignore the <kbd>Shift</kbd> key state. However, the character that can be inputted without <kbd>Shift</kbd> key is preferred.
</li><li> At shortcut key handling, if the event is fired with <kbd>Shift</kbd> key, but the alternative <code>charCode</code> is not a case changeable character (i.e., it is not an alphabet), then, <kbd>Shift</kbd> key state should be ignored if there are not exact matching handler. (When <kbd>Alt</kbd> key of Mac is pressed, the behavior should be similar, but it is not implemented on Gecko 1.9, See {{template.Bug(306585)}}).
</li><li> At shortcut key handling, if the inputted character is case changeable character (i.e., an alphabet), the <kbd>Shift</kbd> key should not be ignored always. I.e., <kbd>Ctrl+Shift+'C'</kbd> should not execute <kbd>Ctrl+'C'</kbd>.
</li><li> At shortcut key handling, when <kbd>Shift</kbd> key is not pressed and the character without <kbd>Shift</kbd> key is not numeric but the character with <kbd>Shift</kbd> key is numeric, the key may be the numeric keys of AZERTY keyboard layout (E.g., French), then the numeric should be a low priority shortcut key candidate ({{template.Bug(429219)}}).
</li></ul>
<p>So, these conditions are too complex. And the handling rules will be improved if we find new problems. Therefore, XUL application developers should use <code>key</code> element for handling a shortcut key, so, they should <b>not</b> handle it on <code>keypress</code> event themselves. And also they should use <code>accesskey</code> attribute for access keys, so, they should <b>not</b> also handle it on <code>keypress</code> event too.
</p><p>So, if XUL application developers handle themselves, they also need to change the handling code <b>every time</b> when the rules are changed. That is not smart implementation.
</p>
<h4 name="Implementation"> Implementation </h4>
<p>The native keypress event has all meanings of the key. They are set to <code>nsKeyEvent::alternativeCharCodes</code> in <a class="external" href="http://mxr.mozilla.org/mozilla/source/widget/public/nsGUIEvent.h">nsGUIEvent.h</a>. However, the most Gecko developers should not access to this directly. The priority between the alternative <code>charCode</code>s are too complex. The most Gecko developers should use <code>nsContentUtils::GetAccelKeyCandidates()</code> for shortcut keys handling, and <code>nsContentUtils::GetAccessKeyCandidates()</code> for access keys handling (See <a class="external" href="http://mxr.mozilla.org/mozilla/source/content/base/public/nsContentUtils.h">nsContentUtils.h</a> and <a class="external" href="http://mxr.mozilla.org/mozilla/source/content/base/src/nsContentUtils.cpp">nsContentUtils.cpp</a>).
</p>
Revert to this revision