Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: ui/keyboard/keyboard_util.cc

Issue 20145004: Switch from text insertion to key press and release events on the virtual k… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Formatting. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "ui/keyboard/keyboard_util.h" 5 #include "ui/keyboard/keyboard_util.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/string16.h" 11 #include "base/strings/string16.h"
12 #include "grit/keyboard_resources.h" 12 #include "grit/keyboard_resources.h"
13 #include "grit/keyboard_resources_map.h" 13 #include "grit/keyboard_resources_map.h"
14 #include "ui/aura/client/aura_constants.h" 14 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/root_window.h" 15 #include "ui/aura/root_window.h"
16 #include "ui/base/ime/input_method.h" 16 #include "ui/base/ime/input_method.h"
17 #include "ui/base/ime/text_input_client.h" 17 #include "ui/base/ime/text_input_client.h"
18 #include "ui/base/keycodes/keyboard_code_conversion.h"
18 #include "ui/keyboard/keyboard_switches.h" 19 #include "ui/keyboard/keyboard_switches.h"
19 20
21 namespace {
22
23 const char kKeyPressed[] ="keyPressed";
24 const char kKeyReleased[] = "keyReleased";
25
26 const int kMinKeyCode = ui::VKEY_BACK;
27 const int kMaxKeyCode = ui::VKEY_OEM_CLEAR;
28 const int kMaxKeyChar = 0x7f;
29
30 static bool initialized = false;
31 static int unshifted_character_map[kMaxKeyChar];
32 static int shifted_character_map[kMaxKeyChar];
33
34 // Initializes mapping of characters to keycodes.
35 void InitCharacterMapping() {
36 for (int i = kMinKeyCode; i <= kMaxKeyCode; i++) {
37 uint16 ch = ui::GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(i),
bshe 2013/07/25 15:33:05 nit: indent is off here.
kevers 2013/07/26 00:53:30 Fixed.
38 ui::EF_NONE);
39 if (ch > 0 && ch < kMaxKeyChar)
40 unshifted_character_map[ch] = i;
41 ch = ui::GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(i),
42 ui::EF_SHIFT_DOWN);
43 if (ch > 0 && ch < kMaxKeyChar)
44 shifted_character_map[ch] = i;
45 }
46 initialized = true;
47 }
48
49 // Creates a synthetic KeyEvent corresponding to a |char_code|. The KeyEvent
50 // contains a keycode and modifier flags. The character code is also
51 // explicitly set to enable key events for i18n characters not found on a
52 // US-English keyboard.
53 ui::KeyEvent CreateFabricatedKeyEvent(ui::EventType type, int char_code) {
54 if (!initialized)
55 InitCharacterMapping();
56
57 ui::KeyboardCode keyCode = ui::VKEY_UNKNOWN;
58 int flags = ui::EF_NONE;
59 if (char_code < kMaxKeyChar) {
60 int unshifted = unshifted_character_map[char_code];
61 if (unshifted > 0) {
62 keyCode = static_cast<ui::KeyboardCode>(unshifted);
63 } else {
64 int shifted = shifted_character_map[char_code];
65 if (shifted > 0) {
66 keyCode = static_cast<ui::KeyboardCode>(shifted);
67 flags = ui::EF_SHIFT_DOWN;
68 }
69 }
70 }
71 ui::KeyEvent event(type, keyCode, flags, false);
72 event.set_character(char_code);
73 event.set_unmodified_character(char_code);
74 return event;
75 }
76
77 } // namespace
78
20 namespace keyboard { 79 namespace keyboard {
21 80
22 bool IsKeyboardEnabled() { 81 bool IsKeyboardEnabled() {
23 return CommandLine::ForCurrentProcess()->HasSwitch( 82 return CommandLine::ForCurrentProcess()->HasSwitch(
24 switches::kEnableVirtualKeyboard); 83 switches::kEnableVirtualKeyboard);
25 } 84 }
26 85
27 bool InsertText(const base::string16& text, aura::RootWindow* root_window) { 86 bool InsertText(const base::string16& text, aura::RootWindow* root_window) {
28 if (!root_window) 87 if (!root_window)
29 return false; 88 return false;
30 89
31 // Handle Backspace and Enter specially: using TextInputClient::InsertText is 90 // Handle Backspace and Enter specially: using TextInputClient::InsertText is
32 // very unreliable for these characters. 91 // very unreliable for these characters.
33 // TODO(bryeung): remove this code once virtual keyboards are able to send 92 // TODO(kevers): remove this code once virtual keyboards are able to send
34 // these events directly via the Input Injection API. 93 // these events directly via the Input Injection API.
35 if (text.length() == 1) { 94 if (text.length() == 1) {
36 ui::KeyboardCode code = ui::VKEY_UNKNOWN; 95 ui::KeyboardCode code = ui::VKEY_UNKNOWN;
37 if (text[0] == L'\n') 96 if (text[0] == L'\n')
38 code = ui::VKEY_RETURN; 97 code = ui::VKEY_RETURN;
39 else if (text[0] == L'\b') 98 else if (text[0] == L'\b')
40 code = ui::VKEY_BACK; 99 code = ui::VKEY_BACK;
41 100
42 if (code != ui::VKEY_UNKNOWN) { 101 if (code != ui::VKEY_UNKNOWN) {
43 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, code, 0, 0); 102 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, code, 0, 0);
(...skipping 13 matching lines...) Expand all
57 116
58 ui::TextInputClient* tic = input_method->GetTextInputClient(); 117 ui::TextInputClient* tic = input_method->GetTextInputClient();
59 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 118 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
60 return false; 119 return false;
61 120
62 tic->InsertText(text); 121 tic->InsertText(text);
63 122
64 return true; 123 return true;
65 } 124 }
66 125
126 bool DispatchKeyEvent(const std::string type,
127 int char_code,
128 aura::RootWindow* root_window) {
129 ui::EventType event_type = ui::ET_UNKNOWN;
130 if (type == kKeyPressed)
131 event_type = ui::ET_KEY_PRESSED;
132 else if (type == kKeyReleased)
133 event_type = ui::ET_KEY_RELEASED;
134 if (event_type == ui::ET_UNKNOWN)
135 return false;
136
137 ui::KeyEvent event = CreateFabricatedKeyEvent(event_type, char_code);
138 if (event.key_code() != ui::VKEY_UNKNOWN) {
139 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&event);
140 } else if (event_type == ui::ET_KEY_RELEASED) {
141 // Though the KeyEvent has setters for unicode characters that are intended
142 // for use with a virtual keyboard, these values are ignored further down
143 // the pipeline, relying on the key code. The key code is 0 for most
144 // characters not found on a US-English keyboard (the assumed configuration
145 // for fabricated key events). Fall back on inserting raw text as a short-
146 // term measure.
147 // TODO(kevers): Fix handling of unicode characters to unify the code
148 // paths and fix use cases where raw injection fails.
149 base::string16 text;
150 base::char16 chars[] = {static_cast<char16>(char_code), 0};
151 text.append(chars);
152 return InsertText(text, root_window);
153 }
154 return true;
155 }
156
67 const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { 157 const GritResourceMap* GetKeyboardExtensionResources(size_t* size) {
68 // This looks a lot like the contents of a resource map; however it is 158 // This looks a lot like the contents of a resource map; however it is
69 // necessary to have a custom path for the extension path, so the resource 159 // necessary to have a custom path for the extension path, so the resource
70 // map cannot be used directly. 160 // map cannot be used directly.
71 static const GritResourceMap kKeyboardResources[] = { 161 static const GritResourceMap kKeyboardResources[] = {
72 {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS}, 162 {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS},
73 {"keyboard/constants.js", IDR_KEYBOARD_CONSTANTS_JS}, 163 {"keyboard/constants.js", IDR_KEYBOARD_CONSTANTS_JS},
74 {"keyboard/elements/kb-altkey.html", IDR_KEYBOARD_ELEMENTS_ALTKEY}, 164 {"keyboard/elements/kb-altkey.html", IDR_KEYBOARD_ELEMENTS_ALTKEY},
75 {"keyboard/elements/kb-altkey-container.html", 165 {"keyboard/elements/kb-altkey-container.html",
76 IDR_KEYBOARD_ELEMENTS_ALTKEY_CONTAINER}, 166 IDR_KEYBOARD_ELEMENTS_ALTKEY_CONTAINER},
(...skipping 25 matching lines...) Expand all
102 {"keyboard/main.css", IDR_KEYBOARD_MAIN_CSS}, 192 {"keyboard/main.css", IDR_KEYBOARD_MAIN_CSS},
103 {"keyboard/polymer.min.js", IDR_KEYBOARD_POLYMER}, 193 {"keyboard/polymer.min.js", IDR_KEYBOARD_POLYMER},
104 {"keyboard/voice_input.js", IDR_KEYBOARD_VOICE_INPUT_JS}, 194 {"keyboard/voice_input.js", IDR_KEYBOARD_VOICE_INPUT_JS},
105 }; 195 };
106 static const size_t kKeyboardResourcesSize = arraysize(kKeyboardResources); 196 static const size_t kKeyboardResourcesSize = arraysize(kKeyboardResources);
107 *size = kKeyboardResourcesSize; 197 *size = kKeyboardResourcesSize;
108 return kKeyboardResources; 198 return kKeyboardResources;
109 } 199 }
110 200
111 } // namespace keyboard 201 } // namespace keyboard
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698