summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/input_method/input_method_engine.cc45
-rw-r--r--chrome/browser/chromeos/input_method/input_method_engine.h2
-rw-r--r--chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc34
-rw-r--r--chrome/browser/chromeos/input_method/input_method_engine_interface.h4
-rw-r--r--chrome/browser/extensions/api/input_ime/input_ime_api.cc33
5 files changed, 117 insertions, 1 deletions
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index 47f6818..8edbb57 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -11,6 +11,7 @@
#include <X11/Xutil.h>
#undef FocusIn
#undef FocusOut
+#undef RootWindow
#include <map>
#include "ash/shell.h"
@@ -25,7 +26,10 @@
#include "chromeos/ime/ibus_keymap.h"
#include "chromeos/ime/ibus_text.h"
#include "chromeos/ime/input_method_manager.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
#include "ui/events/event.h"
+#include "ui/events/keycodes/dom4/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/keyboard/keyboard_controller.h"
@@ -196,6 +200,47 @@ bool InputMethodEngine::CommitText(int context_id, const char* text,
return true;
}
+bool InputMethodEngine::SendKeyEvents(
+ int context_id,
+ const std::vector<KeyboardEvent>& events) {
+ if (!active_) {
+ return false;
+ }
+ if (context_id != context_id_ || context_id_ == -1) {
+ return false;
+ }
+
+ aura::WindowEventDispatcher* dispatcher =
+ ash::Shell::GetPrimaryRootWindow()->GetDispatcher();
+
+ for (size_t i = 0; i < events.size(); ++i) {
+ const KeyboardEvent& event = events[i];
+ const ui::EventType type =
+ (event.type == "keyup") ? ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED;
+
+ // KeyboardCodeFromXKyeSym assumes US keyboard layout.
+ ui::KeycodeConverter* conv = ui::KeycodeConverter::GetInstance();
+ DCHECK(conv);
+
+ // DOM code (KeyA) -> XKB -> XKeySym (XK_A) -> KeyboardCode (VKEY_A)
+ const uint16 native_keycode =
+ conv->CodeToNativeKeycode(event.code.c_str());
+ const uint xkeysym = ui::DefaultXKeysymFromHardwareKeycode(native_keycode);
+ const ui::KeyboardCode key_code = ui::KeyboardCodeFromXKeysym(xkeysym);
+
+ const std::string code = event.code;
+ int flags = ui::EF_NONE;
+ flags |= event.alt_key ? ui::EF_ALT_DOWN : ui::EF_NONE;
+ flags |= event.ctrl_key ? ui::EF_CONTROL_DOWN : ui::EF_NONE;
+ flags |= event.shift_key ? ui::EF_SHIFT_DOWN : ui::EF_NONE;
+ flags |= event.caps_lock ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE;
+
+ ui::KeyEvent ui_event(type, key_code, code, flags, false /* is_char */);
+ dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&ui_event);
+ }
+ return true;
+}
+
const InputMethodEngine::CandidateWindowProperty&
InputMethodEngine::GetCandidateWindowProperty() const {
return candidate_window_property_;
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index e53cfb0..b49d1de 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -53,6 +53,8 @@ class InputMethodEngine : public InputMethodEngineInterface {
virtual bool ClearComposition(int context_id, std::string* error) OVERRIDE;
virtual bool CommitText(int context_id, const char* text,
std::string* error) OVERRIDE;
+ virtual bool SendKeyEvents(int context_id,
+ const std::vector<KeyboardEvent>& events) OVERRIDE;
virtual const CandidateWindowProperty&
GetCandidateWindowProperty() const OVERRIDE;
virtual void SetCandidateWindowProperty(
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
index 62a1ce52..d7c6b87 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -403,6 +403,40 @@ IN_PROC_BROWSER_TEST_P(InputMethodEngineIBusBrowserTest,
EXPECT_EQ("COMMIT_TEXT", mock_input_context->last_commit_text());
}
{
+ SCOPED_TRACE("sendKeyEvents test");
+ mock_input_context->Reset();
+ mock_candidate_window->Reset();
+
+ const char send_key_events_test_script[] =
+ "chrome.input.ime.sendKeyEvents({"
+ " contextID: engineBridge.getFocusedContextID().contextID,"
+ " keyData : [{"
+ " type : 'keydown',"
+ " requestId : '0',"
+ " key : 'z',"
+ " code : 'KeyZ',"
+ " },{"
+ " type : 'keyup',"
+ " requestId : '1',"
+ " key : 'z',"
+ " code : 'KeyZ',"
+ " }]"
+ "});";
+
+ ExtensionTestMessageListener keyevent_listener_down(
+ "onKeyEvent:keydown:z:KeyZ:false:false:false:false", false);
+ ExtensionTestMessageListener keyevent_listener_up(
+ "onKeyEvent:keyup:z:KeyZ:false:false:false:false", false);
+
+ ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
+ send_key_events_test_script));
+
+ ASSERT_TRUE(keyevent_listener_down.WaitUntilSatisfied());
+ EXPECT_TRUE(keyevent_listener_down.was_satisfied());
+ ASSERT_TRUE(keyevent_listener_up.WaitUntilSatisfied());
+ EXPECT_TRUE(keyevent_listener_up.was_satisfied());
+ }
+ {
SCOPED_TRACE("setComposition test");
mock_input_context->Reset();
mock_candidate_window->Reset();
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_interface.h b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
index c6b0655..4fba077 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_interface.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
@@ -186,6 +186,10 @@ class InputMethodEngineInterface : public IBusEngineHandlerInterface {
virtual bool CommitText(int context_id, const char* text,
std::string* error) = 0;
+ // Send the sequence of key events.
+ virtual bool SendKeyEvents(int context_id,
+ const std::vector<KeyboardEvent>& events) = 0;
+
// This function returns the current property of the candidate window.
// The caller can use the returned value as the default property and
// modify some of specified items.
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index 4dc97da..7e1cefb 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -512,7 +512,38 @@ bool InputImeHideInputViewFunction::RunImpl() {
}
bool InputImeSendKeyEventsFunction::RunImpl() {
- // TODO(komatsu): Implement here.
+ scoped_ptr<SendKeyEvents::Params> parent_params(
+ SendKeyEvents::Params::Create(*args_));
+ const SendKeyEvents::Params::Parameters& params =
+ parent_params->parameters;
+ chromeos::InputMethodEngineInterface* engine =
+ InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
+ if (!engine) {
+ error_ = kErrorEngineNotAvailable;
+ return false;
+ }
+
+ const std::vector<linked_ptr<input_ime::KeyboardEvent> >& key_data =
+ params.key_data;
+ std::vector<chromeos::InputMethodEngine::KeyboardEvent> key_data_out;
+
+ for (size_t i = 0; i < key_data.size(); ++i) {
+ chromeos::InputMethodEngine::KeyboardEvent event;
+ event.type = input_ime::KeyboardEvent::ToString(key_data[i]->type);
+ event.key = key_data[i]->key;
+ event.code = key_data[i]->code;
+ if (key_data[i]->alt_key)
+ event.alt_key = *(key_data[i]->alt_key);
+ if (key_data[i]->ctrl_key)
+ event.ctrl_key = *(key_data[i]->ctrl_key);
+ if (key_data[i]->shift_key)
+ event.shift_key = *(key_data[i]->shift_key);
+ if (key_data[i]->caps_lock)
+ event.caps_lock = *(key_data[i]->caps_lock);
+ key_data_out.push_back(event);
+ }
+
+ engine->SendKeyEvents(params.context_id, key_data_out);
return true;
}