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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: ui/keyboard/keyboard_util.cc
diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc
index 076eacff109eccdc480903b38289cf1ff2d1386b..e14045ebc5512a0f16914bf3b64d9fd61f1ca684 100644
--- a/ui/keyboard/keyboard_util.cc
+++ b/ui/keyboard/keyboard_util.cc
@@ -15,8 +15,67 @@
#include "ui/aura/root_window.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h"
+#include "ui/base/keycodes/keyboard_code_conversion.h"
#include "ui/keyboard/keyboard_switches.h"
+namespace {
+
+const char kKeyPressed[] ="keyPressed";
+const char kKeyReleased[] = "keyReleased";
+
+const int kMinKeyCode = ui::VKEY_BACK;
+const int kMaxKeyCode = ui::VKEY_OEM_CLEAR;
+const int kMaxKeyChar = 0x7f;
+
+static bool initialized = false;
+static int unshifted_character_map[kMaxKeyChar];
+static int shifted_character_map[kMaxKeyChar];
+
+// Initializes mapping of characters to keycodes.
+void InitCharacterMapping() {
+ for (int i = kMinKeyCode; i <= kMaxKeyCode; i++) {
+ 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.
+ ui::EF_NONE);
+ if (ch > 0 && ch < kMaxKeyChar)
+ unshifted_character_map[ch] = i;
+ ch = ui::GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(i),
+ ui::EF_SHIFT_DOWN);
+ if (ch > 0 && ch < kMaxKeyChar)
+ shifted_character_map[ch] = i;
+ }
+ initialized = true;
+}
+
+// Creates a synthetic KeyEvent corresponding to a |char_code|. The KeyEvent
+// contains a keycode and modifier flags. The character code is also
+// explicitly set to enable key events for i18n characters not found on a
+// US-English keyboard.
+ui::KeyEvent CreateFabricatedKeyEvent(ui::EventType type, int char_code) {
+ if (!initialized)
+ InitCharacterMapping();
+
+ ui::KeyboardCode keyCode = ui::VKEY_UNKNOWN;
+ int flags = ui::EF_NONE;
+ if (char_code < kMaxKeyChar) {
+ int unshifted = unshifted_character_map[char_code];
+ if (unshifted > 0) {
+ keyCode = static_cast<ui::KeyboardCode>(unshifted);
+ } else {
+ int shifted = shifted_character_map[char_code];
+ if (shifted > 0) {
+ keyCode = static_cast<ui::KeyboardCode>(shifted);
+ flags = ui::EF_SHIFT_DOWN;
+ }
+ }
+ }
+ ui::KeyEvent event(type, keyCode, flags, false);
+ event.set_character(char_code);
+ event.set_unmodified_character(char_code);
+ return event;
+}
+
+} // namespace
+
namespace keyboard {
bool IsKeyboardEnabled() {
@@ -30,7 +89,7 @@ bool InsertText(const base::string16& text, aura::RootWindow* root_window) {
// Handle Backspace and Enter specially: using TextInputClient::InsertText is
// very unreliable for these characters.
- // TODO(bryeung): remove this code once virtual keyboards are able to send
+ // TODO(kevers): remove this code once virtual keyboards are able to send
// these events directly via the Input Injection API.
if (text.length() == 1) {
ui::KeyboardCode code = ui::VKEY_UNKNOWN;
@@ -64,6 +123,37 @@ bool InsertText(const base::string16& text, aura::RootWindow* root_window) {
return true;
}
+bool DispatchKeyEvent(const std::string type,
+ int char_code,
+ aura::RootWindow* root_window) {
+ ui::EventType event_type = ui::ET_UNKNOWN;
+ if (type == kKeyPressed)
+ event_type = ui::ET_KEY_PRESSED;
+ else if (type == kKeyReleased)
+ event_type = ui::ET_KEY_RELEASED;
+ if (event_type == ui::ET_UNKNOWN)
+ return false;
+
+ ui::KeyEvent event = CreateFabricatedKeyEvent(event_type, char_code);
+ if (event.key_code() != ui::VKEY_UNKNOWN) {
+ root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&event);
+ } else if (event_type == ui::ET_KEY_RELEASED) {
+ // Though the KeyEvent has setters for unicode characters that are intended
+ // for use with a virtual keyboard, these values are ignored further down
+ // the pipeline, relying on the key code. The key code is 0 for most
+ // characters not found on a US-English keyboard (the assumed configuration
+ // for fabricated key events). Fall back on inserting raw text as a short-
+ // term measure.
+ // TODO(kevers): Fix handling of unicode characters to unify the code
+ // paths and fix use cases where raw injection fails.
+ base::string16 text;
+ base::char16 chars[] = {static_cast<char16>(char_code), 0};
+ text.append(chars);
+ return InsertText(text, root_window);
+ }
+ return true;
+}
+
const GritResourceMap* GetKeyboardExtensionResources(size_t* size) {
// This looks a lot like the contents of a resource map; however it is
// necessary to have a custom path for the extension path, so the resource

Powered by Google App Engine
This is Rietveld 408576698