Index: ui/base/ime/input_method_ibus.cc |
diff --git a/ui/base/ime/input_method_ibus.cc b/ui/base/ime/input_method_ibus.cc |
index d667e91692e0ad43fb9c3cb3b39a285f66a69cd8..2441a7b425467516504cb155f80def77ec28e9fa 100644 |
--- a/ui/base/ime/input_method_ibus.cc |
+++ b/ui/base/ime/input_method_ibus.cc |
@@ -23,10 +23,11 @@ |
#include "base/third_party/icu/icu_utf.h" |
#include "base/utf_string_conversions.h" |
#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/ibus/ibus_client.h" |
#include "chromeos/dbus/ibus/ibus_input_context_client.h" |
#include "chromeos/dbus/ibus/ibus_text.h" |
#include "ui/base/events.h" |
-#include "ui/base/ime/ibus_client_impl.h" |
+#include "ui/base/ime/ibus_client.h" |
#include "ui/base/ime/text_input_client.h" |
#include "ui/base/keycodes/keyboard_code_conversion.h" |
#include "ui/base/keycodes/keyboard_code_conversion_x.h" |
@@ -36,6 +37,12 @@ |
namespace { |
const int kIBusReleaseMask = 1 << 30; |
+const char kClientName[] = "chrome"; |
+ |
+// Following capability mask is introduced from |
+// http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabilite |
+const uint32 kIBusCapabilityPreeditText = 1U; |
+const uint32 kIBusCapabilityFocus = 8U; |
XKeyEvent* GetKeyEvent(XEvent* event) { |
DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); |
@@ -77,21 +84,26 @@ void IBusKeyEventFromNativeKeyEvent(const base::NativeEvent& native_event, |
*ibus_state |= kIBusReleaseMask; |
} |
+chromeos::IBusInputContextClient* GetInputContextClient() { |
+ return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); |
+} |
+ |
} // namespace |
namespace ui { |
-// InputMethodIBus::PendingKeyEventImpl implementation ------------------------ |
-class InputMethodIBus::PendingKeyEventImpl |
- : public internal::IBusClient::PendingKeyEvent { |
+// A class to hold all data related to a key event being processed by the input |
+// method but still has no result back yet. |
+class InputMethodIBus::PendingKeyEvent { |
public: |
- PendingKeyEventImpl(InputMethodIBus* input_method, |
- const base::NativeEvent& native_event, |
- uint32 ibus_keyval); |
- virtual ~PendingKeyEventImpl(); |
+ PendingKeyEvent(InputMethodIBus* input_method, |
+ const base::NativeEvent& native_event, |
+ uint32 ibus_keyval); |
+ virtual ~PendingKeyEvent(); |
- // internal::IBusClient::PendingKeyEvent overrides: |
- virtual void ProcessPostIME(bool handled) OVERRIDE; |
+ // Process this pending key event after we receive its result from the input |
+ // method. It just call through InputMethodIBus::ProcessKeyEventPostIME(). |
+ void ProcessPostIME(bool handled); |
// Abandon this pending key event. Its result will just be discarded. |
void Abandon() { input_method_ = NULL; } |
@@ -112,10 +124,10 @@ class InputMethodIBus::PendingKeyEventImpl |
const uint32 ibus_keyval_; |
- DISALLOW_COPY_AND_ASSIGN(PendingKeyEventImpl); |
+ DISALLOW_COPY_AND_ASSIGN(PendingKeyEvent); |
}; |
-InputMethodIBus::PendingKeyEventImpl::PendingKeyEventImpl( |
+InputMethodIBus::PendingKeyEvent::PendingKeyEvent( |
InputMethodIBus* input_method, |
const base::NativeEvent& native_event, |
uint32 ibus_keyval) |
@@ -128,12 +140,12 @@ InputMethodIBus::PendingKeyEventImpl::PendingKeyEventImpl( |
x_event_ = *GetKeyEvent(native_event); |
} |
-InputMethodIBus::PendingKeyEventImpl::~PendingKeyEventImpl() { |
+InputMethodIBus::PendingKeyEvent::~PendingKeyEvent() { |
if (input_method_) |
input_method_->FinishPendingKeyEvent(this); |
} |
-void InputMethodIBus::PendingKeyEventImpl::ProcessPostIME(bool handled) { |
+void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) { |
if (!input_method_) |
return; |
@@ -149,18 +161,20 @@ void InputMethodIBus::PendingKeyEventImpl::ProcessPostIME(bool handled) { |
// and 'unmodified_character_' to support i18n VKs like a French VK! |
} |
-// InputMethodIBus::PendingCreateICRequestImpl implementation ----------------- |
-class InputMethodIBus::PendingCreateICRequestImpl |
- : public internal::IBusClient::PendingCreateICRequest { |
+// A class to hold information of a pending request for creating an ibus input |
+// context. |
+class InputMethodIBus::PendingCreateICRequest { |
public: |
- PendingCreateICRequestImpl(InputMethodIBus* input_method, |
- internal::IBusClient* ibus_client, |
- PendingCreateICRequestImpl** request_ptr); |
- virtual ~PendingCreateICRequestImpl(); |
+ PendingCreateICRequest(InputMethodIBus* input_method, |
+ PendingCreateICRequest** request_ptr); |
+ virtual ~PendingCreateICRequest(); |
+ |
+ // Set up signal handlers, or destroy object proxy if the input context is |
+ // already abandoned. |
+ void InitOrAbandonInputContext(); |
- // internal::IBusClient::PendingCreateICRequest overrides: |
- virtual void InitOrAbandonInputContext() OVERRIDE; |
- virtual void OnCreateInputContextFailed() OVERRIDE; |
+ // Called if the create input context method call is failed. |
+ void OnCreateInputContextFailed(); |
// Abandon this pending key event. Its result will just be discarded. |
void Abandon() { |
@@ -171,49 +185,44 @@ class InputMethodIBus::PendingCreateICRequestImpl |
private: |
InputMethodIBus* input_method_; |
- internal::IBusClient* ibus_client_; |
- PendingCreateICRequestImpl** request_ptr_; |
+ PendingCreateICRequest** request_ptr_; |
- DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequestImpl); |
+ DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequest); |
}; |
-InputMethodIBus::PendingCreateICRequestImpl::PendingCreateICRequestImpl( |
+InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest( |
InputMethodIBus* input_method, |
- internal::IBusClient* ibus_client, |
- PendingCreateICRequestImpl** request_ptr) |
+ PendingCreateICRequest** request_ptr) |
: input_method_(input_method), |
- ibus_client_(ibus_client), |
request_ptr_(request_ptr) { |
} |
-InputMethodIBus::PendingCreateICRequestImpl::~PendingCreateICRequestImpl() { |
+InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() { |
if (request_ptr_) { |
DCHECK_EQ(*request_ptr_, this); |
*request_ptr_ = NULL; |
} |
} |
-void InputMethodIBus::PendingCreateICRequestImpl::OnCreateInputContextFailed() { |
+void InputMethodIBus::PendingCreateICRequest::OnCreateInputContextFailed() { |
// TODO(nona): If the connection between Chrome and ibus-daemon terminates |
// for some reason, the create ic request will fail. We might want to call |
// ibus_client_->CreateContext() again after some delay. |
} |
-void InputMethodIBus::PendingCreateICRequestImpl::InitOrAbandonInputContext() { |
+void InputMethodIBus::PendingCreateICRequest::InitOrAbandonInputContext() { |
if (input_method_) { |
- DCHECK(ibus_client_->IsContextReady()); |
+ DCHECK(input_method_->IsContextReady()); |
input_method_->SetUpSignalHandlers(); |
} else { |
- ibus_client_->DestroyProxy(); |
- DCHECK(!ibus_client_->IsContextReady()); |
+ GetInputContextClient()->ResetObjectProxy(); |
} |
} |
// InputMethodIBus implementation ----------------------------------------- |
InputMethodIBus::InputMethodIBus( |
internal::InputMethodDelegate* delegate) |
- : |
- ibus_client_(new internal::IBusClientImpl), |
+ : ibus_client_(new internal::IBusClient), |
pending_create_ic_request_(NULL), |
context_focused_(false), |
composing_text_(false), |
@@ -225,7 +234,7 @@ InputMethodIBus::InputMethodIBus( |
InputMethodIBus::~InputMethodIBus() { |
AbandonAllPendingKeyEvents(); |
- if (ibus_client_->IsContextReady()) |
+ if (IsContextReady()) |
DestroyContext(); |
} |
@@ -255,7 +264,7 @@ void InputMethodIBus::Init(bool focused) { |
// created automatically. |
// Create the input context if the connection is already established. |
- if (ibus_client_->IsConnected()) |
+ if (IsConnected()) |
CreateContext(); |
InputMethodBase::Init(focused); |
@@ -263,7 +272,7 @@ void InputMethodIBus::Init(bool focused) { |
// static |
void InputMethodIBus::ProcessKeyEventDone( |
- PendingKeyEventImpl* pending_key_event, bool is_handled) { |
+ PendingKeyEvent* pending_key_event, bool is_handled) { |
DCHECK(pending_key_event); |
pending_key_event->ProcessPostIME(is_handled); |
delete pending_key_event; |
@@ -296,15 +305,15 @@ void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { |
return; |
} |
- PendingKeyEventImpl* pending_key = |
- new PendingKeyEventImpl(this, native_event, ibus_keyval); |
+ PendingKeyEvent* pending_key = |
+ new PendingKeyEvent(this, native_event, ibus_keyval); |
pending_key_events_.insert(pending_key); |
- ibus_client_->SendKeyEvent(ibus_keyval, |
- ibus_keycode, |
- ibus_state, |
- base::Bind(&InputMethodIBus::ProcessKeyEventDone, |
- base::Unretained(pending_key))); |
+ GetInputContextClient()->ProcessKeyEvent( |
+ ibus_keyval, |
+ ibus_keycode, |
+ ibus_state, base::Bind(&InputMethodIBus::ProcessKeyEventDone, |
+ base::Unretained(pending_key))); |
// We don't want to suppress the result generated by this key event, but it |
// may cause problem. See comment in ResetContext() method. |
@@ -312,7 +321,7 @@ void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { |
} |
void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { |
- if (ibus_client_->IsContextReady() && IsTextInputClientFocused(client)) { |
+ if (IsContextReady() && IsTextInputClientFocused(client)) { |
ResetContext(); |
UpdateContextFocusState(); |
} |
@@ -375,17 +384,25 @@ void InputMethodIBus::OnDidChangeFocusedClient(TextInputClient* focused_before, |
} |
void InputMethodIBus::CreateContext() { |
- DCHECK(ibus_client_->IsConnected()); |
+ DCHECK(IsConnected()); |
DCHECK(!pending_create_ic_request_); |
+ pending_create_ic_request_ = new PendingCreateICRequest( |
+ this, &pending_create_ic_request_); |
+ |
// Creates the input context asynchronously. |
- pending_create_ic_request_ = new PendingCreateICRequestImpl( |
- this, ibus_client_.get(), &pending_create_ic_request_); |
- ibus_client_->CreateContext(pending_create_ic_request_); |
+ chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext( |
+ kClientName, |
+ base::Bind(&InputMethodIBus::CreateInputContextDone, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ base::Unretained(pending_create_ic_request_)), |
+ base::Bind(&InputMethodIBus::CreateInputContextFail, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ base::Unretained(pending_create_ic_request_))); |
} |
void InputMethodIBus::SetUpSignalHandlers() { |
- DCHECK(ibus_client_->IsContextReady()); |
+ DCHECK(IsContextReady()); |
// connect input context signals |
chromeos::IBusInputContextClient* input_context_client = |
@@ -410,7 +427,8 @@ void InputMethodIBus::SetUpSignalHandlers() { |
base::Bind(&InputMethodIBus::OnHidePreeditText, |
weak_ptr_factory_.GetWeakPtr())); |
- ibus_client_->SetCapabilities(internal::IBusClient::INLINE_COMPOSITION); |
+ GetInputContextClient()->SetCapabilities( |
+ kIBusCapabilityPreeditText | kIBusCapabilityFocus); |
UpdateContextFocusState(); |
// Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or |
@@ -422,7 +440,7 @@ void InputMethodIBus::SetUpSignalHandlers() { |
void InputMethodIBus::DestroyContext() { |
if (pending_create_ic_request_) { |
- DCHECK(!ibus_client_->IsContextReady()); |
+ DCHECK(!IsContextReady()); |
// |pending_create_ic_request_| will be deleted in CreateInputContextDone(). |
pending_create_ic_request_->Abandon(); |
pending_create_ic_request_ = NULL; |
@@ -434,7 +452,7 @@ void InputMethodIBus::DestroyContext() { |
// We can't use IsContextReady here because we want to destroy object proxy |
// regardless of connection. The IsContextReady contains connection check. |
ResetInputContext(); |
- DCHECK(!ibus_client_->IsContextReady()); |
+ DCHECK(!IsContextReady()); |
} |
} |
@@ -476,13 +494,13 @@ void InputMethodIBus::ResetContext() { |
// Note: some input method engines may not support reset method, such as |
// ibus-anthy. But as we control all input method engines by ourselves, we can |
// make sure that all of the engines we are using support it correctly. |
- ibus_client_->Reset(); |
+ GetInputContextClient()->Reset(); |
character_composer_.Reset(); |
} |
void InputMethodIBus::UpdateContextFocusState() { |
- if (!ibus_client_->IsContextReady()) { |
+ if (!IsContextReady()) { |
context_focused_ = false; |
return; |
} |
@@ -502,15 +520,15 @@ void InputMethodIBus::UpdateContextFocusState() { |
// We only focus in |context_| when the focus is in a normal textfield. |
// ibus_input_context_focus_{in|out}() run asynchronously. |
if (old_context_focused && !context_focused_) |
- ibus_client_->FocusOut(); |
+ GetInputContextClient()->FocusOut(); |
else if (!old_context_focused && context_focused_) |
- ibus_client_->FocusIn(); |
+ GetInputContextClient()->FocusIn(); |
if (context_focused_) { |
- internal::IBusClient::InlineCompositionCapability capability = |
- CanComposeInline() ? internal::IBusClient::INLINE_COMPOSITION |
- : internal::IBusClient::OFF_THE_SPOT_COMPOSITION; |
- ibus_client_->SetCapabilities(capability); |
+ uint32 capability = kIBusCapabilityFocus; |
+ if (CanComposeInline()) |
+ capability |= kIBusCapabilityPreeditText; |
+ GetInputContextClient()->SetCapabilities(capability); |
} |
} |
@@ -707,7 +725,7 @@ void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const { |
0); |
} |
-void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEventImpl* pending_key) { |
+void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEvent* pending_key) { |
DCHECK(pending_key_events_.count(pending_key)); |
// |pending_key| will be deleted in ProcessKeyEventDone(). |
@@ -715,7 +733,7 @@ void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEventImpl* pending_key) { |
} |
void InputMethodIBus::AbandonAllPendingKeyEvents() { |
- std::set<PendingKeyEventImpl*>::iterator i; |
+ std::set<PendingKeyEvent*>::iterator i; |
for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) { |
// The object will be deleted in ProcessKeyEventDone(). |
(*i)->Abandon(); |
@@ -845,13 +863,41 @@ void InputMethodIBus::ResetInputContext() { |
// We are dead, so we need to ask the client to stop relying on us. |
OnInputMethodChanged(); |
- ibus_client_->DestroyProxy(); |
+ GetInputContextClient()->ResetObjectProxy(); |
+} |
+ |
+void InputMethodIBus::CreateInputContextDone( |
+ PendingCreateICRequest* ic_request, |
+ const dbus::ObjectPath& object_path) { |
+ chromeos::DBusThreadManager::Get()->GetIBusInputContextClient() |
+ ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(), |
+ object_path); |
+ ic_request->InitOrAbandonInputContext(); |
+ delete ic_request; |
+} |
+ |
+void InputMethodIBus::CreateInputContextFail( |
+ PendingCreateICRequest* ic_request) { |
+ ic_request->OnCreateInputContextFailed(); |
+ delete ic_request; |
+} |
+ |
+bool InputMethodIBus::IsConnected() { |
+ return chromeos::DBusThreadManager::Get()->GetIBusBus() != NULL; |
+} |
+ |
+bool InputMethodIBus::IsContextReady() { |
+ if (!IsConnected()) |
+ return false; |
+ if (!GetInputContextClient()) |
+ return false; |
+ return GetInputContextClient()->IsObjectProxyReady(); |
} |
void InputMethodIBus::OnConnected() { |
- DCHECK(ibus_client_->IsConnected()); |
+ DCHECK(IsConnected()); |
// If already input context is initialized, do nothing. |
- if (ibus_client_->IsContextReady()) |
+ if (IsContextReady()) |
return; |
DestroyContext(); |