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

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

Issue 16972006: Insert text directly from the virtual keyboard. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix include Created 7 years, 6 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
« no previous file with comments | « ui/keyboard/keyboard_util.h ('k') | ui/keyboard/resources/api_adapter.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/string_number_conversions.h" 11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h" 12 #include "ui/aura/client/aura_constants.h"
13 #include "base/values.h" 13 #include "ui/aura/root_window.h"
14 #include "ui/base/events/event.h" 14 #include "ui/base/ime/input_method.h"
15 #include "ui/base/events/event_constants.h" 15 #include "ui/base/ime/text_input_client.h"
16 #include "ui/base/events/key_identifier_conversion.h"
17 #include "ui/keyboard/keyboard_switches.h" 16 #include "ui/keyboard/keyboard_switches.h"
18 17
19 namespace {
20
21 // KeyEvent dictionary keys
22 const char kType[] = "type";
23 const char kKeyIdentifier[] = "keyIdentifier";
24 const char kAlt[] = "altKey";
25 const char kCtrl[] = "ctrlKey";
26 const char kMeta[] = "metaKey";
27 const char kShift[] = "shiftKey";
28 const char kKeyDown[] = "keydown";
29 const char kKeyUp[] = "keyup";
30
31 // Errors.
32 const char kInvalidArgumentsListError[] =
33 "Argument list does not contain a dictionary.";
34 const char kInvalidKeyEventMissingKeyIdentifierError[] =
35 "KeyEvent object is missing the keyIdentifier field";
36 const char kInvalidKeyEventMissingTypeError[] =
37 "KeyEvent object is missing the type field";
38 const char kUnknownKeyEventTypeError[] =
39 "Unknown event type in KeyEvent.";
40 const char kUnknownOrUnsupportedKeyIdentiferError[] =
41 "Unknown or unsupported key identifier.";
42 const char kUnsupportedModifierError[] =
43 "Unsupported modifier (meta).";
44
45 ui::EventType GetTypeFromString(const std::string& type) {
46 if (type == kKeyDown) {
47 return ui::ET_KEY_PRESSED;
48 } else if (type == kKeyUp) {
49 return ui::ET_KEY_RELEASED;
50 }
51 return ui::ET_UNKNOWN;
52 }
53
54 // Converts a hex string "U+NNNN" to uint16. Returns 0 on error.
55 uint16 UnicodeIdentifierStringToInt(const std::string& key_identifier) {
56 int character = 0;
57 if ((key_identifier.length() == 6) &&
58 (key_identifier.substr(0, 2) == "U+") &&
59 (key_identifier.substr(2).find_first_not_of("0123456789abcdefABCDEF") ==
60 std::string::npos)) {
61 const bool result =
62 base::HexStringToInt(key_identifier.substr(2), &character);
63 DCHECK(result) << key_identifier;
64 }
65 return character;
66 }
67
68 } // namespace
69
70 namespace keyboard { 18 namespace keyboard {
71 19
72 bool IsKeyboardEnabled() { 20 bool IsKeyboardEnabled() {
73 return CommandLine::ForCurrentProcess()->HasSwitch( 21 return CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kEnableVirtualKeyboard); 22 switches::kEnableVirtualKeyboard);
75 } 23 }
76 24
77 ui::KeyEvent* KeyEventFromArgs(const base::ListValue* args, 25 bool InsertText(const base::string16& text, aura::RootWindow* root_window) {
78 std::string* error) { 26 if (!root_window)
79 const DictionaryValue* key_event; 27 return false;
80 if (!args->GetDictionary(0, &key_event)) {
81 *error = kInvalidArgumentsListError;
82 return NULL;
83 }
84 28
85 std::string type_name; 29 // Handle Backspace and Enter specially: using TextInputClient::InsertText is
86 if (!key_event->GetString(kType, &type_name)) { 30 // very unreliable for these characters.
87 *error = kInvalidKeyEventMissingTypeError; 31 // TODO(bryeung): remove this code once virtual keyboards are able to send
88 return NULL; 32 // these events directly via the Input Injection API.
89 } 33 if (text.length() == 1) {
34 ui::KeyboardCode code = ui::VKEY_UNKNOWN;
35 if (text[0] == L'\n')
36 code = ui::VKEY_RETURN;
37 else if (text[0] == L'\b')
38 code = ui::VKEY_BACK;
90 39
91 ui::EventType type = GetTypeFromString(type_name); 40 if (code != ui::VKEY_UNKNOWN) {
92 if (type == ui::ET_UNKNOWN) { 41 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, code, 0, 0);
93 *error = kUnknownKeyEventTypeError; 42 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event);
94 return NULL;
95 }
96 43
97 std::string identifier; 44 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, code, 0, 0);
98 if (!key_event->GetString(kKeyIdentifier, &identifier)) { 45 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event);
99 *error = kInvalidKeyEventMissingKeyIdentifierError;
100 return NULL;
101 }
102 TrimWhitespaceASCII(identifier, TRIM_ALL, &identifier);
103 46
104 const ui::KeyEvent& prototype_event = 47 return true;
105 ui::KeyEventFromKeyIdentifier(identifier);
106 uint16 character = 0;
107 if (prototype_event.key_code() == ui::VKEY_UNKNOWN) {
108 character = UnicodeIdentifierStringToInt(identifier);
109 if (!character) {
110 *error = kUnknownOrUnsupportedKeyIdentiferError;
111 return NULL;
112 } 48 }
113 } 49 }
114 50
115 int flags = 0; 51 ui::InputMethod* input_method = root_window->GetProperty(
116 if (prototype_event.key_code() != ui::VKEY_UNKNOWN) 52 aura::client::kRootWindowInputMethodKey);
117 flags = prototype_event.flags(); 53 if (!input_method)
54 return false;
118 55
119 bool flag = false; 56 ui::TextInputClient* tic = input_method->GetTextInputClient();
120 if (key_event->GetBoolean(kAlt, &flag) && flag) 57 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
121 flags |= ui::EF_ALT_DOWN; 58 return false;
122 if (key_event->GetBoolean(kCtrl, &flag) && flag)
123 flags |= ui::EF_CONTROL_DOWN;
124 if (key_event->GetBoolean(kShift, &flag) && flag)
125 flags |= ui::EF_SHIFT_DOWN;
126 if (key_event->GetBoolean(kMeta, &flag) && flag) {
127 // ui::KeyEvent does not have a Meta flag, so return an error for now.
128 *error = kUnsupportedModifierError;
129 return NULL;
130 }
131 59
132 ui::KeyEvent* event = new ui::KeyEvent( 60 tic->InsertText(text);
133 type, prototype_event.key_code(), flags, prototype_event.is_char());
134 if (character) {
135 event->set_character(character);
136 event->set_unmodified_character(character);
137 }
138 61
139 return event; 62 return true;
140 } 63 }
141 64
142 } // namespace keyboard 65 } // namespace keyboard
OLDNEW
« no previous file with comments | « ui/keyboard/keyboard_util.h ('k') | ui/keyboard/resources/api_adapter.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698