Commit b171ff9c authored by moshayedi's avatar moshayedi Committed by Commit bot

IME for Mus: Use ui::InputMethodChromeOS to provide logic for ime driver.

The goal of this CL is to modify content_browser's IMEDriver so we have access
to ui::InputMethodChromeOS's functionality in mus+ash.

This CL:
- Modifies ui::InputMethodChromeOS so it can call an ack callback after
  processing events.
- Introduces InputMethodBridge to acts as a bridge between
  ui::mojom::InputMethod and ui::InputMethodChromeOS.
- Introduces RemoteTextInputClient to send commands received from
  ui::InputMethodChromeOS to a remote client over mojo IPC.
- Modifies content_browser's IMEDriver implementation to use
  ui::InputMethodChromeOS via InputMethodBridge.
- Some unittests to verify that InputMethodBridge works correctly.

BUG=665981

Review-Url: https://codereview.chromium.org/2557493002
Cr-Commit-Position: refs/heads/master@{#437955}
parent 561b5ae6
......@@ -1892,8 +1892,14 @@ split_static_library("ui") {
# apart from aura::Window, which is also not supported).
if (!is_mac) {
sources += [
"views/ime_driver_mus.cc",
"views/ime_driver_mus.h",
"views/ime_driver/ime_driver_mus.cc",
"views/ime_driver/ime_driver_mus.h",
"views/ime_driver/input_method_bridge_chromeos.cc",
"views/ime_driver/input_method_bridge_chromeos.h",
"views/ime_driver/remote_text_input_client.cc",
"views/ime_driver/remote_text_input_client.h",
"views/ime_driver/simple_input_method.cc",
"views/ime_driver/simple_input_method.h",
"views/tabs/window_finder_mus.cc",
"views/tabs/window_finder_mus.h",
]
......
......@@ -6,7 +6,7 @@
#include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h"
#include "chrome/browser/ui/views/ime_driver_mus.h"
#include "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
#include "components/constrained_window/constrained_window_views.h"
#if defined(USE_AURA)
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/ime_driver_mus.h"
#include "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/service_manager_connection.h"
......@@ -10,41 +10,17 @@
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/ime_bridge.h"
namespace {
#if defined(OS_CHROMEOS)
#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#else
#include "chrome/browser/ui/views/ime_driver/simple_input_method.h"
#endif // defined(OS_CHROMEOS)
class InputMethod : public ui::mojom::InputMethod {
public:
explicit InputMethod(ui::mojom::TextInputClientPtr client)
: client_(std::move(client)) {}
~InputMethod() override {}
private:
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override {}
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override {}
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {}
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override {
DCHECK(key_event->IsKeyEvent());
if (key_event->AsKeyEvent()->is_char()) {
client_->InsertChar(std::move(key_event));
callback.Run(true);
} else {
callback.Run(false);
}
}
void CancelComposition() override {}
ui::mojom::TextInputClientPtr client_;
DISALLOW_COPY_AND_ASSIGN(InputMethod);
};
} // namespace
IMEDriver::IMEDriver() {
ui::IMEBridge::Initialize();
}
IMEDriver::~IMEDriver() {}
......@@ -52,7 +28,7 @@ IMEDriver::~IMEDriver() {}
void IMEDriver::Register() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
ui::mojom::IMEDriverPtr ime_driver_ptr;
mojo::MakeStrongBinding(base::WrapUnique(new IMEDriver),
mojo::MakeStrongBinding(base::MakeUnique<IMEDriver>(),
GetProxy(&ime_driver_ptr));
ui::mojom::IMERegistrarPtr ime_registrar;
content::ServiceManagerConnection::GetForProcess()
......@@ -65,13 +41,18 @@ void IMEDriver::StartSession(
int32_t session_id,
ui::mojom::TextInputClientPtr client,
ui::mojom::InputMethodRequest input_method_request) {
#if defined(OS_CHROMEOS)
input_method_bindings_[session_id] =
base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
new InputMethodBridge(std::move(client)),
std::move(input_method_request));
#else
input_method_bindings_[session_id] =
base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
new InputMethod(std::move(client)), std::move(input_method_request));
new SimpleInputMethod());
#endif
}
IMEDriver::IMEDriver() {}
void IMEDriver::CancelSession(int32_t session_id) {
input_method_bindings_.erase(session_id);
}
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
#include <stdint.h>
......@@ -15,14 +15,13 @@
class IMEDriver : public ui::mojom::IMEDriver {
public:
IMEDriver();
~IMEDriver() override;
// Instantiate the IME driver and register it to the UI service.
static void Register();
private:
IMEDriver();
// ui::mojom::IMEDriver:
void StartSession(
int32_t session_id,
......@@ -36,4 +35,4 @@ class IMEDriver : public ui::mojom::IMEDriver {
DISALLOW_COPY_AND_ASSIGN(IMEDriver);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
InputMethodBridge::InputMethodBridge(ui::mojom::TextInputClientPtr client)
: client_(base::MakeUnique<RemoteTextInputClient>(std::move(client))),
input_method_chromeos_(
base::MakeUnique<ui::InputMethodChromeOS>(nullptr)) {
input_method_chromeos_->SetFocusedTextInputClient(client_.get());
}
InputMethodBridge::~InputMethodBridge() {}
void InputMethodBridge::OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) {
// TODO(moshayedi): crbug.com/631527. Consider removing this, as
// ui::InputMethodChromeOS doesn't have this.
}
void InputMethodBridge::OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) {
input_method_chromeos_->OnTextInputTypeChanged(client_.get());
}
void InputMethodBridge::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {
input_method_chromeos_->OnCaretBoundsChanged(client_.get());
}
void InputMethodBridge::ProcessKeyEvent(
std::unique_ptr<ui::Event> event,
const ProcessKeyEventCallback& callback) {
DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent();
if (!key_event->is_char()) {
input_method_chromeos_->DispatchKeyEvent(
key_event, base::MakeUnique<base::Callback<void(bool)>>(callback));
} else {
callback.Run(false);
}
}
void InputMethodBridge::CancelComposition() {
input_method_chromeos_->CancelComposition(client_.get());
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/input_method_chromeos.h"
// This bridges between mojo InputMethod API and ui::InputMethodChromeOS. It
// forwards the received events to an instance of ui::InputMethodChromeOS.
class InputMethodBridge : public ui::mojom::InputMethod {
public:
explicit InputMethodBridge(ui::mojom::TextInputClientPtr client);
~InputMethodBridge() override;
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override;
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override;
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override;
void CancelComposition() override;
private:
std::unique_ptr<ui::TextInputClient> client_;
std::unique_ptr<ui::InputMethodChromeOS> input_method_chromeos_;
DISALLOW_COPY_AND_ASSIGN(InputMethodBridge);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include "base/bind.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/ime_bridge.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
enum class CompositionEventType {
SET,
CONFIRM,
CLEAR,
INSERT_TEXT,
INSERT_CHAR
};
struct CompositionEvent {
CompositionEventType type;
base::string16 text_data;
base::char16 char_data;
};
class TestTextInputClient : public ui::mojom::TextInputClient {
public:
explicit TestTextInputClient(ui::mojom::TextInputClientRequest request)
: binding_(this, std::move(request)) {}
CompositionEvent WaitUntilCompositionEvent() {
if (!receieved_event_.has_value()) {
run_loop_ = base::MakeUnique<base::RunLoop>();
run_loop_->Run();
run_loop_.reset();
}
CompositionEvent result = receieved_event_.value();
receieved_event_.reset();
return result;
}
private:
void SetCompositionText(const ui::CompositionText& composition) override {
CompositionEvent ev = {CompositionEventType::SET, composition.text, 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void ConfirmCompositionText() override {
CompositionEvent ev = {CompositionEventType::CONFIRM, base::string16(), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void ClearCompositionText() override {
CompositionEvent ev = {CompositionEventType::CLEAR, base::string16(), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void InsertText(const std::string& text) override {
CompositionEvent ev = {CompositionEventType::INSERT_TEXT,
base::UTF8ToUTF16(text), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void InsertChar(std::unique_ptr<ui::Event> event) override {
ASSERT_TRUE(event->IsKeyEvent());
CompositionEvent ev = {CompositionEventType::INSERT_CHAR, base::string16(),
event->AsKeyEvent()->GetCharacter()};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
mojo::Binding<ui::mojom::TextInputClient> binding_;
std::unique_ptr<base::RunLoop> run_loop_;
base::Optional<CompositionEvent> receieved_event_;
DISALLOW_COPY_AND_ASSIGN(TestTextInputClient);
};
class InputMethodBridgeChromeOSTest : public testing::Test {
public:
InputMethodBridgeChromeOSTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
~InputMethodBridgeChromeOSTest() override {}
void SetUp() override {
ui::IMEBridge::Initialize();
ui::mojom::TextInputClientPtr client_ptr;
client_ = base::MakeUnique<TestTextInputClient>(GetProxy(&client_ptr));
input_method_ = base::MakeUnique<InputMethodBridge>(std::move(client_ptr));
}
bool ProcessKeyEvent(std::unique_ptr<ui::Event> event) {
handled_.reset();
input_method_->ProcessKeyEvent(
std::move(event),
base::Bind(&InputMethodBridgeChromeOSTest::ProcessKeyEventCallback,
base::Unretained(this)));
if (!handled_.has_value()) {
run_loop_ = base::MakeUnique<base::RunLoop>();
run_loop_->Run();
run_loop_.reset();
}
return handled_.value();
}
std::unique_ptr<ui::Event> UnicodeKeyPress(ui::KeyboardCode vkey,
ui::DomCode code,
int flags,
base::char16 character) const {
return base::MakeUnique<ui::KeyEvent>(ui::ET_KEY_PRESSED, vkey, code, flags,
ui::DomKey::FromCharacter(character),
ui::EventTimeForNow());
}
protected:
void ProcessKeyEventCallback(bool handled) {
handled_ = handled;
if (run_loop_)
run_loop_->Quit();
}
content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<TestTextInputClient> client_;
std::unique_ptr<InputMethodBridge> input_method_;
std::unique_ptr<base::RunLoop> run_loop_;
base::Optional<bool> handled_;
DISALLOW_COPY_AND_ASSIGN(InputMethodBridgeChromeOSTest);
};
// Tests if hexadecimal composition provided by ui::CharacterComposer works
// correctly. ui::CharacterComposer is tried if no input method extensions
// have been registered yet.
TEST_F(InputMethodBridgeChromeOSTest, HexadecimalComposition) {
struct {
ui::KeyboardCode vkey;
ui::DomCode code;
int flags;
base::char16 character;
std::string composition_text;
} kTestSequence[] = {
{ui::VKEY_U, ui::DomCode::US_U, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
'U', "u"},
{ui::VKEY_3, ui::DomCode::DIGIT3, 0, '3', "u3"},
{ui::VKEY_0, ui::DomCode::DIGIT0, 0, '0', "u30"},
{ui::VKEY_4, ui::DomCode::DIGIT4, 0, '4', "u304"},
{ui::VKEY_2, ui::DomCode::DIGIT2, 0, '2', "u3042"},
};
// Send the Ctrl-Shift-U,3,4,0,2 sequence.
for (size_t i = 0; i < arraysize(kTestSequence); i++) {
EXPECT_TRUE(ProcessKeyEvent(
UnicodeKeyPress(kTestSequence[i].vkey, kTestSequence[i].code,
kTestSequence[i].flags, kTestSequence[i].character)));
CompositionEvent ev = client_->WaitUntilCompositionEvent();
EXPECT_EQ(CompositionEventType::SET, ev.type);
EXPECT_EQ(base::UTF8ToUTF16(kTestSequence[i].composition_text),
ev.text_data);
}
// Press the return key and verify that the composition text was converted
// to the desired text.
EXPECT_TRUE(ProcessKeyEvent(
UnicodeKeyPress(ui::VKEY_RETURN, ui::DomCode::ENTER, 0, '\r')));
CompositionEvent ev = client_->WaitUntilCompositionEvent();
EXPECT_EQ(CompositionEventType::INSERT_TEXT, ev.type);
EXPECT_EQ(base::string16(1, 0x3042), ev.text_data);
}
// Test that Ctrl-C, Ctrl-X, and Ctrl-V are not handled.
TEST_F(InputMethodBridgeChromeOSTest, ClipboardAccelerators) {
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_C, ui::DomCode::US_C,
ui::EF_CONTROL_DOWN, 'C')));
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_X, ui::DomCode::US_X,
ui::EF_CONTROL_DOWN, 'X')));
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_V, ui::DomCode::US_V,
ui::EF_CONTROL_DOWN, 'V')));
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Reduce number of log messages by logging each NOTIMPLEMENTED() only once.
// This has to be before any other includes, else default is picked up.
// See base/logging.h for details on this.
#define NOTIMPLEMENTED_POLICY 5
#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
#include "base/strings/utf_string_conversions.h"
RemoteTextInputClient::RemoteTextInputClient(
ui::mojom::TextInputClientPtr remote_client)
: remote_client_(std::move(remote_client)) {}
RemoteTextInputClient::~RemoteTextInputClient() {}
void RemoteTextInputClient::SetCompositionText(
const ui::CompositionText& composition) {
remote_client_->SetCompositionText(composition);
}
void RemoteTextInputClient::ConfirmCompositionText() {
remote_client_->ConfirmCompositionText();
}
void RemoteTextInputClient::ClearCompositionText() {
remote_client_->ClearCompositionText();
}
void RemoteTextInputClient::InsertText(const base::string16& text) {
remote_client_->InsertText(base::UTF16ToUTF8(text));
}
void RemoteTextInputClient::InsertChar(const ui::KeyEvent& event) {
remote_client_->InsertChar(ui::Event::Clone(event));
}
ui::TextInputType RemoteTextInputClient::GetTextInputType() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return ui::TEXT_INPUT_TYPE_TEXT;
}
ui::TextInputMode RemoteTextInputClient::GetTextInputMode() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return ui::TEXT_INPUT_MODE_DEFAULT;
}
base::i18n::TextDirection RemoteTextInputClient::GetTextDirection() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return base::i18n::UNKNOWN_DIRECTION;
}
int RemoteTextInputClient::GetTextInputFlags() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return 0;
}
bool RemoteTextInputClient::CanComposeInline() const {
// If we return false here, ui::InputMethodChromeOS will try to create a
// composition window. But here we are at IMEDriver, and composition
// window shouldn't be created by IMEDriver.
return true;
}
gfx::Rect RemoteTextInputClient::GetCaretBounds() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return gfx::Rect();
}
bool RemoteTextInputClient::GetCompositionCharacterBounds(
uint32_t index,
gfx::Rect* rect) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::HasCompositionText() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetTextRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetCompositionTextRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetSelectionRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::SetSelectionRange(const gfx::Range& range) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::DeleteRange(const gfx::Range& range) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetTextFromRange(const gfx::Range& range,
base::string16* text) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::OnInputMethodChanged() {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
bool RemoteTextInputClient::ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::ExtendSelectionAndDelete(size_t before,
size_t after) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
void RemoteTextInputClient::EnsureCaretNotInRect(const gfx::Rect& rect) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
bool RemoteTextInputClient::IsTextEditCommandEnabled(
ui::TextEditCommand command) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::SetTextEditCommandForNextKeyEvent(
ui::TextEditCommand command) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/text_input_client.h"
// This implementation of ui::TextInputClient sends all updates via mojo IPC to
// a remote client. This is intended to be passed to the overrides of
// ui::InputMethod::SetFocusedTextInputClient().
class RemoteTextInputClient : public ui::TextInputClient {
public:
explicit RemoteTextInputClient(ui::mojom::TextInputClientPtr remote_client);
~RemoteTextInputClient() override;
private:
// ui::TextInputClient:
void SetCompositionText(const ui::CompositionText& composition) override;
void ConfirmCompositionText() override;
void ClearCompositionText() override;
void InsertText(const base::string16& text) override;
void InsertChar(const ui::KeyEvent& event) override;
ui::TextInputType GetTextInputType() const override;
ui::TextInputMode GetTextInputMode() const override;
base::i18n::TextDirection GetTextDirection() const override;
int GetTextInputFlags() const override;
bool CanComposeInline() const override;
gfx::Rect GetCaretBounds() const override;
bool GetCompositionCharacterBounds(uint32_t index,
gfx::Rect* rect) const override;
bool HasCompositionText() const override;
bool GetTextRange(gfx::Range* range) const override;
bool GetCompositionTextRange(gfx::Range* range) const override;
bool GetSelectionRange(gfx::Range* range) const override;
bool SetSelectionRange(const gfx::Range& range) override;
bool DeleteRange(const gfx::Range& range) override;
bool GetTextFromRange(const gfx::Range& range,
base::string16* text) const override;
void OnInputMethodChanged() override;
bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) override;
void ExtendSelectionAndDelete(size_t before, size_t after) override;
void EnsureCaretNotInRect(const gfx::Rect& rect) override;
bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
ui::mojom::TextInputClientPtr remote_client_;
DISALLOW_COPY_AND_ASSIGN(RemoteTextInputClient);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/ime_driver/simple_input_method.h"
SimpleInputMethod::SimpleInputMethod() {}
SimpleInputMethod::~SimpleInputMethod() {}
void SimpleInputMethod::OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) {}
void SimpleInputMethod::OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) {}
void SimpleInputMethod::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {}
void SimpleInputMethod::ProcessKeyEvent(
std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) {
callback.Run(false);
}
void SimpleInputMethod::CancelComposition() {}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
// This is to be used on platforms where a proper implementation of
// ui::mojom::InputMethod is missing. It doesn't handle any events and calls
// the callback with false, which will result in client code handling events
// locally.
class SimpleInputMethod : public ui::mojom::InputMethod {
public:
SimpleInputMethod();
~SimpleInputMethod() override;
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override;
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override;
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override;
void CancelComposition() override;
private:
DISALLOW_COPY_AND_ASSIGN(SimpleInputMethod);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
......@@ -4757,6 +4757,9 @@ test("unit_tests") {
"../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc",
"../browser/ui/views/website_settings/website_settings_popup_view_unittest.cc",
]
if (is_chromeos) {
sources += [ "../browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc" ]
}
if (!is_chromeos && (!is_mac || mac_views_browser)) {
sources += [
"../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc",
......
......@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) {
void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent();
DCHECK(key_event->is_char());
text_input_client_->InsertChar(*key_event);
text_input_client_->InsertChar(*event->AsKeyEvent());
}
} // namespace aura
......@@ -57,34 +57,9 @@ InputMethodChromeOS::~InputMethodChromeOS() {
ui::IMEBridge::Get()->SetInputContextHandler(NULL);
}
bool InputMethodChromeOS::OnUntranslatedIMEMessage(
const base::NativeEvent& event,
NativeEventResult* result) {
return false;
}
void InputMethodChromeOS::ProcessKeyEventDone(ui::KeyEvent* event,
bool is_handled) {
DCHECK(event);
if (event->type() == ET_KEY_PRESSED) {
if (is_handled) {
// IME event has a priority to be handled, so that character composer
// should be reset.
character_composer_.Reset();
} else {
// If IME does not handle key event, passes keyevent to character composer
// to be able to compose complex characters.
is_handled = ExecuteCharacterComposer(*event);
}
}
if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
ProcessKeyEventPostIME(event, is_handled);
handling_key_event_ = false;
}
void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
void InputMethodChromeOS::DispatchKeyEvent(
ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback) {
DCHECK(event->IsKeyEvent());
DCHECK(!(event->flags() & ui::EF_IS_SYNTHESIZED));
......@@ -114,28 +89,68 @@ void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
// Treating as PostIME event if character composer handles key event and
// generates some IME event,
ProcessKeyEventPostIME(event, true);
if (ack_callback)
ack_callback->Run(true);
return;
}
ProcessUnfilteredKeyPressEvent(event);
} else {
ignore_result(DispatchKeyEventPostIME(event));
}
if (ack_callback)
ack_callback->Run(false);
return;
}
handling_key_event_ = true;
if (GetEngine()->IsInterestedInKeyEvent()) {
ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback =
base::Bind(&InputMethodChromeOS::ProcessKeyEventDone,
weak_ptr_factory_.GetWeakPtr(),
// Pass the ownership of the new copied event.
base::Owned(new ui::KeyEvent(*event)));
ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = base::Bind(
&InputMethodChromeOS::ProcessKeyEventDone,
weak_ptr_factory_.GetWeakPtr(),
// Pass the ownership of the new copied event.
base::Owned(new ui::KeyEvent(*event)), Passed(&ack_callback));
GetEngine()->ProcessKeyEvent(*event, callback);
} else {
ProcessKeyEventDone(event, false);
ProcessKeyEventDone(event, std::move(ack_callback), false);
}
}
bool InputMethodChromeOS::OnUntranslatedIMEMessage(
const base::NativeEvent& event,
NativeEventResult* result) {
return false;
}
void InputMethodChromeOS::ProcessKeyEventDone(
ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback,
bool is_handled) {
DCHECK(event);
if (event->type() == ET_KEY_PRESSED) {
if (is_handled) {
// IME event has a priority to be handled, so that character composer
// should be reset.
character_composer_.Reset();
} else {
// If IME does not handle key event, passes keyevent to character composer
// to be able to compose complex characters.
is_handled = ExecuteCharacterComposer(*event);
}
}
if (ack_callback)
ack_callback->Run(is_handled);
if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
ProcessKeyEventPostIME(event, is_handled);
handling_key_event_ = false;
}
void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
DispatchKeyEvent(event, nullptr);
}
void InputMethodChromeOS::OnTextInputTypeChanged(
const TextInputClient* client) {
if (!IsTextInputClientFocused(client))
......
......@@ -27,6 +27,10 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase {
explicit InputMethodChromeOS(internal::InputMethodDelegate* delegate);
~InputMethodChromeOS() override;
using AckCallback = base::Callback<void(bool)>;
void DispatchKeyEvent(ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback);
// Overridden from InputMethod:
bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
NativeEventResult* result) override;
......@@ -100,7 +104,9 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase {
void HidePreeditText();
// Callback function for IMEEngineHandlerInterface::ProcessKeyEvent.
void ProcessKeyEventDone(ui::KeyEvent* event, bool is_handled);
void ProcessKeyEventDone(ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback,
bool is_handled);
// Returns whether an non-password input field is focused.
bool IsNonPasswordInputFieldFocused();
......
......@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) {
void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent();
DCHECK(key_event->is_char());
text_input_client_->InsertChar(*key_event);
text_input_client_->InsertChar(*event->AsKeyEvent());
}
} // namespace views
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment