Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/events/event_rewriter.h" | 5 #include "ui/chromeos/events/event_rewriter_chromeos.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" | |
| 14 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
| 15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 16 #include "base/sys_info.h" | 17 #include "base/sys_info.h" |
| 17 #include "chrome/browser/chromeos/login/ui/login_display_host.h" | |
| 18 #include "chrome/browser/extensions/extension_commands_global_registry.h" | |
| 19 #include "chrome/browser/profiles/profile_manager.h" | |
| 20 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | |
| 21 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" | |
| 22 #include "chrome/common/pref_names.h" | |
| 23 #include "chromeos/chromeos_switches.h" | 18 #include "chromeos/chromeos_switches.h" |
| 24 #include "components/prefs/pref_service.h" | |
| 25 #include "components/user_manager/user_manager.h" | |
| 26 #include "ui/base/ime/chromeos/ime_keyboard.h" | 19 #include "ui/base/ime/chromeos/ime_keyboard.h" |
| 27 #include "ui/base/ime/chromeos/input_method_manager.h" | 20 #include "ui/base/ime/chromeos/input_method_manager.h" |
| 21 #include "ui/chromeos/events/pref_names.h" | |
| 28 #include "ui/events/devices/input_device_manager.h" | 22 #include "ui/events/devices/input_device_manager.h" |
| 29 #include "ui/events/event.h" | 23 #include "ui/events/event.h" |
| 30 #include "ui/events/event_utils.h" | 24 #include "ui/events/event_utils.h" |
| 31 #include "ui/events/keycodes/dom/dom_code.h" | 25 #include "ui/events/keycodes/dom/dom_code.h" |
| 32 #include "ui/events/keycodes/dom/dom_key.h" | 26 #include "ui/events/keycodes/dom/dom_key.h" |
| 33 #include "ui/events/keycodes/dom/keycode_converter.h" | 27 #include "ui/events/keycodes/dom/keycode_converter.h" |
| 34 #include "ui/events/keycodes/keyboard_code_conversion.h" | 28 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 35 | 29 |
| 36 #if defined(USE_X11) | 30 #if defined(USE_X11) |
| 31 #include <X11/Xlib.h> | |
| 37 #include <X11/extensions/XInput2.h> | 32 #include <X11/extensions/XInput2.h> |
| 38 #include <X11/Xlib.h> | |
| 39 | 33 |
| 40 // Get rid of macros from Xlib.h that conflicts with other parts of the code. | 34 // Get rid of macros from Xlib.h that conflicts with other parts of the code. |
| 41 #undef RootWindow | 35 #undef RootWindow |
| 42 #undef Status | 36 #undef Status |
| 43 | 37 |
| 44 #include "ui/base/x/x11_util.h" | 38 #include "ui/base/x/x11_util.h" |
| 45 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 39 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| 46 #endif | 40 #endif |
| 47 | 41 |
| 48 namespace chromeos { | 42 namespace ui { |
| 49 | 43 |
| 50 namespace { | 44 namespace { |
| 51 | 45 |
| 52 // Hotrod controller vendor/product ids. | 46 // Hotrod controller vendor/product ids. |
| 53 const int kHotrodRemoteVendorId = 0x0471; | 47 const int kHotrodRemoteVendorId = 0x0471; |
| 54 const int kHotrodRemoteProductId = 0x21cc; | 48 const int kHotrodRemoteProductId = 0x21cc; |
| 55 const int kUnknownVendorId = -1; | 49 const int kUnknownVendorId = -1; |
| 56 const int kUnknownProductId = -1; | 50 const int kUnknownProductId = -1; |
| 57 | 51 |
| 58 // Table of properties of remappable keys and/or remapping targets (not | 52 // Table of properties of remappable keys and/or remapping targets (not |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 69 // | 63 // |
| 70 // For the second case, rewriting modifier EventFlags, | 64 // For the second case, rewriting modifier EventFlags, |
| 71 // |GetRemappedModifierMasks()| processes every table entry whose |flag| | 65 // |GetRemappedModifierMasks()| processes every table entry whose |flag| |
| 72 // is set in the incoming event. Using the |pref_name| in the table entry, | 66 // is set in the incoming event. Using the |pref_name| in the table entry, |
| 73 // it likewise uses |GetRemappedKey()| to find the properties of the | 67 // it likewise uses |GetRemappedKey()| to find the properties of the |
| 74 // user preference target key, and replaces the flag accordingly. | 68 // user preference target key, and replaces the flag accordingly. |
| 75 const struct ModifierRemapping { | 69 const struct ModifierRemapping { |
| 76 int flag; | 70 int flag; |
| 77 int remap_to; | 71 int remap_to; |
| 78 const char* pref_name; | 72 const char* pref_name; |
| 79 EventRewriter::MutableKeyState result; | 73 EventRewriterChromeOS::MutableKeyState result; |
| 80 } kModifierRemappings[] = { | 74 } kModifierRemappings[] = { |
| 81 {// kModifierRemappingCtrl references this entry by index. | 75 {// kModifierRemappingCtrl references this entry by index. |
| 82 ui::EF_CONTROL_DOWN, | 76 ui::EF_CONTROL_DOWN, |
| 83 input_method::kControlKey, | 77 ::chromeos::input_method::kControlKey, |
| 84 prefs::kLanguageRemapControlKeyTo, | 78 prefs::kLanguageRemapControlKeyTo, |
| 85 {ui::EF_CONTROL_DOWN, ui::DomCode::CONTROL_LEFT, ui::DomKey::CONTROL, | 79 {ui::EF_CONTROL_DOWN, ui::DomCode::CONTROL_LEFT, ui::DomKey::CONTROL, |
| 86 ui::VKEY_CONTROL}}, | 80 ui::VKEY_CONTROL}}, |
| 87 {// kModifierRemappingNeoMod3 references this entry by index. | 81 {// kModifierRemappingNeoMod3 references this entry by index. |
| 88 ui::EF_MOD3_DOWN | ui::EF_ALTGR_DOWN, | 82 ui::EF_MOD3_DOWN | ui::EF_ALTGR_DOWN, |
| 89 input_method::kNumModifierKeys, | 83 ::chromeos::input_method::kNumModifierKeys, |
| 90 nullptr, | 84 nullptr, |
| 91 {ui::EF_MOD3_DOWN | ui::EF_ALTGR_DOWN, ui::DomCode::CAPS_LOCK, | 85 {ui::EF_MOD3_DOWN | ui::EF_ALTGR_DOWN, ui::DomCode::CAPS_LOCK, |
| 92 ui::DomKey::ALT_GRAPH, ui::VKEY_ALTGR}}, | 86 ui::DomKey::ALT_GRAPH, ui::VKEY_ALTGR}}, |
| 93 {ui::EF_COMMAND_DOWN, | 87 {ui::EF_COMMAND_DOWN, |
| 94 input_method::kSearchKey, | 88 ::chromeos::input_method::kSearchKey, |
| 95 prefs::kLanguageRemapSearchKeyTo, | 89 prefs::kLanguageRemapSearchKeyTo, |
| 96 {ui::EF_COMMAND_DOWN, ui::DomCode::META_LEFT, ui::DomKey::META, | 90 {ui::EF_COMMAND_DOWN, ui::DomCode::META_LEFT, ui::DomKey::META, |
| 97 ui::VKEY_LWIN}}, | 91 ui::VKEY_LWIN}}, |
| 98 {ui::EF_ALT_DOWN, | 92 {ui::EF_ALT_DOWN, |
| 99 input_method::kAltKey, | 93 ::chromeos::input_method::kAltKey, |
| 100 prefs::kLanguageRemapAltKeyTo, | 94 prefs::kLanguageRemapAltKeyTo, |
| 101 {ui::EF_ALT_DOWN, ui::DomCode::ALT_LEFT, ui::DomKey::ALT, ui::VKEY_MENU}}, | 95 {ui::EF_ALT_DOWN, ui::DomCode::ALT_LEFT, ui::DomKey::ALT, ui::VKEY_MENU}}, |
| 102 {ui::EF_NONE, | 96 {ui::EF_NONE, |
| 103 input_method::kVoidKey, | 97 ::chromeos::input_method::kVoidKey, |
| 104 nullptr, | 98 nullptr, |
| 105 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::NONE, ui::VKEY_UNKNOWN}}, | 99 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::NONE, ui::VKEY_UNKNOWN}}, |
| 106 {ui::EF_MOD3_DOWN, | 100 {ui::EF_MOD3_DOWN, |
| 107 input_method::kCapsLockKey, | 101 ::chromeos::input_method::kCapsLockKey, |
| 108 prefs::kLanguageRemapCapsLockKeyTo, | 102 prefs::kLanguageRemapCapsLockKeyTo, |
| 109 {ui::EF_MOD3_DOWN, ui::DomCode::CAPS_LOCK, ui::DomKey::CAPS_LOCK, | 103 {ui::EF_MOD3_DOWN, ui::DomCode::CAPS_LOCK, ui::DomKey::CAPS_LOCK, |
| 110 ui::VKEY_CAPITAL}}, | 104 ui::VKEY_CAPITAL}}, |
| 111 {ui::EF_NONE, | 105 {ui::EF_NONE, |
| 112 input_method::kEscapeKey, | 106 ::chromeos::input_method::kEscapeKey, |
| 113 prefs::kLanguageRemapEscapeKeyTo, | 107 prefs::kLanguageRemapEscapeKeyTo, |
| 114 {ui::EF_NONE, ui::DomCode::ESCAPE, ui::DomKey::ESCAPE, ui::VKEY_ESCAPE}}, | 108 {ui::EF_NONE, ui::DomCode::ESCAPE, ui::DomKey::ESCAPE, ui::VKEY_ESCAPE}}, |
| 115 {ui::EF_NONE, | 109 {ui::EF_NONE, |
| 116 input_method::kBackspaceKey, | 110 ::chromeos::input_method::kBackspaceKey, |
| 117 prefs::kLanguageRemapBackspaceKeyTo, | 111 prefs::kLanguageRemapBackspaceKeyTo, |
| 118 {ui::EF_NONE, ui::DomCode::BACKSPACE, ui::DomKey::BACKSPACE, | 112 {ui::EF_NONE, ui::DomCode::BACKSPACE, ui::DomKey::BACKSPACE, |
| 119 ui::VKEY_BACK}}, | 113 ui::VKEY_BACK}}, |
| 120 {ui::EF_NONE, | 114 {ui::EF_NONE, |
| 121 input_method::kNumModifierKeys, | 115 ::chromeos::input_method::kNumModifierKeys, |
| 122 prefs::kLanguageRemapDiamondKeyTo, | 116 prefs::kLanguageRemapDiamondKeyTo, |
| 123 {ui::EF_NONE, ui::DomCode::F15, ui::DomKey::F15, ui::VKEY_F15}}}; | 117 {ui::EF_NONE, ui::DomCode::F15, ui::DomKey::F15, ui::VKEY_F15}}}; |
| 124 | 118 |
| 125 const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[0]; | 119 const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[0]; |
| 126 const ModifierRemapping* kModifierRemappingNeoMod3 = &kModifierRemappings[1]; | 120 const ModifierRemapping* kModifierRemappingNeoMod3 = &kModifierRemappings[1]; |
| 127 | 121 |
| 128 // Gets a remapped key for |pref_name| key. For example, to find out which | 122 // Gets a remapped key for |pref_name| key. For example, to find out which |
| 129 // key Search is currently remapped to, call the function with | 123 // key Search is currently remapped to, call the function with |
| 130 // prefs::kLanguageRemapSearchKeyTo. | 124 // prefs::kLanguageRemapSearchKeyTo. |
| 131 const ModifierRemapping* GetRemappedKey(const std::string& pref_name, | 125 const ModifierRemapping* GetRemappedKey( |
| 132 const PrefService& pref_service) { | 126 const std::string& pref_name, |
| 127 EventRewriterChromeOS::Delegate* delegate) { | |
| 128 if (!delegate) | |
| 129 return nullptr; | |
| 130 | |
| 133 int value = -1; | 131 int value = -1; |
| 134 // If we're at the login screen, try to get the pref from the global prefs | 132 if (!delegate->GetKeyboardRemappedPrefValue(pref_name, &value)) |
| 135 // dictionary. | 133 return nullptr; |
| 136 if (!LoginDisplayHost::default_host() || | |
| 137 !LoginDisplayHost::default_host() | |
| 138 ->GetOobeUI() | |
| 139 ->signin_screen_handler() | |
| 140 ->GetKeyboardRemappedPrefValue(pref_name, &value)) { | |
| 141 if (!pref_service.FindPreference(pref_name)) | |
| 142 return nullptr; | |
| 143 value = pref_service.GetInteger(pref_name); | |
| 144 } | |
| 145 | 134 |
| 146 for (size_t i = 0; i < arraysize(kModifierRemappings); ++i) { | 135 for (size_t i = 0; i < arraysize(kModifierRemappings); ++i) { |
| 147 if (value == kModifierRemappings[i].remap_to) | 136 if (value == kModifierRemappings[i].remap_to) |
| 148 return &kModifierRemappings[i]; | 137 return &kModifierRemappings[i]; |
| 149 } | 138 } |
| 150 return nullptr; | 139 return nullptr; |
| 151 } | 140 } |
| 152 | 141 |
| 153 bool HasDiamondKey() { | 142 bool HasDiamondKey() { |
| 154 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 143 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 155 chromeos::switches::kHasChromeOSDiamondKey); | 144 ::chromeos::switches::kHasChromeOSDiamondKey); |
| 156 } | 145 } |
| 157 | 146 |
| 158 bool IsISOLevel5ShiftUsedByCurrentInputMethod() { | 147 bool IsISOLevel5ShiftUsedByCurrentInputMethod() { |
| 159 // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask, | 148 // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask, |
| 160 // it's not possible to make both features work. For now, we don't remap | 149 // it's not possible to make both features work. For now, we don't remap |
| 161 // Mod3Mask when Neo2 is in use. | 150 // Mod3Mask when Neo2 is in use. |
| 162 // TODO(yusukes): Remove the restriction. | 151 // TODO(yusukes): Remove the restriction. |
| 163 input_method::InputMethodManager* manager = | 152 ::chromeos::input_method::InputMethodManager* manager = |
| 164 input_method::InputMethodManager::Get(); | 153 ::chromeos::input_method::InputMethodManager::Get(); |
| 165 return manager->IsISOLevel5ShiftUsedByCurrentInputMethod(); | 154 return manager->IsISOLevel5ShiftUsedByCurrentInputMethod(); |
| 166 } | 155 } |
| 167 | 156 |
| 168 bool IsExtensionCommandRegistered(ui::KeyboardCode key_code, int flags) { | 157 EventRewriterChromeOS::DeviceType GetDeviceType(const std::string& device_name, |
| 169 // Some keyboard events for ChromeOS get rewritten, such as: | 158 int vendor_id, |
| 170 // Search+Shift+Left gets converted to Shift+Home (BeginDocument). | 159 int product_id) { |
| 171 // This doesn't make sense if the user has assigned that shortcut | |
| 172 // to an extension. Because: | |
| 173 // 1) The extension would, upon seeing a request for Ctrl+Shift+Home have | |
| 174 // to register for Shift+Home, instead. | |
| 175 // 2) The conversion is unnecessary, because Shift+Home (BeginDocument) isn't | |
| 176 // going to be executed. | |
| 177 // Therefore, we skip converting the accelerator if an extension has | |
| 178 // registered for this shortcut. | |
| 179 Profile* profile = ProfileManager::GetActiveUserProfile(); | |
| 180 if (!profile || !extensions::ExtensionCommandsGlobalRegistry::Get(profile)) | |
| 181 return false; | |
| 182 | |
| 183 int modifiers = flags & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | | |
| 184 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN); | |
| 185 ui::Accelerator accelerator(key_code, modifiers); | |
| 186 return extensions::ExtensionCommandsGlobalRegistry::Get(profile) | |
| 187 ->IsRegistered(accelerator); | |
| 188 } | |
| 189 | |
| 190 EventRewriter::DeviceType GetDeviceType(const std::string& device_name, | |
| 191 int vendor_id, | |
| 192 int product_id) { | |
| 193 if (vendor_id == kHotrodRemoteVendorId && | 160 if (vendor_id == kHotrodRemoteVendorId && |
| 194 product_id == kHotrodRemoteProductId) { | 161 product_id == kHotrodRemoteProductId) { |
| 195 return EventRewriter::kDeviceHotrodRemote; | 162 return EventRewriterChromeOS::kDeviceHotrodRemote; |
| 196 } | 163 } |
| 197 | 164 |
| 198 if (base::LowerCaseEqualsASCII(device_name, "virtual core keyboard")) | 165 if (base::LowerCaseEqualsASCII(device_name, "virtual core keyboard")) |
| 199 return EventRewriter::kDeviceVirtualCoreKeyboard; | 166 return EventRewriterChromeOS::kDeviceVirtualCoreKeyboard; |
| 200 | 167 |
| 201 std::vector<std::string> tokens = base::SplitString( | 168 std::vector<std::string> tokens = base::SplitString( |
| 202 device_name, " .", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 169 device_name, " .", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 203 | 170 |
| 204 // If the |device_name| contains the two words, "apple" and "keyboard", treat | 171 // If the |device_name| contains the two words, "apple" and "keyboard", treat |
| 205 // it as an Apple keyboard. | 172 // it as an Apple keyboard. |
| 206 bool found_apple = false; | 173 bool found_apple = false; |
| 207 bool found_keyboard = false; | 174 bool found_keyboard = false; |
| 208 for (size_t i = 0; i < tokens.size(); ++i) { | 175 for (size_t i = 0; i < tokens.size(); ++i) { |
| 209 if (!found_apple && base::LowerCaseEqualsASCII(tokens[i], "apple")) | 176 if (!found_apple && base::LowerCaseEqualsASCII(tokens[i], "apple")) |
| 210 found_apple = true; | 177 found_apple = true; |
| 211 if (!found_keyboard && base::LowerCaseEqualsASCII(tokens[i], "keyboard")) | 178 if (!found_keyboard && base::LowerCaseEqualsASCII(tokens[i], "keyboard")) |
| 212 found_keyboard = true; | 179 found_keyboard = true; |
| 213 if (found_apple && found_keyboard) | 180 if (found_apple && found_keyboard) |
| 214 return EventRewriter::kDeviceAppleKeyboard; | 181 return EventRewriterChromeOS::kDeviceAppleKeyboard; |
| 215 } | 182 } |
| 216 | 183 |
| 217 return EventRewriter::kDeviceUnknown; | 184 return EventRewriterChromeOS::kDeviceUnknown; |
| 218 } | 185 } |
| 219 | 186 |
| 220 struct KeyboardRemapping { | 187 struct KeyboardRemapping { |
| 221 // MatchKeyboardRemapping() succeeds if the tested has all of the specified | 188 // MatchKeyboardRemapping() succeeds if the tested has all of the specified |
| 222 // flags (and possibly other flags), and either the key_code matches or the | 189 // flags (and possibly other flags), and either the key_code matches or the |
| 223 // condition's key_code is VKEY_UNKNOWN. | 190 // condition's key_code is VKEY_UNKNOWN. |
| 224 struct Condition { | 191 struct Condition { |
| 225 int flags; | 192 int flags; |
| 226 ui::KeyboardCode key_code; | 193 ui::KeyboardCode key_code; |
| 227 } condition; | 194 } condition; |
| 228 // ApplyRemapping(), which is the primary user of this structure, | 195 // ApplyRemapping(), which is the primary user of this structure, |
| 229 // conditionally sets the output fields from the |result| here. | 196 // conditionally sets the output fields from the |result| here. |
| 230 // - |dom_code| is set if |result.dom_code| is not NONE. | 197 // - |dom_code| is set if |result.dom_code| is not NONE. |
| 231 // - |dom_key| and |character| are set if |result.dom_key| is not NONE. | 198 // - |dom_key| and |character| are set if |result.dom_key| is not NONE. |
| 232 // -|key_code| is set if |result.key_code| is not VKEY_UNKNOWN. | 199 // -|key_code| is set if |result.key_code| is not VKEY_UNKNOWN. |
| 233 // - |flags| are always set from |result.flags|, but this can be |EF_NONE|. | 200 // - |flags| are always set from |result.flags|, but this can be |EF_NONE|. |
| 234 EventRewriter::MutableKeyState result; | 201 EventRewriterChromeOS::MutableKeyState result; |
| 235 }; | 202 }; |
| 236 | 203 |
| 237 bool MatchKeyboardRemapping(const EventRewriter::MutableKeyState& suspect, | 204 bool MatchKeyboardRemapping( |
| 238 const KeyboardRemapping::Condition& test) { | 205 const EventRewriterChromeOS::MutableKeyState& suspect, |
| 206 const KeyboardRemapping::Condition& test) { | |
| 239 return ((test.key_code == ui::VKEY_UNKNOWN) || | 207 return ((test.key_code == ui::VKEY_UNKNOWN) || |
| 240 (test.key_code == suspect.key_code)) && | 208 (test.key_code == suspect.key_code)) && |
| 241 ((suspect.flags & test.flags) == test.flags); | 209 ((suspect.flags & test.flags) == test.flags); |
| 242 } | 210 } |
| 243 | 211 |
| 244 void ApplyRemapping(const EventRewriter::MutableKeyState& changes, | 212 void ApplyRemapping(const EventRewriterChromeOS::MutableKeyState& changes, |
| 245 EventRewriter::MutableKeyState* state) { | 213 EventRewriterChromeOS::MutableKeyState* state) { |
| 246 state->flags |= changes.flags; | 214 state->flags |= changes.flags; |
| 247 if (changes.code != ui::DomCode::NONE) | 215 if (changes.code != ui::DomCode::NONE) |
| 248 state->code = changes.code; | 216 state->code = changes.code; |
| 249 if (changes.key != ui::DomKey::NONE) | 217 if (changes.key != ui::DomKey::NONE) |
| 250 state->key = changes.key; | 218 state->key = changes.key; |
| 251 if (changes.key_code != ui::VKEY_UNKNOWN) | 219 if (changes.key_code != ui::VKEY_UNKNOWN) |
| 252 state->key_code = changes.key_code; | 220 state->key_code = changes.key_code; |
| 253 } | 221 } |
| 254 | 222 |
| 255 // Given a set of KeyboardRemapping structs, finds a matching struct | 223 // Given a set of KeyboardRemapping structs, finds a matching struct |
| 256 // if possible, and updates the remapped event values. Returns true if a | 224 // if possible, and updates the remapped event values. Returns true if a |
| 257 // remapping was found and remapped values were updated. | 225 // remapping was found and remapped values were updated. |
| 258 bool RewriteWithKeyboardRemappings( | 226 bool RewriteWithKeyboardRemappings( |
| 259 const KeyboardRemapping* mappings, | 227 const KeyboardRemapping* mappings, |
| 260 size_t num_mappings, | 228 size_t num_mappings, |
| 261 const EventRewriter::MutableKeyState& input_state, | 229 const EventRewriterChromeOS::MutableKeyState& input_state, |
| 262 EventRewriter::MutableKeyState* remapped_state) { | 230 EventRewriterChromeOS::MutableKeyState* remapped_state) { |
| 263 for (size_t i = 0; i < num_mappings; ++i) { | 231 for (size_t i = 0; i < num_mappings; ++i) { |
| 264 const KeyboardRemapping& map = mappings[i]; | 232 const KeyboardRemapping& map = mappings[i]; |
| 265 if (MatchKeyboardRemapping(input_state, map.condition)) { | 233 if (MatchKeyboardRemapping(input_state, map.condition)) { |
| 266 remapped_state->flags = (input_state.flags & ~map.condition.flags); | 234 remapped_state->flags = (input_state.flags & ~map.condition.flags); |
| 267 ApplyRemapping(map.result, remapped_state); | 235 ApplyRemapping(map.result, remapped_state); |
| 268 return true; | 236 return true; |
| 269 } | 237 } |
| 270 } | 238 } |
| 271 return false; | 239 return false; |
| 272 } | 240 } |
| 273 | 241 |
| 274 void SetMeaningForLayout(ui::EventType type, | 242 void SetMeaningForLayout(ui::EventType type, |
| 275 EventRewriter::MutableKeyState* state) { | 243 EventRewriterChromeOS::MutableKeyState* state) { |
| 276 // Currently layout is applied by creating a temporary key event with the | 244 // Currently layout is applied by creating a temporary key event with the |
| 277 // current physical state, and extracting the layout results. | 245 // current physical state, and extracting the layout results. |
| 278 ui::KeyEvent key(type, state->key_code, state->code, state->flags); | 246 ui::KeyEvent key(type, state->key_code, state->code, state->flags); |
| 279 state->key = key.GetDomKey(); | 247 state->key = key.GetDomKey(); |
| 280 } | 248 } |
| 281 | 249 |
| 282 ui::DomCode RelocateModifier(ui::DomCode code, ui::DomKeyLocation location) { | 250 ui::DomCode RelocateModifier(ui::DomCode code, ui::DomKeyLocation location) { |
| 283 bool right = (location == ui::DomKeyLocation::RIGHT); | 251 bool right = (location == ui::DomKeyLocation::RIGHT); |
| 284 switch (code) { | 252 switch (code) { |
| 285 case ui::DomCode::CONTROL_LEFT: | 253 case ui::DomCode::CONTROL_LEFT: |
| 286 case ui::DomCode::CONTROL_RIGHT: | 254 case ui::DomCode::CONTROL_RIGHT: |
| 287 return right ? ui::DomCode::CONTROL_RIGHT : ui::DomCode::CONTROL_LEFT; | 255 return right ? ui::DomCode::CONTROL_RIGHT : ui::DomCode::CONTROL_LEFT; |
| 288 case ui::DomCode::SHIFT_LEFT: | 256 case ui::DomCode::SHIFT_LEFT: |
| 289 case ui::DomCode::SHIFT_RIGHT: | 257 case ui::DomCode::SHIFT_RIGHT: |
| 290 return right ? ui::DomCode::SHIFT_RIGHT : ui::DomCode::SHIFT_LEFT; | 258 return right ? ui::DomCode::SHIFT_RIGHT : ui::DomCode::SHIFT_LEFT; |
| 291 case ui::DomCode::ALT_LEFT: | 259 case ui::DomCode::ALT_LEFT: |
| 292 case ui::DomCode::ALT_RIGHT: | 260 case ui::DomCode::ALT_RIGHT: |
| 293 return right ? ui::DomCode::ALT_RIGHT : ui::DomCode::ALT_LEFT; | 261 return right ? ui::DomCode::ALT_RIGHT : ui::DomCode::ALT_LEFT; |
| 294 case ui::DomCode::META_LEFT: | 262 case ui::DomCode::META_LEFT: |
| 295 case ui::DomCode::META_RIGHT: | 263 case ui::DomCode::META_RIGHT: |
| 296 return right ? ui::DomCode::META_RIGHT : ui::DomCode::META_LEFT; | 264 return right ? ui::DomCode::META_RIGHT : ui::DomCode::META_LEFT; |
| 297 default: | 265 default: |
| 298 break; | 266 break; |
| 299 } | 267 } |
| 300 return code; | 268 return code; |
| 301 } | 269 } |
| 302 | 270 |
| 303 } // namespace | 271 } // namespace |
| 304 | 272 |
| 305 EventRewriter::EventRewriter(ui::EventRewriter* sticky_keys_controller) | 273 EventRewriterChromeOS::EventRewriterChromeOS( |
| 274 Delegate* delegate, | |
| 275 ui::EventRewriter* sticky_keys_controller) | |
| 306 : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE), | 276 : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE), |
| 307 ime_keyboard_for_testing_(NULL), | 277 ime_keyboard_for_testing_(nullptr), |
| 308 pref_service_for_testing_(NULL), | 278 delegate_(delegate), |
| 309 sticky_keys_controller_(sticky_keys_controller), | 279 sticky_keys_controller_(sticky_keys_controller), |
| 310 pressed_modifier_latches_(ui::EF_NONE), | 280 pressed_modifier_latches_(ui::EF_NONE), |
| 311 latched_modifier_latches_(ui::EF_NONE), | 281 latched_modifier_latches_(ui::EF_NONE), |
| 312 used_modifier_latches_(ui::EF_NONE) {} | 282 used_modifier_latches_(ui::EF_NONE) {} |
| 313 | 283 |
| 314 EventRewriter::~EventRewriter() {} | 284 EventRewriterChromeOS::~EventRewriterChromeOS() {} |
| 315 | 285 |
| 316 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedForTesting( | 286 EventRewriterChromeOS::DeviceType |
| 287 EventRewriterChromeOS::KeyboardDeviceAddedForTesting( | |
| 317 int device_id, | 288 int device_id, |
| 318 const std::string& device_name) { | 289 const std::string& device_name) { |
| 319 // Tests must avoid XI2 reserved device IDs. | 290 // Tests must avoid XI2 reserved device IDs. |
| 320 DCHECK((device_id < 0) || (device_id > 1)); | 291 DCHECK((device_id < 0) || (device_id > 1)); |
| 321 return KeyboardDeviceAddedInternal(device_id, device_name, kUnknownVendorId, | 292 return KeyboardDeviceAddedInternal(device_id, device_name, kUnknownVendorId, |
| 322 kUnknownProductId); | 293 kUnknownProductId); |
| 323 } | 294 } |
| 324 | 295 |
| 325 void EventRewriter::RewriteMouseButtonEventForTesting( | 296 void EventRewriterChromeOS::RewriteMouseButtonEventForTesting( |
| 326 const ui::MouseEvent& event, | 297 const ui::MouseEvent& event, |
| 327 std::unique_ptr<ui::Event>* rewritten_event) { | 298 std::unique_ptr<ui::Event>* rewritten_event) { |
| 328 RewriteMouseButtonEvent(event, rewritten_event); | 299 RewriteMouseButtonEvent(event, rewritten_event); |
| 329 } | 300 } |
| 330 | 301 |
| 331 ui::EventRewriteStatus EventRewriter::RewriteEvent( | 302 ui::EventRewriteStatus EventRewriterChromeOS::RewriteEvent( |
| 332 const ui::Event& event, | 303 const ui::Event& event, |
| 333 std::unique_ptr<ui::Event>* rewritten_event) { | 304 std::unique_ptr<ui::Event>* rewritten_event) { |
| 334 if ((event.type() == ui::ET_KEY_PRESSED) || | 305 if ((event.type() == ui::ET_KEY_PRESSED) || |
| 335 (event.type() == ui::ET_KEY_RELEASED)) { | 306 (event.type() == ui::ET_KEY_RELEASED)) { |
| 336 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), | 307 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), |
| 337 rewritten_event); | 308 rewritten_event); |
| 338 } | 309 } |
| 339 if ((event.type() == ui::ET_MOUSE_PRESSED) || | 310 if ((event.type() == ui::ET_MOUSE_PRESSED) || |
| 340 (event.type() == ui::ET_MOUSE_RELEASED)) { | 311 (event.type() == ui::ET_MOUSE_RELEASED)) { |
| 341 return RewriteMouseButtonEvent(static_cast<const ui::MouseEvent&>(event), | 312 return RewriteMouseButtonEvent(static_cast<const ui::MouseEvent&>(event), |
| 342 rewritten_event); | 313 rewritten_event); |
| 343 } | 314 } |
| 344 if (event.type() == ui::ET_MOUSEWHEEL) { | 315 if (event.type() == ui::ET_MOUSEWHEEL) { |
| 345 return RewriteMouseWheelEvent( | 316 return RewriteMouseWheelEvent( |
| 346 static_cast<const ui::MouseWheelEvent&>(event), rewritten_event); | 317 static_cast<const ui::MouseWheelEvent&>(event), rewritten_event); |
| 347 } | 318 } |
| 348 if ((event.type() == ui::ET_TOUCH_PRESSED) || | 319 if ((event.type() == ui::ET_TOUCH_PRESSED) || |
| 349 (event.type() == ui::ET_TOUCH_RELEASED)) { | 320 (event.type() == ui::ET_TOUCH_RELEASED)) { |
| 350 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), | 321 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), |
| 351 rewritten_event); | 322 rewritten_event); |
| 352 } | 323 } |
| 353 if (event.IsScrollEvent()) { | 324 if (event.IsScrollEvent()) { |
| 354 return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event), | 325 return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event), |
| 355 rewritten_event); | 326 rewritten_event); |
| 356 } | 327 } |
| 357 return ui::EVENT_REWRITE_CONTINUE; | 328 return ui::EVENT_REWRITE_CONTINUE; |
| 358 } | 329 } |
| 359 | 330 |
| 360 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( | 331 ui::EventRewriteStatus EventRewriterChromeOS::NextDispatchEvent( |
| 361 const ui::Event& last_event, | 332 const ui::Event& last_event, |
| 362 std::unique_ptr<ui::Event>* new_event) { | 333 std::unique_ptr<ui::Event>* new_event) { |
| 363 if (sticky_keys_controller_) { | 334 if (sticky_keys_controller_) { |
| 364 // In the case of sticky keys, we know what the events obtained here are: | 335 // In the case of sticky keys, we know what the events obtained here are: |
| 365 // modifier key releases that match the ones previously discarded. So, we | 336 // modifier key releases that match the ones previously discarded. So, we |
| 366 // know that they don't have to be passed through the post-sticky key | 337 // know that they don't have to be passed through the post-sticky key |
| 367 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, | 338 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, |
| 368 // because those phases do nothing with modifier key releases. | 339 // because those phases do nothing with modifier key releases. |
| 369 return sticky_keys_controller_->NextDispatchEvent(last_event, new_event); | 340 return sticky_keys_controller_->NextDispatchEvent(last_event, new_event); |
| 370 } | 341 } |
| 371 NOTREACHED(); | 342 NOTREACHED(); |
| 372 return ui::EVENT_REWRITE_CONTINUE; | 343 return ui::EVENT_REWRITE_CONTINUE; |
| 373 } | 344 } |
| 374 | 345 |
| 375 void EventRewriter::BuildRewrittenKeyEvent( | 346 void EventRewriterChromeOS::BuildRewrittenKeyEvent( |
| 376 const ui::KeyEvent& key_event, | 347 const ui::KeyEvent& key_event, |
| 377 const MutableKeyState& state, | 348 const MutableKeyState& state, |
| 378 std::unique_ptr<ui::Event>* rewritten_event) { | 349 std::unique_ptr<ui::Event>* rewritten_event) { |
| 379 ui::KeyEvent* rewritten_key_event = | 350 ui::KeyEvent* rewritten_key_event = |
| 380 new ui::KeyEvent(key_event.type(), state.key_code, state.code, | 351 new ui::KeyEvent(key_event.type(), state.key_code, state.code, |
| 381 state.flags, state.key, key_event.time_stamp()); | 352 state.flags, state.key, key_event.time_stamp()); |
| 382 rewritten_event->reset(rewritten_key_event); | 353 rewritten_event->reset(rewritten_key_event); |
| 383 } | 354 } |
| 384 | 355 |
| 385 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { | 356 void EventRewriterChromeOS::DeviceKeyPressedOrReleased(int device_id) { |
| 386 std::map<int, DeviceType>::const_iterator iter = | 357 std::map<int, DeviceType>::const_iterator iter = |
| 387 device_id_to_type_.find(device_id); | 358 device_id_to_type_.find(device_id); |
| 388 DeviceType type; | 359 DeviceType type; |
| 389 if (iter != device_id_to_type_.end()) | 360 if (iter != device_id_to_type_.end()) |
| 390 type = iter->second; | 361 type = iter->second; |
| 391 else | 362 else |
| 392 type = KeyboardDeviceAdded(device_id); | 363 type = KeyboardDeviceAdded(device_id); |
| 393 | 364 |
| 394 // Ignore virtual Xorg keyboard (magic that generates key repeat | 365 // Ignore virtual Xorg keyboard (magic that generates key repeat |
| 395 // events). Pretend that the previous real keyboard is the one that is still | 366 // events). Pretend that the previous real keyboard is the one that is still |
| 396 // in use. | 367 // in use. |
| 397 if (type == kDeviceVirtualCoreKeyboard) | 368 if (type == kDeviceVirtualCoreKeyboard) |
| 398 return; | 369 return; |
| 399 | 370 |
| 400 last_keyboard_device_id_ = device_id; | 371 last_keyboard_device_id_ = device_id; |
| 401 } | 372 } |
| 402 | 373 |
| 403 const PrefService* EventRewriter::GetPrefService() const { | 374 bool EventRewriterChromeOS::IsAppleKeyboard() const { |
| 404 if (pref_service_for_testing_) | |
| 405 return pref_service_for_testing_; | |
| 406 Profile* profile = ProfileManager::GetActiveUserProfile(); | |
| 407 return profile ? profile->GetPrefs() : NULL; | |
| 408 } | |
| 409 | |
| 410 bool EventRewriter::IsAppleKeyboard() const { | |
| 411 return IsLastKeyboardOfType(kDeviceAppleKeyboard); | 375 return IsLastKeyboardOfType(kDeviceAppleKeyboard); |
| 412 } | 376 } |
| 413 | 377 |
| 414 bool EventRewriter::IsHotrodRemote() const { | 378 bool EventRewriterChromeOS::IsHotrodRemote() const { |
| 415 return IsLastKeyboardOfType(kDeviceHotrodRemote); | 379 return IsLastKeyboardOfType(kDeviceHotrodRemote); |
| 416 } | 380 } |
| 417 | 381 |
| 418 bool EventRewriter::IsLastKeyboardOfType(DeviceType device_type) const { | 382 bool EventRewriterChromeOS::IsLastKeyboardOfType(DeviceType device_type) const { |
| 419 if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) | 383 if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) |
| 420 return false; | 384 return false; |
| 421 | 385 |
| 422 // Check which device generated |event|. | 386 // Check which device generated |event|. |
| 423 std::map<int, DeviceType>::const_iterator iter = | 387 std::map<int, DeviceType>::const_iterator iter = |
| 424 device_id_to_type_.find(last_keyboard_device_id_); | 388 device_id_to_type_.find(last_keyboard_device_id_); |
| 425 if (iter == device_id_to_type_.end()) { | 389 if (iter == device_id_to_type_.end()) { |
| 426 LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown."; | 390 LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown."; |
| 427 return false; | 391 return false; |
| 428 } | 392 } |
| 429 | 393 |
| 430 const DeviceType type = iter->second; | 394 const DeviceType type = iter->second; |
| 431 return type == device_type; | 395 return type == device_type; |
| 432 } | 396 } |
| 433 | 397 |
| 434 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { | 398 int EventRewriterChromeOS::GetRemappedModifierMasks(const ui::Event& event, |
| 435 const PrefService* prefs = GetPrefService(); | 399 int original_flags) const { |
| 436 return prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && | |
| 437 prefs->GetBoolean(prefs::kLanguageSendFunctionKeys); | |
| 438 } | |
| 439 | |
| 440 int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service, | |
| 441 const ui::Event& event, | |
| 442 int original_flags) const { | |
| 443 int unmodified_flags = original_flags; | 400 int unmodified_flags = original_flags; |
| 444 int rewritten_flags = pressed_modifier_latches_ | latched_modifier_latches_; | 401 int rewritten_flags = pressed_modifier_latches_ | latched_modifier_latches_; |
| 445 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); | 402 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); |
| 446 ++i) { | 403 ++i) { |
| 447 const ModifierRemapping* remapped_key = NULL; | 404 const ModifierRemapping* remapped_key = nullptr; |
| 448 if (!(unmodified_flags & kModifierRemappings[i].flag)) | 405 if (!(unmodified_flags & kModifierRemappings[i].flag)) |
| 449 continue; | 406 continue; |
| 450 switch (kModifierRemappings[i].flag) { | 407 switch (kModifierRemappings[i].flag) { |
| 451 case ui::EF_COMMAND_DOWN: | 408 case ui::EF_COMMAND_DOWN: |
| 452 // Rewrite Command key presses on an Apple keyboard to Control. | 409 // Rewrite Command key presses on an Apple keyboard to Control. |
| 453 if (IsAppleKeyboard()) { | 410 if (IsAppleKeyboard()) { |
| 454 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); | 411 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); |
| 455 remapped_key = kModifierRemappingCtrl; | 412 remapped_key = kModifierRemappingCtrl; |
| 456 } | 413 } |
| 457 break; | 414 break; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 470 if ((original_flags & ui::EF_ALTGR_DOWN) && | 427 if ((original_flags & ui::EF_ALTGR_DOWN) && |
| 471 IsISOLevel5ShiftUsedByCurrentInputMethod()) { | 428 IsISOLevel5ShiftUsedByCurrentInputMethod()) { |
| 472 remapped_key = kModifierRemappingNeoMod3; | 429 remapped_key = kModifierRemappingNeoMod3; |
| 473 } | 430 } |
| 474 break; | 431 break; |
| 475 default: | 432 default: |
| 476 break; | 433 break; |
| 477 } | 434 } |
| 478 if (!remapped_key && kModifierRemappings[i].pref_name) { | 435 if (!remapped_key && kModifierRemappings[i].pref_name) { |
| 479 remapped_key = | 436 remapped_key = |
| 480 GetRemappedKey(kModifierRemappings[i].pref_name, pref_service); | 437 GetRemappedKey(kModifierRemappings[i].pref_name, delegate_); |
|
oshima
2017/03/16 18:51:08
optional: I slightly prefer to handle delegate_ ==
Peng
2017/03/16 20:33:27
GetRemappedKey() is called so many places. It is h
| |
| 481 } | 438 } |
| 482 if (remapped_key) { | 439 if (remapped_key) { |
| 483 unmodified_flags &= ~kModifierRemappings[i].flag; | 440 unmodified_flags &= ~kModifierRemappings[i].flag; |
| 484 rewritten_flags |= remapped_key->flag; | 441 rewritten_flags |= remapped_key->flag; |
| 485 } | 442 } |
| 486 } | 443 } |
| 487 return rewritten_flags | unmodified_flags; | 444 return rewritten_flags | unmodified_flags; |
| 488 } | 445 } |
| 489 | 446 |
| 490 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | 447 ui::EventRewriteStatus EventRewriterChromeOS::RewriteKeyEvent( |
| 491 const ui::KeyEvent& key_event, | 448 const ui::KeyEvent& key_event, |
| 492 std::unique_ptr<ui::Event>* rewritten_event) { | 449 std::unique_ptr<ui::Event>* rewritten_event) { |
| 493 if (IsExtensionCommandRegistered(key_event.key_code(), key_event.flags())) | 450 if (delegate_ && delegate_->IsExtensionCommandRegistered(key_event.key_code(), |
| 451 key_event.flags())) | |
| 494 return ui::EVENT_REWRITE_CONTINUE; | 452 return ui::EVENT_REWRITE_CONTINUE; |
| 495 if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE) | 453 if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE) |
| 496 DeviceKeyPressedOrReleased(key_event.source_device_id()); | 454 DeviceKeyPressedOrReleased(key_event.source_device_id()); |
| 497 | 455 |
| 498 // Drop repeated keys from Hotrod remote. | 456 // Drop repeated keys from Hotrod remote. |
| 499 if ((key_event.flags() & ui::EF_IS_REPEAT) && | 457 if ((key_event.flags() & ui::EF_IS_REPEAT) && |
| 500 (key_event.type() == ui::ET_KEY_PRESSED) && IsHotrodRemote() && | 458 (key_event.type() == ui::ET_KEY_PRESSED) && IsHotrodRemote() && |
| 501 key_event.key_code() != ui::VKEY_BACK) { | 459 key_event.key_code() != ui::VKEY_BACK) { |
| 502 return ui::EVENT_REWRITE_DISCARD; | 460 return ui::EVENT_REWRITE_DISCARD; |
| 503 } | 461 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 523 tmp_event.set_key_code(state.key_code); | 481 tmp_event.set_key_code(state.key_code); |
| 524 tmp_event.set_flags(state.flags); | 482 tmp_event.set_flags(state.flags); |
| 525 std::unique_ptr<ui::Event> output_event; | 483 std::unique_ptr<ui::Event> output_event; |
| 526 status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); | 484 status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); |
| 527 if (status == ui::EVENT_REWRITE_REWRITTEN || | 485 if (status == ui::EVENT_REWRITE_REWRITTEN || |
| 528 status == ui::EVENT_REWRITE_DISPATCH_ANOTHER) | 486 status == ui::EVENT_REWRITE_DISPATCH_ANOTHER) |
| 529 state.flags = output_event->flags(); | 487 state.flags = output_event->flags(); |
| 530 if (status == ui::EVENT_REWRITE_DISCARD) | 488 if (status == ui::EVENT_REWRITE_DISCARD) |
| 531 return ui::EVENT_REWRITE_DISCARD; | 489 return ui::EVENT_REWRITE_DISCARD; |
| 532 is_sticky_key_extension_command = | 490 is_sticky_key_extension_command = |
| 533 IsExtensionCommandRegistered(state.key_code, state.flags); | 491 delegate_ && |
| 492 delegate_->IsExtensionCommandRegistered(state.key_code, state.flags); | |
| 534 } | 493 } |
| 535 | 494 |
| 536 // If flags have changed, this may change the interpretation of the key, | 495 // If flags have changed, this may change the interpretation of the key, |
| 537 // so reapply layout. | 496 // so reapply layout. |
| 538 if (state.flags != key_event.flags()) | 497 if (state.flags != key_event.flags()) |
| 539 SetMeaningForLayout(key_event.type(), &state); | 498 SetMeaningForLayout(key_event.type(), &state); |
| 540 | 499 |
| 541 // If sticky key rewrites the event, and it matches an extension command, do | 500 // If sticky key rewrites the event, and it matches an extension command, do |
| 542 // not further rewrite the event since it won't match the extension command | 501 // not further rewrite the event since it won't match the extension command |
| 543 // thereafter. | 502 // thereafter. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 562 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, | 521 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, |
| 563 // in which case we need to preserve that return status. Alternatively, we | 522 // in which case we need to preserve that return status. Alternatively, we |
| 564 // might be here because key_event changed, in which case we need to | 523 // might be here because key_event changed, in which case we need to |
| 565 // return |EVENT_REWRITE_REWRITTEN|. | 524 // return |EVENT_REWRITE_REWRITTEN|. |
| 566 if (status == ui::EVENT_REWRITE_CONTINUE) | 525 if (status == ui::EVENT_REWRITE_CONTINUE) |
| 567 status = ui::EVENT_REWRITE_REWRITTEN; | 526 status = ui::EVENT_REWRITE_REWRITTEN; |
| 568 BuildRewrittenKeyEvent(key_event, state, rewritten_event); | 527 BuildRewrittenKeyEvent(key_event, state, rewritten_event); |
| 569 return status; | 528 return status; |
| 570 } | 529 } |
| 571 | 530 |
| 572 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( | 531 ui::EventRewriteStatus EventRewriterChromeOS::RewriteMouseButtonEvent( |
| 573 const ui::MouseEvent& mouse_event, | 532 const ui::MouseEvent& mouse_event, |
| 574 std::unique_ptr<ui::Event>* rewritten_event) { | 533 std::unique_ptr<ui::Event>* rewritten_event) { |
| 575 int flags = mouse_event.flags(); | 534 int flags = mouse_event.flags(); |
| 576 RewriteLocatedEvent(mouse_event, &flags); | 535 RewriteLocatedEvent(mouse_event, &flags); |
| 577 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | 536 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; |
| 578 if (sticky_keys_controller_) { | 537 if (sticky_keys_controller_) { |
| 579 auto tmp_event = mouse_event; | 538 auto tmp_event = mouse_event; |
| 580 tmp_event.set_flags(flags); | 539 tmp_event.set_flags(flags); |
| 581 std::unique_ptr<ui::Event> output_event; | 540 std::unique_ptr<ui::Event> output_event; |
| 582 status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); | 541 status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 603 #endif | 562 #endif |
| 604 if (changed_button != ui::EF_NONE) { | 563 if (changed_button != ui::EF_NONE) { |
| 605 rewritten_mouse_event->set_changed_button_flags(changed_button); | 564 rewritten_mouse_event->set_changed_button_flags(changed_button); |
| 606 #if defined(USE_X11) | 565 #if defined(USE_X11) |
| 607 ui::UpdateX11EventForChangedButtonFlags(rewritten_mouse_event); | 566 ui::UpdateX11EventForChangedButtonFlags(rewritten_mouse_event); |
| 608 #endif | 567 #endif |
| 609 } | 568 } |
| 610 return status; | 569 return status; |
| 611 } | 570 } |
| 612 | 571 |
| 613 ui::EventRewriteStatus EventRewriter::RewriteMouseWheelEvent( | 572 ui::EventRewriteStatus EventRewriterChromeOS::RewriteMouseWheelEvent( |
| 614 const ui::MouseWheelEvent& wheel_event, | 573 const ui::MouseWheelEvent& wheel_event, |
| 615 std::unique_ptr<ui::Event>* rewritten_event) { | 574 std::unique_ptr<ui::Event>* rewritten_event) { |
| 616 if (!sticky_keys_controller_) | 575 if (!sticky_keys_controller_) |
| 617 return ui::EVENT_REWRITE_CONTINUE; | 576 return ui::EVENT_REWRITE_CONTINUE; |
| 618 int flags = wheel_event.flags(); | 577 int flags = wheel_event.flags(); |
| 619 RewriteLocatedEvent(wheel_event, &flags); | 578 RewriteLocatedEvent(wheel_event, &flags); |
| 620 auto tmp_event = wheel_event; | 579 auto tmp_event = wheel_event; |
| 621 tmp_event.set_flags(flags); | 580 tmp_event.set_flags(flags); |
| 622 ui::EventRewriteStatus status = | 581 ui::EventRewriteStatus status = |
| 623 sticky_keys_controller_->RewriteEvent(tmp_event, rewritten_event); | 582 sticky_keys_controller_->RewriteEvent(tmp_event, rewritten_event); |
| 624 | 583 |
| 625 switch (status) { | 584 switch (status) { |
| 626 case ui::EVENT_REWRITE_REWRITTEN: | 585 case ui::EVENT_REWRITE_REWRITTEN: |
| 627 case ui::EVENT_REWRITE_DISPATCH_ANOTHER: | 586 case ui::EVENT_REWRITE_DISPATCH_ANOTHER: |
| 628 // whell event has been rewritten and stored in |rewritten_event|. | 587 // whell event has been rewritten and stored in |rewritten_event|. |
| 629 #if defined(USE_X11) | 588 #if defined(USE_X11) |
| 630 ui::UpdateX11EventForFlags(rewritten_event->get()); | 589 ui::UpdateX11EventForFlags(rewritten_event->get()); |
| 631 #endif | 590 #endif |
| 632 break; | 591 break; |
| 633 case ui::EVENT_REWRITE_CONTINUE: | 592 case ui::EVENT_REWRITE_CONTINUE: |
| 634 if (flags != wheel_event.flags()) { | 593 if (flags != wheel_event.flags()) { |
| 635 *rewritten_event = base::MakeUnique<ui::MouseWheelEvent>(wheel_event); | 594 *rewritten_event = base::MakeUnique<ui::MouseWheelEvent>(wheel_event); |
| 636 (*rewritten_event)->set_flags(flags); | 595 (*rewritten_event)->set_flags(flags); |
| 637 status = ui::EVENT_REWRITE_REWRITTEN; | 596 status = ui::EVENT_REWRITE_REWRITTEN; |
| 638 #if defined(USE_X11) | 597 #if defined(USE_X11) |
| 639 ui::UpdateX11EventForFlags(rewritten_event->get()); | 598 ui::UpdateX11EventForFlags(rewritten_event->get()); |
| 640 #endif | 599 #endif |
| 641 } | 600 } |
| 642 break; | 601 break; |
| 643 case ui::EVENT_REWRITE_DISCARD: | 602 case ui::EVENT_REWRITE_DISCARD: |
| 644 NOTREACHED(); | 603 NOTREACHED(); |
| 645 break; | 604 break; |
| 646 } | 605 } |
| 647 | 606 |
| 648 return status; | 607 return status; |
| 649 } | 608 } |
| 650 | 609 |
| 651 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( | 610 ui::EventRewriteStatus EventRewriterChromeOS::RewriteTouchEvent( |
| 652 const ui::TouchEvent& touch_event, | 611 const ui::TouchEvent& touch_event, |
| 653 std::unique_ptr<ui::Event>* rewritten_event) { | 612 std::unique_ptr<ui::Event>* rewritten_event) { |
| 654 int flags = touch_event.flags(); | 613 int flags = touch_event.flags(); |
| 655 RewriteLocatedEvent(touch_event, &flags); | 614 RewriteLocatedEvent(touch_event, &flags); |
| 656 if (touch_event.flags() == flags) | 615 if (touch_event.flags() == flags) |
| 657 return ui::EVENT_REWRITE_CONTINUE; | 616 return ui::EVENT_REWRITE_CONTINUE; |
| 658 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); | 617 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); |
| 659 rewritten_event->reset(rewritten_touch_event); | 618 rewritten_event->reset(rewritten_touch_event); |
| 660 rewritten_touch_event->set_flags(flags); | 619 rewritten_touch_event->set_flags(flags); |
| 661 #if defined(USE_X11) | 620 #if defined(USE_X11) |
| 662 ui::UpdateX11EventForFlags(rewritten_touch_event); | 621 ui::UpdateX11EventForFlags(rewritten_touch_event); |
| 663 #endif | 622 #endif |
| 664 return ui::EVENT_REWRITE_REWRITTEN; | 623 return ui::EVENT_REWRITE_REWRITTEN; |
| 665 } | 624 } |
| 666 | 625 |
| 667 ui::EventRewriteStatus EventRewriter::RewriteScrollEvent( | 626 ui::EventRewriteStatus EventRewriterChromeOS::RewriteScrollEvent( |
| 668 const ui::ScrollEvent& scroll_event, | 627 const ui::ScrollEvent& scroll_event, |
| 669 std::unique_ptr<ui::Event>* rewritten_event) { | 628 std::unique_ptr<ui::Event>* rewritten_event) { |
| 670 if (!sticky_keys_controller_) | 629 if (!sticky_keys_controller_) |
| 671 return ui::EVENT_REWRITE_CONTINUE; | 630 return ui::EVENT_REWRITE_CONTINUE; |
| 672 ui::EventRewriteStatus status = | 631 ui::EventRewriteStatus status = |
| 673 sticky_keys_controller_->RewriteEvent(scroll_event, rewritten_event); | 632 sticky_keys_controller_->RewriteEvent(scroll_event, rewritten_event); |
| 674 // Scroll event shouldn't be discarded. | 633 // Scroll event shouldn't be discarded. |
| 675 DCHECK_NE(status, ui::EVENT_REWRITE_DISCARD); | 634 DCHECK_NE(status, ui::EVENT_REWRITE_DISCARD); |
| 676 #if defined(USE_X11) | 635 #if defined(USE_X11) |
| 677 if (status != ui::EVENT_REWRITE_CONTINUE) | 636 if (status != ui::EVENT_REWRITE_CONTINUE) |
| 678 ui::UpdateX11EventForFlags(rewritten_event->get()); | 637 ui::UpdateX11EventForFlags(rewritten_event->get()); |
| 679 #endif | 638 #endif |
| 680 return status; | 639 return status; |
| 681 } | 640 } |
| 682 | 641 |
| 683 bool EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, | 642 bool EventRewriterChromeOS::RewriteModifierKeys(const ui::KeyEvent& key_event, |
| 684 MutableKeyState* state) { | 643 MutableKeyState* state) { |
| 685 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 644 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 686 key_event.type() == ui::ET_KEY_RELEASED); | 645 key_event.type() == ui::ET_KEY_RELEASED); |
| 687 | 646 |
| 688 // Do nothing if we have just logged in as guest but have not restarted chrome | 647 if (!delegate_ || !delegate_->RewriteModifierKeys()) |
| 689 // process yet (so we are still on the login screen). In this situations we | |
| 690 // have no user profile so can not do anything useful. | |
| 691 // Note that currently, unlike other accounts, when user logs in as guest, we | |
| 692 // restart chrome process. In future this is to be changed. | |
| 693 // TODO(glotov): remove the following condition when we do not restart chrome | |
| 694 // when user logs in as guest. | |
| 695 // TODO(kpschoedel): check whether this is still necessary. | |
| 696 if (user_manager::UserManager::Get()->IsLoggedInAsGuest() && | |
| 697 LoginDisplayHost::default_host()) | |
| 698 return false; | |
| 699 | |
| 700 const PrefService* pref_service = GetPrefService(); | |
| 701 if (!pref_service) | |
| 702 return false; | 648 return false; |
| 703 | 649 |
| 704 // Preserve a copy of the original before rewriting |state| based on | 650 // Preserve a copy of the original before rewriting |state| based on |
| 705 // user preferences, device configuration, and certain IME properties. | 651 // user preferences, device configuration, and certain IME properties. |
| 706 MutableKeyState incoming = *state; | 652 MutableKeyState incoming = *state; |
| 707 state->flags = ui::EF_NONE; | 653 state->flags = ui::EF_NONE; |
| 708 int characteristic_flag = ui::EF_NONE; | 654 int characteristic_flag = ui::EF_NONE; |
| 709 bool exact_event = false; | 655 bool exact_event = false; |
| 710 | 656 |
| 711 // First, remap the key code. | 657 // First, remap the key code. |
| 712 const ModifierRemapping* remapped_key = NULL; | 658 const ModifierRemapping* remapped_key = nullptr; |
| 713 // Remapping based on DomKey. | 659 // Remapping based on DomKey. |
| 714 switch (incoming.key) { | 660 switch (incoming.key) { |
| 715 // On Chrome OS, F15 (XF86XK_Launch6) with NumLock (Mod2Mask) is sent | 661 // On Chrome OS, F15 (XF86XK_Launch6) with NumLock (Mod2Mask) is sent |
| 716 // when Diamond key is pressed. | 662 // when Diamond key is pressed. |
| 717 case ui::DomKey::F15: | 663 case ui::DomKey::F15: |
| 718 // When diamond key is not available, the configuration UI for Diamond | 664 // When diamond key is not available, the configuration UI for Diamond |
| 719 // key is not shown. Therefore, ignore the kLanguageRemapDiamondKeyTo | 665 // key is not shown. Therefore, ignore the kLanguageRemapDiamondKeyTo |
| 720 // syncable pref. | 666 // syncable pref. |
| 721 if (HasDiamondKey()) | 667 if (HasDiamondKey()) |
| 722 remapped_key = | 668 remapped_key = |
| 723 GetRemappedKey(prefs::kLanguageRemapDiamondKeyTo, *pref_service); | 669 GetRemappedKey(prefs::kLanguageRemapDiamondKeyTo, delegate_); |
| 724 // Default behavior of F15 is Control, even if --has-chromeos-diamond-key | 670 // Default behavior of F15 is Control, even if --has-chromeos-diamond-key |
| 725 // is absent, according to unit test comments. | 671 // is absent, according to unit test comments. |
| 726 if (!remapped_key) { | 672 if (!remapped_key) { |
| 727 DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->result.key_code); | 673 DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->result.key_code); |
| 728 remapped_key = kModifierRemappingCtrl; | 674 remapped_key = kModifierRemappingCtrl; |
| 729 } | 675 } |
| 730 break; | 676 break; |
| 731 case ui::DomKey::ALT_GRAPH: | 677 case ui::DomKey::ALT_GRAPH: |
| 732 // The Neo2 codes modifiers such that CapsLock appears as VKEY_ALTGR, | 678 // The Neo2 codes modifiers such that CapsLock appears as VKEY_ALTGR, |
| 733 // but AltGraph (right Alt) also appears as VKEY_ALTGR in Neo2, | 679 // but AltGraph (right Alt) also appears as VKEY_ALTGR in Neo2, |
| 734 // as it does in other layouts. Neo2's "Mod3" is represented in | 680 // as it does in other layouts. Neo2's "Mod3" is represented in |
| 735 // EventFlags by a combination of AltGr+Mod3, while its "Mod4" is | 681 // EventFlags by a combination of AltGr+Mod3, while its "Mod4" is |
| 736 // AltGr alone. | 682 // AltGr alone. |
| 737 if (IsISOLevel5ShiftUsedByCurrentInputMethod()) { | 683 if (IsISOLevel5ShiftUsedByCurrentInputMethod()) { |
| 738 if (incoming.code == ui::DomCode::CAPS_LOCK) { | 684 if (incoming.code == ui::DomCode::CAPS_LOCK) { |
| 739 characteristic_flag = ui::EF_ALTGR_DOWN | ui::EF_MOD3_DOWN; | 685 characteristic_flag = ui::EF_ALTGR_DOWN | ui::EF_MOD3_DOWN; |
| 740 remapped_key = | 686 remapped_key = |
| 741 GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service); | 687 GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, delegate_); |
| 742 } else { | 688 } else { |
| 743 characteristic_flag = ui::EF_ALTGR_DOWN; | 689 characteristic_flag = ui::EF_ALTGR_DOWN; |
| 744 remapped_key = | 690 remapped_key = |
| 745 GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service); | 691 GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, delegate_); |
| 746 } | 692 } |
| 747 } | 693 } |
| 748 if (remapped_key && remapped_key->result.key_code == ui::VKEY_CAPITAL) | 694 if (remapped_key && remapped_key->result.key_code == ui::VKEY_CAPITAL) |
| 749 remapped_key = kModifierRemappingNeoMod3; | 695 remapped_key = kModifierRemappingNeoMod3; |
| 750 break; | 696 break; |
| 751 #if !defined(USE_X11) | 697 #if !defined(USE_X11) |
| 752 case ui::DomKey::ALT_GRAPH_LATCH: | 698 case ui::DomKey::ALT_GRAPH_LATCH: |
| 753 if (key_event.type() == ui::ET_KEY_PRESSED) { | 699 if (key_event.type() == ui::ET_KEY_PRESSED) { |
| 754 pressed_modifier_latches_ |= ui::EF_ALTGR_DOWN; | 700 pressed_modifier_latches_ |= ui::EF_ALTGR_DOWN; |
| 755 } else { | 701 } else { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 776 // Remapping based on DomCode. | 722 // Remapping based on DomCode. |
| 777 switch (incoming.code) { | 723 switch (incoming.code) { |
| 778 // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock | 724 // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock |
| 779 // is pressed (with one exception: when | 725 // is pressed (with one exception: when |
| 780 // IsISOLevel5ShiftUsedByCurrentInputMethod() is true, the key generates | 726 // IsISOLevel5ShiftUsedByCurrentInputMethod() is true, the key generates |
| 781 // XK_ISO_Level3_Shift with Mod3Mask, not XF86XK_Launch7). | 727 // XK_ISO_Level3_Shift with Mod3Mask, not XF86XK_Launch7). |
| 782 case ui::DomCode::F16: | 728 case ui::DomCode::F16: |
| 783 case ui::DomCode::CAPS_LOCK: | 729 case ui::DomCode::CAPS_LOCK: |
| 784 characteristic_flag = ui::EF_CAPS_LOCK_ON; | 730 characteristic_flag = ui::EF_CAPS_LOCK_ON; |
| 785 remapped_key = | 731 remapped_key = |
| 786 GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service); | 732 GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, delegate_); |
| 787 break; | 733 break; |
| 788 case ui::DomCode::META_LEFT: | 734 case ui::DomCode::META_LEFT: |
| 789 case ui::DomCode::META_RIGHT: | 735 case ui::DomCode::META_RIGHT: |
| 790 characteristic_flag = ui::EF_COMMAND_DOWN; | 736 characteristic_flag = ui::EF_COMMAND_DOWN; |
| 791 // Rewrite Command-L/R key presses on an Apple keyboard to Control. | 737 // Rewrite Command-L/R key presses on an Apple keyboard to Control. |
| 792 if (IsAppleKeyboard()) { | 738 if (IsAppleKeyboard()) { |
| 793 DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->result.key_code); | 739 DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->result.key_code); |
| 794 remapped_key = kModifierRemappingCtrl; | 740 remapped_key = kModifierRemappingCtrl; |
| 795 } else { | 741 } else { |
| 796 remapped_key = | 742 remapped_key = |
| 797 GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service); | 743 GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, delegate_); |
| 798 } | 744 } |
| 799 // Default behavior is Super key, hence don't remap the event if the pref | 745 // Default behavior is Super key, hence don't remap the event if the pref |
| 800 // is unavailable. | 746 // is unavailable. |
| 801 break; | 747 break; |
| 802 case ui::DomCode::CONTROL_LEFT: | 748 case ui::DomCode::CONTROL_LEFT: |
| 803 case ui::DomCode::CONTROL_RIGHT: | 749 case ui::DomCode::CONTROL_RIGHT: |
| 804 characteristic_flag = ui::EF_CONTROL_DOWN; | 750 characteristic_flag = ui::EF_CONTROL_DOWN; |
| 805 remapped_key = | 751 remapped_key = |
| 806 GetRemappedKey(prefs::kLanguageRemapControlKeyTo, *pref_service); | 752 GetRemappedKey(prefs::kLanguageRemapControlKeyTo, delegate_); |
| 807 break; | 753 break; |
| 808 case ui::DomCode::ALT_LEFT: | 754 case ui::DomCode::ALT_LEFT: |
| 809 case ui::DomCode::ALT_RIGHT: | 755 case ui::DomCode::ALT_RIGHT: |
| 810 // ALT key | 756 // ALT key |
| 811 characteristic_flag = ui::EF_ALT_DOWN; | 757 characteristic_flag = ui::EF_ALT_DOWN; |
| 812 remapped_key = | 758 remapped_key = GetRemappedKey(prefs::kLanguageRemapAltKeyTo, delegate_); |
| 813 GetRemappedKey(prefs::kLanguageRemapAltKeyTo, *pref_service); | |
| 814 break; | 759 break; |
| 815 case ui::DomCode::ESCAPE: | 760 case ui::DomCode::ESCAPE: |
| 816 remapped_key = | 761 remapped_key = |
| 817 GetRemappedKey(prefs::kLanguageRemapEscapeKeyTo, *pref_service); | 762 GetRemappedKey(prefs::kLanguageRemapEscapeKeyTo, delegate_); |
| 818 break; | 763 break; |
| 819 case ui::DomCode::BACKSPACE: | 764 case ui::DomCode::BACKSPACE: |
| 820 remapped_key = | 765 remapped_key = |
| 821 GetRemappedKey(prefs::kLanguageRemapBackspaceKeyTo, *pref_service); | 766 GetRemappedKey(prefs::kLanguageRemapBackspaceKeyTo, delegate_); |
| 822 break; | 767 break; |
| 823 default: | 768 default: |
| 824 break; | 769 break; |
| 825 } | 770 } |
| 826 | 771 |
| 827 if (remapped_key) { | 772 if (remapped_key) { |
| 828 state->key_code = remapped_key->result.key_code; | 773 state->key_code = remapped_key->result.key_code; |
| 829 state->code = remapped_key->result.code; | 774 state->code = remapped_key->result.code; |
| 830 state->key = remapped_key->result.key; | 775 state->key = remapped_key->result.key; |
| 831 incoming.flags |= characteristic_flag; | 776 incoming.flags |= characteristic_flag; |
| 832 characteristic_flag = remapped_key->flag; | 777 characteristic_flag = remapped_key->flag; |
| 833 if (remapped_key->remap_to == input_method::kCapsLockKey) | 778 if (remapped_key->remap_to == ::chromeos::input_method::kCapsLockKey) |
| 834 characteristic_flag |= ui::EF_CAPS_LOCK_ON; | 779 characteristic_flag |= ui::EF_CAPS_LOCK_ON; |
| 835 state->code = RelocateModifier( | 780 state->code = RelocateModifier( |
| 836 state->code, ui::KeycodeConverter::DomCodeToLocation(incoming.code)); | 781 state->code, ui::KeycodeConverter::DomCodeToLocation(incoming.code)); |
| 837 } | 782 } |
| 838 | 783 |
| 839 // Next, remap modifier bits. | 784 // Next, remap modifier bits. |
| 840 state->flags |= | 785 state->flags |= GetRemappedModifierMasks(key_event, incoming.flags); |
| 841 GetRemappedModifierMasks(*pref_service, key_event, incoming.flags); | |
| 842 | 786 |
| 843 // If the DomKey is not a modifier before remapping but is after, set the | 787 // If the DomKey is not a modifier before remapping but is after, set the |
| 844 // modifier latches for the later non-modifier key's modifier states. | 788 // modifier latches for the later non-modifier key's modifier states. |
| 845 bool non_modifier_to_modifier = | 789 bool non_modifier_to_modifier = |
| 846 !ui::KeycodeConverter::IsDomKeyForModifier(incoming.key) && | 790 !ui::KeycodeConverter::IsDomKeyForModifier(incoming.key) && |
| 847 ui::KeycodeConverter::IsDomKeyForModifier(state->key); | 791 ui::KeycodeConverter::IsDomKeyForModifier(state->key); |
| 848 if (key_event.type() == ui::ET_KEY_PRESSED) { | 792 if (key_event.type() == ui::ET_KEY_PRESSED) { |
| 849 state->flags |= characteristic_flag; | 793 state->flags |= characteristic_flag; |
| 850 if (non_modifier_to_modifier) | 794 if (non_modifier_to_modifier) |
| 851 pressed_modifier_latches_ |= characteristic_flag; | 795 pressed_modifier_latches_ |= characteristic_flag; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 864 if (state->key_code == ui::VKEY_CAPITAL | 808 if (state->key_code == ui::VKEY_CAPITAL |
| 865 // ... except on linux Chrome OS, where InputMethodChromeOS handles it. | 809 // ... except on linux Chrome OS, where InputMethodChromeOS handles it. |
| 866 && (base::SysInfo::IsRunningOnChromeOS() || ime_keyboard_for_testing_) | 810 && (base::SysInfo::IsRunningOnChromeOS() || ime_keyboard_for_testing_) |
| 867 #if defined(USE_X11) | 811 #if defined(USE_X11) |
| 868 // ... but for X11, do nothing if the original key is ui::VKEY_CAPITAL | 812 // ... but for X11, do nothing if the original key is ui::VKEY_CAPITAL |
| 869 // (i.e. a Caps Lock key on an external keyboard is pressed) since X | 813 // (i.e. a Caps Lock key on an external keyboard is pressed) since X |
| 870 // handles that itself. | 814 // handles that itself. |
| 871 && incoming.key_code != ui::VKEY_CAPITAL | 815 && incoming.key_code != ui::VKEY_CAPITAL |
| 872 #endif | 816 #endif |
| 873 ) { | 817 ) { |
| 874 chromeos::input_method::ImeKeyboard* ime_keyboard = | 818 ::chromeos::input_method::ImeKeyboard* ime_keyboard = |
| 875 ime_keyboard_for_testing_ | 819 ime_keyboard_for_testing_ |
| 876 ? ime_keyboard_for_testing_ | 820 ? ime_keyboard_for_testing_ |
| 877 : chromeos::input_method::InputMethodManager::Get() | 821 : ::chromeos::input_method::InputMethodManager::Get() |
| 878 ->GetImeKeyboard(); | 822 ->GetImeKeyboard(); |
| 879 ime_keyboard->SetCapsLockEnabled(!ime_keyboard->CapsLockIsEnabled()); | 823 ime_keyboard->SetCapsLockEnabled(!ime_keyboard->CapsLockIsEnabled()); |
| 880 } | 824 } |
| 881 } | 825 } |
| 882 return exact_event; | 826 return exact_event; |
| 883 } | 827 } |
| 884 | 828 |
| 885 void EventRewriter::RewriteNumPadKeys(const ui::KeyEvent& key_event, | 829 void EventRewriterChromeOS::RewriteNumPadKeys(const ui::KeyEvent& key_event, |
| 886 MutableKeyState* state) { | 830 MutableKeyState* state) { |
| 887 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 831 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 888 key_event.type() == ui::ET_KEY_RELEASED); | 832 key_event.type() == ui::ET_KEY_RELEASED); |
| 889 static const struct NumPadRemapping { | 833 static const struct NumPadRemapping { |
| 890 ui::KeyboardCode input_key_code; | 834 ui::KeyboardCode input_key_code; |
| 891 EventRewriter::MutableKeyState result; | 835 MutableKeyState result; |
| 892 } kNumPadRemappings[] = { | 836 } kNumPadRemappings[] = { |
| 893 {ui::VKEY_DELETE, | 837 {ui::VKEY_DELETE, |
| 894 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'.'>::Character, | 838 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'.'>::Character, |
| 895 ui::VKEY_DECIMAL}}, | 839 ui::VKEY_DECIMAL}}, |
| 896 {ui::VKEY_INSERT, | 840 {ui::VKEY_INSERT, |
| 897 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'0'>::Character, | 841 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'0'>::Character, |
| 898 ui::VKEY_NUMPAD0}}, | 842 ui::VKEY_NUMPAD0}}, |
| 899 {ui::VKEY_END, | 843 {ui::VKEY_END, |
| 900 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'1'>::Character, | 844 {ui::EF_NONE, ui::DomCode::NONE, ui::DomKey::Constant<'1'>::Character, |
| 901 ui::VKEY_NUMPAD1}}, | 845 ui::VKEY_NUMPAD1}}, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 927 if (state->key_code == map.input_key_code) { | 871 if (state->key_code == map.input_key_code) { |
| 928 if (ui::KeycodeConverter::DomCodeToLocation(state->code) == | 872 if (ui::KeycodeConverter::DomCodeToLocation(state->code) == |
| 929 ui::DomKeyLocation::NUMPAD) { | 873 ui::DomKeyLocation::NUMPAD) { |
| 930 ApplyRemapping(map.result, state); | 874 ApplyRemapping(map.result, state); |
| 931 } | 875 } |
| 932 return; | 876 return; |
| 933 } | 877 } |
| 934 } | 878 } |
| 935 } | 879 } |
| 936 | 880 |
| 937 void EventRewriter::RewriteExtendedKeys(const ui::KeyEvent& key_event, | 881 void EventRewriterChromeOS::RewriteExtendedKeys(const ui::KeyEvent& key_event, |
| 938 MutableKeyState* state) { | 882 MutableKeyState* state) { |
| 939 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 883 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 940 key_event.type() == ui::ET_KEY_RELEASED); | 884 key_event.type() == ui::ET_KEY_RELEASED); |
| 941 MutableKeyState incoming = *state; | 885 MutableKeyState incoming = *state; |
| 942 | 886 |
| 943 if ((incoming.flags & (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) == | 887 if ((incoming.flags & (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) == |
| 944 (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) { | 888 (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) { |
| 945 // Allow Search to avoid rewriting extended keys. | 889 // Allow Search to avoid rewriting extended keys. |
| 946 // For these, we only remove the EF_COMMAND_DOWN flag. | 890 // For these, we only remove the EF_COMMAND_DOWN flag. |
| 947 static const KeyboardRemapping::Condition kAvoidRemappings[] = { | 891 static const KeyboardRemapping::Condition kAvoidRemappings[] = { |
| 948 {// Alt+Backspace | 892 {// Alt+Backspace |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1014 {ui::EF_NONE, ui::DomCode::PAGE_DOWN, ui::DomKey::PAGE_DOWN, | 958 {ui::EF_NONE, ui::DomCode::PAGE_DOWN, ui::DomKey::PAGE_DOWN, |
| 1015 ui::VKEY_NEXT}}}; | 959 ui::VKEY_NEXT}}}; |
| 1016 if (RewriteWithKeyboardRemappings(kNonSearchRemappings, | 960 if (RewriteWithKeyboardRemappings(kNonSearchRemappings, |
| 1017 arraysize(kNonSearchRemappings), incoming, | 961 arraysize(kNonSearchRemappings), incoming, |
| 1018 state)) { | 962 state)) { |
| 1019 return; | 963 return; |
| 1020 } | 964 } |
| 1021 } | 965 } |
| 1022 } | 966 } |
| 1023 | 967 |
| 1024 void EventRewriter::RewriteFunctionKeys(const ui::KeyEvent& key_event, | 968 void EventRewriterChromeOS::RewriteFunctionKeys(const ui::KeyEvent& key_event, |
| 1025 MutableKeyState* state) { | 969 MutableKeyState* state) { |
| 1026 CHECK(key_event.type() == ui::ET_KEY_PRESSED || | 970 CHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 1027 key_event.type() == ui::ET_KEY_RELEASED); | 971 key_event.type() == ui::ET_KEY_RELEASED); |
| 1028 | 972 |
| 1029 if ((state->key_code >= ui::VKEY_F1) && (state->key_code <= ui::VKEY_F12)) { | 973 if ((state->key_code >= ui::VKEY_F1) && (state->key_code <= ui::VKEY_F12)) { |
| 1030 // By default the top row (F1-F12) keys are system keys for back, forward, | 974 // By default the top row (F1-F12) keys are system keys for back, forward, |
| 1031 // brightness, volume, etc. However, windows for v2 apps can optionally | 975 // brightness, volume, etc. However, windows for v2 apps can optionally |
| 1032 // request raw function keys for these keys. | 976 // request raw function keys for these keys. |
| 1033 bool top_row_keys_are_function_keys = TopRowKeysAreFunctionKeys(key_event); | 977 const bool top_row_keys_are_function_keys = |
| 1034 bool search_is_pressed = (state->flags & ui::EF_COMMAND_DOWN) != 0; | 978 delegate_ && delegate_->TopRowKeysAreFunctionKeys(); |
| 979 const bool search_is_pressed = (state->flags & ui::EF_COMMAND_DOWN) != 0; | |
| 1035 | 980 |
| 1036 // Search? Top Row Result | 981 // Search? Top Row Result |
| 1037 // ------- -------- ------ | 982 // ------- -------- ------ |
| 1038 // No Fn Unchanged | 983 // No Fn Unchanged |
| 1039 // No System Fn -> System | 984 // No System Fn -> System |
| 1040 // Yes Fn Fn -> System | 985 // Yes Fn Fn -> System |
| 1041 // Yes System Search+Fn -> Fn | 986 // Yes System Search+Fn -> Fn |
| 1042 if (top_row_keys_are_function_keys == search_is_pressed) { | 987 if (top_row_keys_are_function_keys == search_is_pressed) { |
| 1043 // Rewrite the F1-F12 keys on a Chromebook keyboard to system keys. | 988 // Rewrite the F1-F12 keys on a Chromebook keyboard to system keys. |
| 1044 static const KeyboardRemapping kFkeysToSystemKeys[] = { | 989 static const KeyboardRemapping kFkeysToSystemKeys[] = { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 return; | 1031 return; |
| 1087 } | 1032 } |
| 1088 } | 1033 } |
| 1089 | 1034 |
| 1090 if (state->flags & ui::EF_COMMAND_DOWN) { | 1035 if (state->flags & ui::EF_COMMAND_DOWN) { |
| 1091 // Remap Search+<number> to F<number>. | 1036 // Remap Search+<number> to F<number>. |
| 1092 // We check the DOM3 |code| here instead of the VKEY, as these keys may | 1037 // We check the DOM3 |code| here instead of the VKEY, as these keys may |
| 1093 // have different |KeyboardCode|s when modifiers are pressed, such as shift. | 1038 // have different |KeyboardCode|s when modifiers are pressed, such as shift. |
| 1094 static const struct { | 1039 static const struct { |
| 1095 ui::DomCode input_dom_code; | 1040 ui::DomCode input_dom_code; |
| 1096 EventRewriter::MutableKeyState result; | 1041 MutableKeyState result; |
| 1097 } kNumberKeysToFkeys[] = { | 1042 } kNumberKeysToFkeys[] = { |
| 1098 {ui::DomCode::DIGIT1, | 1043 {ui::DomCode::DIGIT1, |
| 1099 {ui::EF_NONE, ui::DomCode::F1, ui::DomKey::F1, ui::VKEY_F1}}, | 1044 {ui::EF_NONE, ui::DomCode::F1, ui::DomKey::F1, ui::VKEY_F1}}, |
| 1100 {ui::DomCode::DIGIT2, | 1045 {ui::DomCode::DIGIT2, |
| 1101 {ui::EF_NONE, ui::DomCode::F2, ui::DomKey::F2, ui::VKEY_F2}}, | 1046 {ui::EF_NONE, ui::DomCode::F2, ui::DomKey::F2, ui::VKEY_F2}}, |
| 1102 {ui::DomCode::DIGIT3, | 1047 {ui::DomCode::DIGIT3, |
| 1103 {ui::EF_NONE, ui::DomCode::F3, ui::DomKey::F3, ui::VKEY_F3}}, | 1048 {ui::EF_NONE, ui::DomCode::F3, ui::DomKey::F3, ui::VKEY_F3}}, |
| 1104 {ui::DomCode::DIGIT4, | 1049 {ui::DomCode::DIGIT4, |
| 1105 {ui::EF_NONE, ui::DomCode::F4, ui::DomKey::F4, ui::VKEY_F4}}, | 1050 {ui::EF_NONE, ui::DomCode::F4, ui::DomKey::F4, ui::VKEY_F4}}, |
| 1106 {ui::DomCode::DIGIT5, | 1051 {ui::DomCode::DIGIT5, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1122 for (const auto& map : kNumberKeysToFkeys) { | 1067 for (const auto& map : kNumberKeysToFkeys) { |
| 1123 if (state->code == map.input_dom_code) { | 1068 if (state->code == map.input_dom_code) { |
| 1124 state->flags &= ~ui::EF_COMMAND_DOWN; | 1069 state->flags &= ~ui::EF_COMMAND_DOWN; |
| 1125 ApplyRemapping(map.result, state); | 1070 ApplyRemapping(map.result, state); |
| 1126 return; | 1071 return; |
| 1127 } | 1072 } |
| 1128 } | 1073 } |
| 1129 } | 1074 } |
| 1130 } | 1075 } |
| 1131 | 1076 |
| 1132 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, int* flags) { | 1077 void EventRewriterChromeOS::RewriteLocatedEvent(const ui::Event& event, |
| 1133 const PrefService* pref_service = GetPrefService(); | 1078 int* flags) { |
| 1134 if (!pref_service) | 1079 if (!delegate_) |
| 1135 return; | 1080 return; |
| 1136 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); | 1081 *flags = GetRemappedModifierMasks(event, *flags); |
| 1137 } | 1082 } |
| 1138 | 1083 |
| 1139 int EventRewriter::RewriteModifierClick(const ui::MouseEvent& mouse_event, | 1084 int EventRewriterChromeOS::RewriteModifierClick( |
| 1140 int* flags) { | 1085 const ui::MouseEvent& mouse_event, |
| 1086 int* flags) { | |
| 1141 // Remap Alt+Button1 to Button3. | 1087 // Remap Alt+Button1 to Button3. |
| 1142 const int kAltLeftButton = (ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); | 1088 const int kAltLeftButton = (ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); |
| 1143 if (((*flags & kAltLeftButton) == kAltLeftButton) && | 1089 if (((*flags & kAltLeftButton) == kAltLeftButton) && |
| 1144 ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || | 1090 ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || |
| 1145 pressed_device_ids_.count(mouse_event.source_device_id()))) { | 1091 pressed_device_ids_.count(mouse_event.source_device_id()))) { |
| 1146 *flags &= ~kAltLeftButton; | 1092 *flags &= ~kAltLeftButton; |
| 1147 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; | 1093 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 1148 if (mouse_event.type() == ui::ET_MOUSE_PRESSED) | 1094 if (mouse_event.type() == ui::ET_MOUSE_PRESSED) |
| 1149 pressed_device_ids_.insert(mouse_event.source_device_id()); | 1095 pressed_device_ids_.insert(mouse_event.source_device_id()); |
| 1150 else | 1096 else |
| 1151 pressed_device_ids_.erase(mouse_event.source_device_id()); | 1097 pressed_device_ids_.erase(mouse_event.source_device_id()); |
| 1152 return ui::EF_RIGHT_MOUSE_BUTTON; | 1098 return ui::EF_RIGHT_MOUSE_BUTTON; |
| 1153 } | 1099 } |
| 1154 return ui::EF_NONE; | 1100 return ui::EF_NONE; |
| 1155 } | 1101 } |
| 1156 | 1102 |
| 1157 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal( | 1103 EventRewriterChromeOS::DeviceType |
| 1104 EventRewriterChromeOS::KeyboardDeviceAddedInternal( | |
| 1158 int device_id, | 1105 int device_id, |
| 1159 const std::string& device_name, | 1106 const std::string& device_name, |
| 1160 int vendor_id, | 1107 int vendor_id, |
| 1161 int product_id) { | 1108 int product_id) { |
| 1162 const DeviceType type = GetDeviceType(device_name, vendor_id, product_id); | 1109 const DeviceType type = GetDeviceType(device_name, vendor_id, product_id); |
| 1163 if (type == kDeviceAppleKeyboard) { | 1110 if (type == kDeviceAppleKeyboard) { |
| 1164 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " | 1111 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " |
| 1165 << "id=" << device_id; | 1112 << "id=" << device_id; |
| 1166 } else if (type == kDeviceHotrodRemote) { | 1113 } else if (type == kDeviceHotrodRemote) { |
| 1167 VLOG(1) << "Hotrod remote '" << device_name << "' connected: " | 1114 VLOG(1) << "Hotrod remote '" << device_name << "' connected: " |
| 1168 << "id=" << device_id; | 1115 << "id=" << device_id; |
| 1169 } else if (type == kDeviceVirtualCoreKeyboard) { | 1116 } else if (type == kDeviceVirtualCoreKeyboard) { |
| 1170 VLOG(1) << "Xorg virtual '" << device_name << "' connected: " | 1117 VLOG(1) << "Xorg virtual '" << device_name << "' connected: " |
| 1171 << "id=" << device_id; | 1118 << "id=" << device_id; |
| 1172 } else { | 1119 } else { |
| 1173 VLOG(1) << "Unknown keyboard '" << device_name << "' connected: " | 1120 VLOG(1) << "Unknown keyboard '" << device_name << "' connected: " |
| 1174 << "id=" << device_id; | 1121 << "id=" << device_id; |
| 1175 } | 1122 } |
| 1176 // Always overwrite the existing device_id since the X server may reuse a | 1123 // Always overwrite the existing device_id since the X server may reuse a |
| 1177 // device id for an unattached device. | 1124 // device id for an unattached device. |
| 1178 device_id_to_type_[device_id] = type; | 1125 device_id_to_type_[device_id] = type; |
| 1179 return type; | 1126 return type; |
| 1180 } | 1127 } |
| 1181 | 1128 |
| 1182 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) { | 1129 EventRewriterChromeOS::DeviceType EventRewriterChromeOS::KeyboardDeviceAdded( |
| 1130 int device_id) { | |
| 1183 if (!ui::InputDeviceManager::HasInstance()) | 1131 if (!ui::InputDeviceManager::HasInstance()) |
| 1184 return kDeviceUnknown; | 1132 return kDeviceUnknown; |
| 1185 const std::vector<ui::InputDevice>& keyboard_devices = | 1133 const std::vector<ui::InputDevice>& keyboard_devices = |
| 1186 ui::InputDeviceManager::GetInstance()->GetKeyboardDevices(); | 1134 ui::InputDeviceManager::GetInstance()->GetKeyboardDevices(); |
| 1187 for (const auto& keyboard : keyboard_devices) { | 1135 for (const auto& keyboard : keyboard_devices) { |
| 1188 if (keyboard.id == device_id) { | 1136 if (keyboard.id == device_id) { |
| 1189 return KeyboardDeviceAddedInternal( | 1137 return KeyboardDeviceAddedInternal( |
| 1190 keyboard.id, keyboard.name, keyboard.vendor_id, keyboard.product_id); | 1138 keyboard.id, keyboard.name, keyboard.vendor_id, keyboard.product_id); |
| 1191 } | 1139 } |
| 1192 } | 1140 } |
| 1193 return kDeviceUnknown; | 1141 return kDeviceUnknown; |
| 1194 } | 1142 } |
| 1195 | 1143 |
| 1196 } // namespace chromeos | 1144 } // namespace ui |
| OLD | NEW |