summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-13 04:56:20 +0000
committerhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-13 04:56:20 +0000
commit34ff04759ed15031330cd7006a2003ce4504a49f (patch)
tree0e34d5fd59f0522185d01d23bc6ad84aedd616e6 /chrome
parent26c611ce4797195d58d323e16b4d1699d7eefeac (diff)
downloadchromium_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.cc14
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h12
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc89
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(