Index: win8/metro_driver/metro_driver_win7.cc |
diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc |
index 3ace04caee0a06327e53b95281b2c12e2be42b5c..028340957262908c6c497273601974a65565e31f 100644 |
--- a/win8/metro_driver/metro_driver_win7.cc |
+++ b/win8/metro_driver/metro_driver_win7.cc |
@@ -371,8 +371,8 @@ class KeyEvent : public mswr::RuntimeClass< |
winui::Core::ICharacterReceivedEventArgs, |
winui::Core::IAcceleratorKeyEventArgs> { |
public: |
- KeyEvent(const MSG& msg) |
- : msg_(msg) {} |
+ KeyEvent(const MSG& msg, bool was_key) |
+ : msg_(msg), was_key_(was_key) {} |
// IKeyEventArgs implementation. |
HRESULT STDMETHODCALLTYPE |
@@ -388,8 +388,8 @@ class KeyEvent : public mswr::RuntimeClass< |
key_status->ScanCode = (msg_.lParam >> 16) & 0x00FF; |
key_status->IsExtendedKey = (msg_.lParam & (1 << 24)); |
key_status->IsMenuKeyDown = (msg_.lParam & (1 << 29)); |
- key_status->WasKeyDown = (msg_.lParam & (1 << 30)); |
key_status->IsKeyReleased = (msg_.lParam & (1 << 31)); |
+ key_status->WasKeyDown = was_key_; |
return S_OK; |
} |
@@ -414,6 +414,7 @@ class KeyEvent : public mswr::RuntimeClass< |
private: |
MSG msg_; |
+ bool was_key_; |
}; |
// The following classes are the emulation of the WinRT system as exposed |
@@ -463,7 +464,11 @@ class CoreDispatcherEmulation : |
MSG msg = {0}; |
while((::GetMessage(&msg, NULL, 0, 0) != 0) && g_window_count > 0) { |
ProcessInputMessage(msg); |
- ::TranslateMessage(&msg); |
+ // Don't call TranslateMessage() here but call TranslateMessage() in |
+ // InputMethodWin, so that the WM_KEYDOWN/WM_KEYUP & WM_CHAR can be |
+ // combined for key event flow. The combination of key events is required |
+ // for Chrome IMEs, which can do IME related actions based on the single |
+ // key event. |
::DispatchMessage(&msg); |
} |
// TODO(cpu): figure what to do with msg.WParam which we would normally |
@@ -522,7 +527,7 @@ class CoreDispatcherEmulation : |
bool HandleSystemKeys(const MSG& msg) { |
mswr::ComPtr<winui::Core::IAcceleratorKeyEventArgs> event_args; |
- event_args = mswr::Make<KeyEvent>(msg); |
+ event_args = mswr::Make<KeyEvent>(msg, true); |
accelerator_key_event_handler_->Invoke(this, event_args.Get()); |
return true; |
} |
@@ -913,8 +918,29 @@ class CoreWindowEmulation |
switch (msg.message) { |
case WM_KEYDOWN: |
case WM_KEYUP: { |
+ ::TranslateMessage(&msg); |
+ // Peek & remove the following messages in the message queue. |
+ // - WM_CHAR (0x0102) |
+ // - WM_DEADCHAR (0x0103) |
+ // - WM_UNICHAR (0x0109) |
+ // And for WM_UNICHAR, call DefWindowProc() to generate WM_CHAR. |
+ // And only process WM_CHAR message in browser. |
+ MSG char_msg; |
+ while (::PeekMessage(&char_msg, msg.hwnd, WM_UNICHAR, WM_UNICHAR, |
James Su
2015/08/07 04:55:55
did you try any unichar use case? As far as I unde
Shu Chen
2015/08/07 06:02:50
The change here is just for double insurance to ma
|
+ PM_REMOVE)) { |
+ ::DefWindowProc( |
+ msg.hwnd, WM_UNICHAR, char_msg.wParam, char_msg.lParam); |
+ } |
+ while (::PeekMessage(&char_msg, msg.hwnd, WM_CHAR, WM_DEADCHAR, |
+ PM_REMOVE)) { |
+ if (char_msg.message == WM_DEADCHAR) |
+ continue; |
+ mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> char_args; |
+ char_args = mswr::Make<KeyEvent>(char_msg, true); |
+ character_received_handler_->Invoke(this, char_args.Get()); |
+ } |
mswr::ComPtr<winui::Core::IKeyEventArgs> event_args; |
- event_args = mswr::Make<KeyEvent>(msg); |
+ event_args = mswr::Make<KeyEvent>(msg, true); |
KeyEventHandler* handler = NULL; |
if (msg.message == WM_KEYDOWN) { |
handler = key_down_handler_; |
@@ -925,11 +951,9 @@ class CoreWindowEmulation |
break; |
} |
- case WM_CHAR: |
- case WM_DEADCHAR: |
- case WM_UNICHAR: { |
+ case WM_CHAR: { |
mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> event_args; |
- event_args = mswr::Make<KeyEvent>(msg); |
+ event_args = mswr::Make<KeyEvent>(msg, false); |
character_received_handler_->Invoke(this, event_args.Get()); |
break; |
} |