summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/mock_keyboard_driver_win.cc
diff options
context:
space:
mode:
authorhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 00:39:59 +0000
committerhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 00:39:59 +0000
commit9db40b680c36437f5e9aa30d0d7aa88f3d24dea6 (patch)
tree4cb6f03fafb021e44cb55c82e8070bdf01ef9949 /chrome/renderer/mock_keyboard_driver_win.cc
parentffde793973e9f1d0ba032eb37e43e40c57325896 (diff)
downloadchromium_src-9db40b680c36437f5e9aa30d0d7aa88f3d24dea6.zip
chromium_src-9db40b680c36437f5e9aa30d0d7aa88f3d24dea6.tar.gz
chromium_src-9db40b680c36437f5e9aa30d0d7aa88f3d24dea6.tar.bz2
Fixed a bug with the unit_tests, which caused it to leave hebrew enabled
vista without hebrew support the bug reason is documented in the source for all to see and the bug=12093 (http://code.google.com/p/chromium/issues/detail?id=12093) the code has been tested with and without a debugger but i have to admit, the unit_tests rarely pass on my machine (the ui ones never do)but this code i changed leaves the state EXACTLY like it was and solves this issue at least BUG=12093 TEST=run unit_tests.exe on Hebrew Windows; run Chrome; open a page which contains a <textarea dir="ltr"></textarea> element; press control+right-shift key, and; verify its "dir" attribute becomes "rtl". Review URL: http://codereview.chromium.org/115849 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17156 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/mock_keyboard_driver_win.cc')
-rw-r--r--chrome/renderer/mock_keyboard_driver_win.cc50
1 files changed, 37 insertions, 13 deletions
diff --git a/chrome/renderer/mock_keyboard_driver_win.cc b/chrome/renderer/mock_keyboard_driver_win.cc
index 07792e9..151cb0b 100644
--- a/chrome/renderer/mock_keyboard_driver_win.cc
+++ b/chrome/renderer/mock_keyboard_driver_win.cc
@@ -15,28 +15,47 @@ MockKeyboardDriverWin::MockKeyboardDriverWin() {
// should save the layout and status here to restore when this instance is
// destroyed.
original_keyboard_layout_ = GetKeyboardLayout(0);
+ active_keyboard_layout_ = original_keyboard_layout_;
GetKeyboardState(&original_keyboard_states_[0]);
- keyboard_handle_ = NULL;
+ const UINT num_keyboard_layouts = GetKeyboardLayoutList(0, NULL);
+ DCHECK(num_keyboard_layouts > 0);
+
+ orig_keyboard_layouts_list_.resize(num_keyboard_layouts);
+ GetKeyboardLayoutList(num_keyboard_layouts, &orig_keyboard_layouts_list_[0]);
+
memset(&keyboard_states_[0], 0, sizeof(keyboard_states_));
}
MockKeyboardDriverWin::~MockKeyboardDriverWin() {
// Unload the keyboard-layout driver, restore the keyboard state, and reset
// the keyboard layout for succeeding tests.
- if (keyboard_handle_)
- UnloadKeyboardLayout(keyboard_handle_);
+ MaybeUnloadActiveLayout();
SetKeyboardState(&original_keyboard_states_[0]);
ActivateKeyboardLayout(original_keyboard_layout_, KLF_RESET);
}
+void MockKeyboardDriverWin::MaybeUnloadActiveLayout() {
+ // Workaround for http://crbug.com/12093
+ // Only unload a keyboard layout if it was loaded by this mock driver.
+ // Contrary to the documentation on MSDN unloading a keyboard layout
+ // previously loaded by the system causes that layout to stop working.
+ // We have confirmation of this behavior on XP & Vista.
+ for (size_t i = 0; i < orig_keyboard_layouts_list_.size(); ++i) {
+ if (orig_keyboard_layouts_list_[i] == active_keyboard_layout_)
+ return;
+ }
+
+ // If we got here, this keyboard layout wasn't loaded by the system so it's
+ // safe to unload it ourselve's.
+ UnloadKeyboardLayout(active_keyboard_layout_);
+ active_keyboard_layout_ = original_keyboard_layout_;
+}
+
bool MockKeyboardDriverWin::SetLayout(int layout) {
// Unload the current keyboard-layout driver and load a new keyboard-layout
// driver for mapping a virtual key-code to a Unicode character.
- if (keyboard_handle_) {
- UnloadKeyboardLayout(keyboard_handle_);
- keyboard_handle_ = NULL;
- }
+ MaybeUnloadActiveLayout();
// Scan the mapping table and retrieve a Language ID for the input layout.
// Load the keyboard-layout driver when we find a Language ID.
@@ -81,11 +100,16 @@ bool MockKeyboardDriverWin::SetLayout(int layout) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLanguageIDs); ++i) {
if (layout == kLanguageIDs[i].keyboard_layout) {
- keyboard_handle_ = LoadKeyboardLayout(kLanguageIDs[i].language,
- KLF_ACTIVATE);
- if (!keyboard_handle_)
- return false;
- return true;
+ HKL new_keyboard_layout = LoadKeyboardLayout(kLanguageIDs[i].language,
+ KLF_ACTIVATE);
+ // loaded_keyboard_layout_ must always have a valid keyboard handle
+ // so we only assign upon success.
+ if (new_keyboard_layout) {
+ active_keyboard_layout_ = new_keyboard_layout;
+ return true;
+ }
+
+ return false;
}
}
@@ -133,7 +157,7 @@ int MockKeyboardDriverWin::GetCharacters(int key_code,
int length = ToUnicodeEx(key_code, MapVirtualKey(key_code, 0),
&keyboard_states_[0], &code[0],
ARRAYSIZE_UNSAFE(code), 0,
- keyboard_handle_);
+ active_keyboard_layout_);
if (length > 0)
output->assign(code);
return length;