| Index: chrome/renderer/mock_keyboard_driver_win.cc
|
| ===================================================================
|
| --- chrome/renderer/mock_keyboard_driver_win.cc (revision 17071)
|
| +++ chrome/renderer/mock_keyboard_driver_win.cc (working copy)
|
| @@ -15,28 +15,47 @@
|
| // 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 @@
|
|
|
| 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 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;
|
|
|
| Property changes on: chrome\renderer\mock_keyboard_driver_win.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|