diff options
author | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-29 00:39:59 +0000 |
---|---|---|
committer | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-29 00:39:59 +0000 |
commit | 9db40b680c36437f5e9aa30d0d7aa88f3d24dea6 (patch) | |
tree | 4cb6f03fafb021e44cb55c82e8070bdf01ef9949 | |
parent | ffde793973e9f1d0ba032eb37e43e40c57325896 (diff) | |
download | chromium_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
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | chrome/renderer/mock_keyboard_driver_win.cc | 50 | ||||
-rw-r--r-- | chrome/renderer/mock_keyboard_driver_win.h | 10 |
3 files changed, 46 insertions, 15 deletions
@@ -38,3 +38,4 @@ Sean Bryant <sean@cyberwang.net> Robert Sesek <rsesek@bluestatic.org> Janwar Dinata <j.dinata@gmail.com> Will Hirsch <chromium@willhirsch.co.uk> +Yoav Zilberberg <yoav.zilberberg@gmail.com> 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; diff --git a/chrome/renderer/mock_keyboard_driver_win.h b/chrome/renderer/mock_keyboard_driver_win.h index 5ad0909..cd374c6 100644 --- a/chrome/renderer/mock_keyboard_driver_win.h +++ b/chrome/renderer/mock_keyboard_driver_win.h @@ -8,7 +8,7 @@ #include <windows.h> #include <string> - +#include <vector> #include "base/basictypes.h" // Implements the platform-dependent part of a pseudo keyboard device for @@ -23,10 +23,16 @@ class MockKeyboardDriverWin { int GetCharacters(int key_code, std::wstring* code); private: + void MaybeUnloadActiveLayout(); + + // The list of keyboard drivers that are installed on this machine. + std::vector<HKL> orig_keyboard_layouts_list_; + // The active keyboard driver at the time the Ctor was called. HKL original_keyboard_layout_; + // The currently active driver. + HKL active_keyboard_layout_; BYTE original_keyboard_states_[256]; - HKL keyboard_handle_; BYTE keyboard_states_[256]; DISALLOW_COPY_AND_ASSIGN(MockKeyboardDriverWin); |