VirtualKey::GetCompositeChar() needs index of virtual keycode which may make around the caller messy. So, KeyboardLayout::GetCompositeChar() should wrap it and KeyboardLayout::MaybeInitNativeKeyWithCompositeChar() should use it.
MozReview-Commit-ID: 8KLTJpCFZ8u
--HG--
extra : rebase_source : fd13c009330fd485c8cba30f469fc645b560c623
Similar to VirtualKey::GetUniChars(), VirtualKey::GetNativeUniChars() needs key index. So, it should be wrapped by a new helper method, KeyboardLayout::GetNativeUniCharsAndModifiers(), and KeyboardEvent::InitNativeKey() should use this instead of accessing its member's GetNativeUniChars().
MozReview-Commit-ID: 7M9OlNF698Y
--HG--
extra : rebase_source : e19a5c99014a8f0a0ed7cc3a86fe0c4ee10cebb5
When InitNativeKey() retrieves UniCharsAndModifiers for a key, it needs key index for the given virtual keycode. Therefore, wrapping the code with GetUniCharsAndModifiers() makes InitNativeKey() code simpler since each call specifies the virtual keycode to the method instead of key index.
MozReview-Commit-ID: Azy8chXexaz
--HG--
extra : rebase_source : 98da43e7f542037f952206cd3db731f6cbb097e7
This patch gets rid of |shiftState| from KeyboardLayout::InitNativeKey() and make each caller clearer. This must make other developers understand what modifier state is used at each call.
MozReview-Commit-ID: 6zydP1jkffv
--HG--
extra : rebase_source : ea1d5f49ea02812aa632bdbad871688879f2b401
KeyboardLayout::InitNativeKey() is very messy because it handles a lot of cases without helper methods.
It's important to make it simpler implementation for preventing regressions caused by some patches which are written with misunderstanding. So, let's rewrite the method with helper method.
First, this patch make InitNativeKey() use IsDeadKey() instead of referring the table because calling IsDeadKey() is easier to understand.
MozReview-Commit-ID: DtN9qoh7Gz7
--HG--
extra : rebase_source : 8e769c1c88bfe646940491c111de609dbf53eeec
When NativeKey tries to remove a char message from the queue, another NativeKey instance might be created due to odd API hook or something. In such case, the old instance should handle the received message and the new instance should do nothing for keeping the order of message handling.
This patch makes:
* NativeKey::GetFollowingCharMsg() store removing char message to mRemovingMsg before calling PeekMessage() with PM_REMOVE.
* NativeKey::InitWithChar() set the old instance's mReceivedMsg to the received char message and do nothing even if HandleCharMessage() is called later.
* NativeKey::GetFollowingCharMsg() return received char message if mReceivedMsg is set during a call of PeekMessage().
MozReview-Commit-ID: KXYW0GgC9AY
--HG--
extra : rebase_source : 08472dec28e93450cd04a367843c1511cb812a9c
For detecting nested creation of NativeKey instances, NativeKey should manage the latest instance with sLastestInstance for the other instances and previous instance with mLastInstance.
MozReview-Commit-ID: BFZ0cr1640S
--HG--
extra : rebase_source : e2439a21f5984c6246283924c2013038c734ae2a
For logging message, we should have better log text generator for MSG.
Then, we can improve the note of crash reports which is appended in NativeKey::GetFollowingCharMessage().
MozReview-Commit-ID: 4sbZJaWFH2o
--HG--
extra : rebase_source : bbc3101a78e4e2aa8b5eb0f68cd6f3605ba924f6
Currently, NativeKey::DispatchPluginEventsAndDiscardsCharMessages() calls nsWindowBase::DispatchPluginEvent() and nsWindowBase::DispatchPluginEvent() does nothing when windowless plugin doesn't have focus. However, this is unclear when other developers read the code of DispatchPluginEventsAndDiscardsCharMessages() and it causes unnecessary virtual calls. So, it should try to dispatch plugin events only when a windowless plugin has focus.
For making the check safer, nsWindowBase should expose the method to check it as ShouldDispatchPluginEvent(). Unfortunately, we cannot mark this method as const due to PluginHasFocus() needs to be not const method, though. Then, for loops in DispatchPluginEventsAndDiscardsCharMessages() should check it at each try.
This change helps to log the behavior (working on bug 1297013) without noise.
Additionally, this patch renames the method to MaybeDispatchPluginEventsForRemovedCharMessages() because it doesn't remove any char messages anymore.
MozReview-Commit-ID: F14Lcx47M6U
--HG--
extra : rebase_source : 64b6da75590c99299f75358023844762198136d6
NativeKey removes odd WM_CHAR messages which are caused by ATOK or WXG if the user tries to do "Kakutei-Undo" (meaning "undo the last commit") after dispatching eKeyDown event.
However, NativeKey should remove them from the queue first because there are some problems:
* If focus is moved during dispatching an eKeyDown event, we'll fail to remove the messages from the queue.
* If dispatching eKeyDown advance native event loop due to entering to a modal loop or dosing synchronous XHR, the message pattern is broken before removing the odd messages from the queue.
After removing the odd char messages, NativeKey should store them with mRemovedOddCharMsgs because NativeKey needs to dispatch them to focused windowless plugin.
Note that this patch also fixes a bug of the loop to remove the odd WM_CHAR messages. Old code removes only one WM_CHAR messages, but we need to remove all WM_CHAR messages before WM_KEYUP. This must be a regression.
MozReview-Commit-ID: I60bcIx2SFS
--HG--
extra : rebase_source : 19d0e70d9f39e6d0476c62def5e0a2dc1e0ab444
NativeKey is now removing and storing following char messages when it's created for a keydown message. Therefore, IsFollowedByNonControlCharMessage() just refers the stored messages and it's enough fast. So, we can get rid of mIsFollowedByNonControlCharMessage.
MozReview-Commit-ID: 542A2sHNXeC
--HG--
extra : rebase_source : e748c9855c3cf2d45609f94f9ccc8d43d29dc447
GetFollowingCharMessage() is now called only when removing following char message. Therefore, it does not need to have the optional argument indicating if removing the found message.
MozReview-Commit-ID: 7P39wyfSC1
--HG--
extra : rebase_source : a38bb961df1bc03adc21295bc39e4e9c16e864f2
While dispatching an event, focused widget may be changed. In such case, NativeKey shouldn't continue to dispatch remaining events (eKeyPress events) for preventing to dispatch to input text in unexpected website.
MozReview-Commit-ID: 7geuqks0LQK
--HG--
extra : rebase_source : 3e6c82e1eb0e27115fe93b1a3b4a155914fd06f7
In some cases, we may receive following char message of WM_*KEYDOWN *during* dispatching an eKeyDown event. In such case, NativeKey shouldn't dispatch eKeyPress event twice (one is caused by receiving WM_*CHAR message, the other is caused by post dispatching eKeyDown event code).
This patch makes NativeKey consume following WM_*CHAR messages before dispatching eKeyDown. Therefore, the former case will never occur.
For doing that, NativeKey stores following WM_*CHAR messages in mFollowingCharMsgs and uses it when it needs to dispatch eKeyPress events for each WM_*CHAR message.
MozReview-Commit-ID: 6QNvlwVVlTz
--HG--
extra : rebase_source : c33b5a1ac503326d51ef78f4f8a09c9a63df7871
For safety, NativeKey::GetScanCodeWithExtendedFlag() returns without extended flag on WinXP and WinServer2003 because ::MapVirtualKeyEx() API doesn't support extend key conversion.
However, extended scan code is available even on them when lParam has 0x1000000 especially when it computes KeyboardEvent.code value. Therefore, it should return with 0xE000 for extended keys on any versions of Windows.
Note that NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() wraps ::MapVirtualKeyEx() API. It checks if the API is not available for the result of NativeKey::GetScanCodeWithExtendedFlag(). So, returning extended scan code from NativeKey::GetScanCodeWithExtendedFlag() is safe.
MozReview-Commit-ID: D2RrHxPI9ET
--HG--
extra : rebase_source : 51f277e8331eb7ad109c3227ac1fe73f6de48105
On Windows, some keys are called "extended key". Their scan code include 0xE000. For example, Enter key in standard position is 0x001C but Numpad's Enter key is 0xE01C. Unfortunately, both of them cause same virtual keycode value, VK_RETURN. Therefore, currently, nsIDOMWindowUtils.sendNativeKey() can synthesize only one native key event of them (only non-extended key's event). Additionally, MapVirtualKeyEx() API with MAPVK_VK_TO_VSC (even with MAPVK_VK_TO_VSC_EX) don't return extended scancode value as expected.
For solving these issues, we should include scan code value to the virtual keycode value at calling sendNativeKey().
Fortunately, virtual keycode value on Windows is 0 ~ 255 (0x00 ~ 0xFF) but aNativeKeyCode of sendNativeKey() is int32_t. So, we can use upper 16 bit for specifying scan code.
This patch explicitly specifies scan code value at defining WIN_VK_* in NativeKeyCodes.js. Additionally, this patch duplicates native virtual keycode definition for Home, End, Insert, Delete, PageUp, PageDown, ArrowUp, ArrowLeft, ArrowDown, ArrowRight and Enter as WIN_VK_* and WIN_VK_NUMPAD_*. This makes automated tests can specify both positions' keys explicitly.
Finally, this patch adds some tests to test_keycodes.xul for testing KeyboardEvent.code value of those keys in both positions.
MozReview-Commit-ID: 8n1rQ71dilg
--HG--
extra : rebase_source : 8215e56ba1ed9fc54c04eb7ca037b12c3ced5c1b
On Windows, some keys are called "extended key". Their scan code include 0xE000. For example, Enter key in standard position is 0x001C but Numpad's Enter key is 0xE01C. Unfortunately, both of them cause same virtual keycode value, VK_RETURN. Therefore, currently, nsIDOMWindowUtils.sendNativeKey() can synthesize only one native key event of them (only non-extended key's event). Additionally, MapVirtualKeyEx() API with MAPVK_VK_TO_VSC (even with MAPVK_VK_TO_VSC_EX) don't return extended scancode value as expected.
For solving these issues, we should include scan code value to the virtual keycode value at calling sendNativeKey().
Fortunately, virtual keycode value on Windows is 0 ~ 255 (0x00 ~ 0xFF) but aNativeKeyCode of sendNativeKey() is int32_t. So, we can use upper 16 bit for specifying scan code.
This patch explicitly specifies scan code value at defining WIN_VK_* in NativeKeyCodes.js. Additionally, this patch duplicates native virtual keycode definition for Home, End, Insert, Delete, PageUp, PageDown, ArrowUp, ArrowLeft, ArrowDown, ArrowRight and Enter as WIN_VK_* and WIN_VK_NUMPAD_*. This makes automated tests can specify both positions' keys explicitly.
Finally, this patch adds some tests to test_keycodes.xul for testing KeyboardEvent.code value of those keys in both positions.
MozReview-Commit-ID: 8n1rQ71dilg
--HG--
extra : rebase_source : 0f4bb9193aa06cd7985590636b77a6e2a71ac2e4
Ctrl+Backspace causes WM_CHAR for control character DELETE. However, NativeKey::IsControlChar() doesn't treat it as a control character. Therefore, NativeKey treats Backspace key as a printable character.
MozReview-Commit-ID: 29V45CNp8kW
--HG--
extra : rebase_source : 6656d884addf8b49dfa7c12d0b2c8d0543493c4f
On some keyboard layouts, a key sequence, a dead key -> another dead key, may produce a composite character instead of two base characters for each key. For example, with "Russian - Mnemonic" keyboard layout on Win 8 or later, both 's' and 'c' are dead keys but key sequence, 's' -> 'c', produces a Unicode character.
For solving this issue, this patch fixes 2 bugs:
First, KeyboardLayout::GetDeadKeyCombinations() doesn't add dead key entry if 2nd key is a dead key (::ToUnicodeEx() returns -1). In such case, it should add a dead key entry with the first character which is produced when only the 2nd key is pressed (the character is called as "base character" and used for index of the dead key table).
Next, KeyboardLayout::InitNativeKey() should check if 2nd dead key press produces a composite character. If it's produced, it should initialize given NativeKey with the composite character. Otherwise, it should initialize with base characters of each key. This patch does it with KeyboardLayout::MaybeInitNativeKeyWithCompositeChar().
Finally, we should add automated test for this. However, unfortunately, it's not available on Win7 and our infra is still using Win7 for running automated tests. Therefore, this patch doesn't include new automated tests.
MozReview-Commit-ID: G1DrfkHKNcK
--HG--
extra : rebase_source : 6ff4278d594a26a0908464b1e603a0a7ee2b3b38
It's difficult to understand what data is created by KeyboardLayout::LoadLayout(). So, for understanding what data is created, let's add logging code into it.
MozReview-Commit-ID: CelxyVpGn5f
--HG--
extra : rebase_source : fd8f15a42c4c2b4c1f1079184060c6e5f796ac5a
There are 2 bugs and this patch fixes them once.
First, NativeKey::WillDispatchKeyboardEvent() is used to setting alternative charCode values for every eKeyPress event. However, for supporting "reserved" shortcut keys, now, it sets alternative charCode values to eKeyDown too. However, they are really different. eKeyPress events are fired for every character to be inputted by a key press sequence. On the other hand, eKeyDown event is fired only once for a key sequence. Therefore, now, NativeKey::WillDispatchKeyboardEvent() needs to set alternative charCode values for all characters inputted by the key sequence to eKeyDown event.
The other is not a new bug. NativeKey::WillDispatchKeyboardEvent() sets the last eKeyPress event's special alternative charCode values, such as unshifted Latin character, shifted Latin character and some character which can be computed from virtual keycode. This is performed when given index is the last index of the longest input string of the key. However, the value includes different shift key state. I.e., when different shift key causes longer text input, NativeKey::WillDispatchKeyboardEvent() won't set the special alternative charCode values to any eKeyPress events. For example, when Ctrl+T is pressed with Arabic keyboard layout, its unshifted input string length is 1 but shifted input string length is 2. Then, eKeyPress event is fired only once, but NativeKey::WillDispatchKeyboardEvent() waits second eKeyPress event.
Therefore, this patch makes the method append alternative charCodes for all remaining characters and detect the last event correctly with mCommittedCharsAndModifiers (it's used for KeyboardEvent.key value of eKeyDown event and the count of eKeyPress events is same as the value's length).
MozReview-Commit-ID: 6adUnmi5KYy
--HG--
extra : rebase_source : 8c04a3a155f2fcb9a5a8b3e9e0a176c678dc6265
The new test failure is caused by a bug of the test API, KeyboardLayout::SysnthesizeNativeKeyEvent(). It doesn't generate WM_SYSKEY* messages nor WM_SYS*CHAR messages when Alt key is pressed. Therefore, the new path in the previous code works unexpectedly with automated tests.
This patch makes KeyboardLayout::SysnthesizeNativeKeyEvent() WM_SYS* message aware. When Alt key is pressed (but Ctrl key is not pressed) and the Alt key + something doesn't cause text input, the API generates WM_SYS* messages as expected.
MozReview-Commit-ID: FLbe4SYEZLf
--HG--
extra : rebase_source : 054147997eddfb01dbad63afc07e0b4f59a60257
Some keyboard utilities for Windows can change non-printable keys to printable keys. Therefore, if a keydown message is followed by one or more char message whose wParam isn't a control character, NativeKey should treat it as a printable key's event.
MozReview-Commit-ID: HoFbz5Zafeh
--HG--
extra : rebase_source : 9001c58cb082a93946e1b4c445dfe71f15d08997
KeyboardEvent::InitNativeKey() should initialize NativeKey if it's created for handling an orphan WM_CHAR message, however, if it the charCode isn't a printable character such as 0x0D for Enter key, it shouldn't refer it because focused editor shouldn't handle keyboard event as inputting the non-printable character.
MozReview-Commit-ID: FwTdGqhPEld
--HG--
extra : rebase_source : 69da91ad47e64199c8ff6c120522eb7e153122cd
This patch also renames:
EditorInputEventDispatcher -> mozilla::EditorInputEventDispatcher
And some variable names are renamed from aEditor or mEditor to aEditorBase or mEditorBase for making their types clearer.
MozReview-Commit-ID: 2FCXWpLMn8e
--HG--
rename : editor/libeditor/nsEditor.cpp => editor/libeditor/EditorBase.cpp
rename : editor/libeditor/nsEditor.h => editor/libeditor/EditorBase.h
And mCharCode shouldn't be compared with NS_VK_*, nsIDOMKeyEvent::DOM_VK_*. Additionally, when it's compared with a character constant, cast isn't necessary.
MozReview-Commit-ID: JMT614copjG
--HG--
extra : rebase_source : 69ee3c589e5a71c814ec9a40ac3aab39c789c11d
And also WidgetKeyboardEvent::mKeyCode should be compared with NS_VK_* rather than nsIDOMKeyEvent::DOM_VK_*.
MozReview-Commit-ID: IKjQ1nr8XYe
--HG--
extra : rebase_source : 83125cd2523f6b70759f621470aad23b00aae8ae
Some special keyboard layout may use a key as a non-lockable modifier key even if the key isn't a non-lockable modifier key (e.g., CapsLock key of 'Neo' for German). In such case, KeyboardLayout class cannot initialize NativeKey::mCommittedCharsAndModifiers with actual input character properly because KeyboardLayout class doesn't support such eccentric keyboard layouts.
For preventing this issue, NativeKey should overwrite mCommittedCharsAndModifiers with following WM_CHAR message when it handles WM_KEYDOWN and should handle with following WM_CHAR message. However, we should ignore following WM_CHAR message if the character is a control character which shouldn't be inputted into focused text editor.
MozReview-Commit-ID: Ax01nnaRXek
--HG--
extra : rebase_source : fd802e868db8990481873ee8eb98375a50efa47a
TextEventDispatcher initializes charCode value with mKeyValue (and mKeyNameIndex) of WidgetKeyboardEvent. Therefore, NativeKey needs to initialize mKeyValue properly at handling WM_KEYDOWN message of VK_PACKET. However, nobody initializes mCommittedCharsAndModifiers value of VK_PACKET. Additionally, KeyboardLayout::ConvertNativeKeyCodeToKeyNameIndex() returns KEY_NAME_INDEX_Unidentified for it too.
Therefore, this patch creates a path for handling VK_PACKET. First, makes KeyboardLayout::ConvertNativeKeyCodeToKeyNameIndex() returns KEY_NAME_INDEX_USE_STRING. Next, the constructor of NativeKey initializes mCommittedCharsAndModifiers with following char message. Additionally, makes sure that VK_PACKET is always handled with following char message even if there is no char message.
nsWindow for Windows cannot decide if a preceding WM_*KEYDOWN or WM_*KEYUP which is a preceding message of WM_*CHAR is consumed because nsWindow cannot know if WM_*CHAR message came from same window which received the preceding WM_*KEYDOWN or WM_*KEYUP. Therefore, PluginInstanceChild should do that.
MozReview-Commit-ID: 1uuZ0nTJ5Xb
--HG--
extra : rebase_source : b99f8057d5e93035a769af2506292ff7d2cb8f4a
Implementing nsWindow::OnWindowedPluginKeyEvent() on Windows. This patch makes NativeKey class dispatches eKeyDownOnPlugin and eKeyUpOnPlugin when the method is called.
MozReview-Commit-ID: L8yRZvDaQKR
--HG--
extra : rebase_source : 387ce72dcea23a92bd8c774fc54a8bff8da6c844
Before posting native key message from PluginInstanceChild, we need to check if the key combination could be a shortcut key, i.e., we need to check if Ctrl or Alt key is pressed. ModifierKeyState is a good class for checking it but it should be defined in an independent header file.
This patch separates the definition of ModifierKeyState to mozilla/widget/WinModifierKeyState.h and implement MaybeMatchShortcutKey() for PluginInstanceChild.
MozReview-Commit-ID: ZjLnJx02Ou
--HG--
rename : widget/windows/KeyboardLayout.h => widget/windows/WinModifierKeyState.h
extra : rebase_source : 66e9351a36dfa88f080ea78972ac0cb347bb174d
When user types a Unicode character with Alt + Numpad keys, recevied messages are:
1. WM_SYSKEYDOWN for Alt (VK_MENU)
2. WM_SYSKEYDOWN and WM_SYSKEYUP of Numpad keys
3. WM_KEYUP for Alt (VK_MENU)
4. WM_CHAR for the Unicode character
The WM_CHAR indicates Alt key with its scancode. Then, we shouldn't set the key value of the keypress event as "Alt". Instead of that, we should set key value to the inputted Unicode character. Then, the keypress event won't be supprressed by WidgetKeyboardEvent::ShouldCauseKeypressEvents() in TextEventDispatcher (this is what the cause of bug 1253153 is.
MozReview-Commit-ID: 8KjOWvYcKMs
--HG--
extra : rebase_source : 463d3185a7074eb564afaf3bb453bbf6967d9677
mDefaultPreventedByChrome is hacky. When PresShell handles Escape key events in fullscreen mode, it prevents default of every Escape key events and dispatch it only into chrome. After that, it check mDefaultPreventedByChrome if at least one call of preventDefault() occurred in chrome. Therefore, if we shouldn't set both mDefaultPreventedByChrome and mDefaultPreventedByContent to true before dispatching an event. This the reason why we need a special method, PreventDefaultBeforeDispatch() is needed for setting only mDefaultPrevented to true.
MozReview-Commit-ID: BPSq68GnWw6
--HG--
extra : rebase_source : f2f963afeba6994cc090efedebc29c0d9334c96d
extra : source : 1012dc095cc1b7236991a7befdbfbf174dc1c1af