diff options
author | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-13 04:56:20 +0000 |
---|---|---|
committer | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-13 04:56:20 +0000 |
commit | 34ff04759ed15031330cd7006a2003ce4504a49f (patch) | |
tree | 0e34d5fd59f0522185d01d23bc6ad84aedd616e6 /chrome | |
parent | 26c611ce4797195d58d323e16b4d1699d7eefeac (diff) | |
download | chromium_src-34ff04759ed15031330cd7006a2003ce4504a49f.zip chromium_src-34ff04759ed15031330cd7006a2003ce4504a49f.tar.gz chromium_src-34ff04759ed15031330cd7006a2003ce4504a49f.tar.bz2 |
A quick fix for Issue 9762 and 9763.
This is caused by my change r12434 that does not check if there are any other keys pressed when a user presses left-control and left-shift keys (or right-control and right-shift keys).
To fix this issue, this change does not only add the above check, but also it adds code that cancels updating the text direction if a user presses another key while he/she is pressing control and shift keys.
BUG=9762 "Regression: Shift+Ctrl+Arrow selection combination also changes text direction in RTL UIs"
BUG=9763 "Ctrl+Shift text alignment depends of the sides of both the Ctrl and the Shift keys"
TEST=In a LTR <textarea> element, pressing a control key, pressing a right-shift key, releasing the right-shift key, and verify its text direction is changed to RTL.
TEST=In an RTL <textarea> element, pressing a control key, pressing a left-shift key, releasing the left-shift key, and verify its text direction is changed to LTR.
TEST=In a LTR <textarea> element, pressing a right-shift key, pressing a control key, releasing the right-shift key, and verify its text direction is still LTR.
TEST=In a LTR <textarea> element, pressing a control key, pressing a right-shift key, releasing the control key, and verify its text direction is changed to RTL.
TEST=In an RTL <textarea> element, pressing a left-shift key, pressing a control key, releasing the left-shift key, and verify its text direction is still RTL.
TEST=In an RTL <textarea> element, pressing a control key, pressing a left-shift key, releasing the control key, and verify its text direction is changed to LTR.
TEST=In a LTR <textarea> element, pressing a control key, pressing a right-shift key, pressing an arrow key, releasing the right-shift key, and verify its text direction is still LTR.
Review URL: http://codereview.chromium.org/63117
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13588 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.cc | 14 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.h | 12 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_win.cc | 89 |
3 files changed, 95 insertions, 20 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 23078c7..6d62b75 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -60,7 +60,8 @@ RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, is_unresponsive_(false), view_being_painted_(false), text_direction_updated_(false), - text_direction_(WEB_TEXT_DIRECTION_LTR) { + text_direction_(WEB_TEXT_DIRECTION_LTR), + text_direction_canceled_(false) { if (routing_id_ == MSG_ROUTING_NONE) routing_id_ = process_->GetNextRoutingID(); @@ -364,11 +365,18 @@ void RenderWidgetHost::UpdateTextDirection(WebTextDirection direction) { text_direction_ = direction; } +void RenderWidgetHost::CancelUpdateTextDirection() { + if (text_direction_updated_) + text_direction_canceled_ = true; +} + void RenderWidgetHost::NotifyTextDirection() { if (text_direction_updated_) { + if (!text_direction_canceled_) + Send(new ViewMsg_SetTextDirection(routing_id(), + static_cast<int>(text_direction_))); text_direction_updated_ = false; - Send(new ViewMsg_SetTextDirection(routing_id(), - static_cast<int>(text_direction_))); + text_direction_canceled_ = false; } } diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index 19a8102..66aef1f 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -238,12 +238,19 @@ class RenderWidgetHost : public IPC::Channel::Listener { // if (key_event.windows_key_code == 'A' && // key_event.modifiers == WebKeyboardEvent::CTRL_KEY) { // UpdateTextDirection(dir); + // } else { + // CancelUpdateTextDirection(); // } // } else if (key_event.type == WebKeyboardEvent::KEY_UP) { // NotifyTextDirection(); // } + // Once we cancel updating the text direction, we have to ignore all + // succeeding UpdateTextDirection() requests until calling + // NotifyTextDirection(). (We may receive keydown events even after we + // canceled updating the text direction because of auto-repeat.) // Note: we cannot undo this change for compatibility with Firefox and IE. void UpdateTextDirection(WebTextDirection direction); + void CancelUpdateTextDirection(); void NotifyTextDirection(); // This is for derived classes to give us access to the resizer rect. @@ -403,6 +410,11 @@ class RenderWidgetHost : public IPC::Channel::Listener { bool text_direction_updated_; WebTextDirection text_direction_; + // Set when we cancel updating the text direction. + // This flag also ignores succeeding update requests until we call + // NotifyTextDirection(). + bool text_direction_canceled_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHost); }; diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 14aee5b..5174ef0a 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -65,6 +65,57 @@ BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { return TRUE; } +// Returns the text direction according to the keyboard status. +// This function retrieves the status of all keys and returns the following +// values: +// * WEB_TEXT_DIRECTION_RTL +// If only a control key and a right-shift key are down. +// * WEB_TEXT_DIRECTION_LTR +// If only a control key and a left-shift key are down. +static bool GetNewTextDirection(WebTextDirection* direction) { + uint8_t keystate[256]; + if (!GetKeyboardState(&keystate[0])) + return false; + + // To check if a user is pressing only a control key and a right-shift key + // (or a left-shift key), we use the steps below: + // 1. Check if a user is pressing a control key and a right-shift key (or + // a left-shift key). + // 2. If the condition 1 is true, we should check if there are any other + // keys pressed at the same time. + // To ignore the keys checked in 1, we set their status to 0 before + // checking the key status. + const int kKeyDownMask = 0x80; + if ((keystate[VK_CONTROL] & kKeyDownMask) == 0) + return false; + + if (keystate[VK_RSHIFT] & kKeyDownMask) { + keystate[VK_RSHIFT] = 0; + *direction = WEB_TEXT_DIRECTION_RTL; + } else if (keystate[VK_LSHIFT] & kKeyDownMask) { + keystate[VK_LSHIFT] = 0; + *direction = WEB_TEXT_DIRECTION_LTR; + } else { + return false; + } + + // Scan the key status to find pressed keys. We should adandon changing the + // text direction when there are other pressed keys. + // This code is executed only when a user is pressing a control key and a + // right-shift key (or a left-shift key), i.e. we should ignore the status of + // the keys: VK_SHIFT, VK_CONTROL, VK_RCONTROL, and VK_LCONTROL. + // So, we reset their status to 0 and ignore them. + keystate[VK_SHIFT] = 0; + keystate[VK_CONTROL] = 0; + keystate[VK_RCONTROL] = 0; + keystate[VK_LCONTROL] = 0; + for (int i = 0; i <= VK_PACKET; ++i) { + if (keystate[i] & kKeyDownMask) + return false; + } + return true; +} + } // namespace // RenderWidgetHostView -------------------------------------------------------- @@ -848,24 +899,28 @@ LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam, return ::SendMessage(parent_hwnd_, message, wparam, lparam); } - if (wparam == VK_SHIFT || wparam == VK_CONTROL) { - // Bug 1845: we need to update the text direction when a user releases - // either a right-shift key or a right-control key after pressing both of - // them. So, we just update the text direction while a user is pressing the - // keys, and we notify the text direction when a user releases either of - // them. - if (message == WM_KEYDOWN) { - const int kKeyDownMask = 0x8000; - if ((GetKeyState(VK_RSHIFT) & kKeyDownMask) && - (GetKeyState(VK_RCONTROL) & kKeyDownMask)) { - render_widget_host_->UpdateTextDirection(WEB_TEXT_DIRECTION_RTL); - } else if ((GetKeyState(VK_LSHIFT) & kKeyDownMask) && - (GetKeyState(VK_LCONTROL) & kKeyDownMask)) { - render_widget_host_->UpdateTextDirection(WEB_TEXT_DIRECTION_LTR); - } - } else if (message == WM_KEYUP) { - render_widget_host_->NotifyTextDirection(); + // Bug 1845: we need to update the text direction when a user releases + // either a right-shift key or a right-control key after pressing both of + // them. So, we just update the text direction while a user is pressing the + // keys, and we notify the text direction when a user releases either of them. + if (message == WM_KEYDOWN) { + if (wparam == VK_SHIFT) { + WebTextDirection direction; + if (GetNewTextDirection(&direction)) + render_widget_host_->UpdateTextDirection(direction); + } else if (wparam != VK_CONTROL) { + // A user pressed a key except shift and control keys. + // When a user presses a key while he/she holds control and shift keys, + // we adandon sending an IPC message in a succeeding NotifyTextDirection() + // call. To adandon it, this call set a flag that prevents sending an IPC + // message in NotifyTextDirection() only if we are going to send it. + // So, it is harmless to call this function if we aren't going to send it. + render_widget_host_->CancelUpdateTextDirection(); } + } else if (message == WM_KEYUP && + (wparam == VK_SHIFT || wparam == VK_CONTROL)) { + // We send an IPC message only if we need to update the text direction. + render_widget_host_->NotifyTextDirection(); } render_widget_host_->ForwardKeyboardEvent( |