Index: ui/base/ime/input_method_ibus.cc |
diff --git a/ui/views/ime/input_method_ibus.cc b/ui/base/ime/input_method_ibus.cc |
similarity index 74% |
copy from ui/views/ime/input_method_ibus.cc |
copy to ui/base/ime/input_method_ibus.cc |
index 9fa95254d65aac2e7b69dd97197b30564eba5de4..05b5842b81b44ad2afb496d2b2267db809e8ca91 100644 |
--- a/ui/views/ime/input_method_ibus.cc |
+++ b/ui/base/ime/input_method_ibus.cc |
@@ -2,12 +2,18 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "ui/views/ime/input_method_ibus.h" |
+#include "ui/base/ime/input_method_ibus.h" |
#include <ibus.h> |
-#if defined(TOUCH_UI) |
+ |
+#if defined(USE_AURA) |
+// Aura for Linux/ChromeOS, with and without TOUCH_UI. |
+#include <X11/X.h> |
#include <X11/Xlib.h> |
#include <X11/Xutil.h> |
+#else |
+// TODO(yusukes): Support non-Aura platforms like TOUCH_UI without Aura. |
+#error not supported yet |
#endif |
#include <algorithm> |
@@ -15,29 +21,42 @@ |
#include <set> |
#include <vector> |
-#include "base/basictypes.h" |
#include "base/command_line.h" |
+#include "base/basictypes.h" |
#include "base/i18n/char_iterator.h" |
#include "base/logging.h" |
#include "base/string_util.h" |
#include "base/third_party/icu/icu_utf.h" |
#include "base/utf_string_conversions.h" |
+#include "ui/base/events.h" |
+#include "ui/base/ime/text_input_client.h" |
#include "ui/base/keycodes/keyboard_codes.h" |
-#include "ui/gfx/point.h" |
#include "ui/gfx/rect.h" |
-#include "views/events/event.h" |
-#include "views/widget/widget.h" |
-#if defined(USE_AURA) || defined(TOUCH_UI) |
+#if defined(USE_AURA) |
+#include "ui/aura/desktop.h" |
+#include "ui/aura/event.h" |
#include "ui/base/keycodes/keyboard_code_conversion_x.h" |
-#elif defined(TOOLKIT_USES_GTK) |
-#include "ui/base/keycodes/keyboard_code_conversion_gtk.h" |
#endif |
namespace { |
-// A global flag to switch the InputMethod implementation to InputMethodIBus |
-bool inputmethod_ibus_enabled = false; |
+#if defined(USE_AURA) |
+aura::KeyEvent* GetKeyEvent(gfx::NativeEvent native_key_event) { |
+ DCHECK(native_key_event && (native_key_event->type() == ui::ET_KEY_PRESSED || |
+ native_key_event->type() == ui::ET_KEY_RELEASED)); |
+ return static_cast<aura::KeyEvent*>(native_key_event); |
+} |
+#endif |
+ |
+ui::KeyboardCode GetCode(gfx::NativeEvent native_key_event) { |
+#if defined(USE_AURA) |
+ return GetKeyEvent(native_key_event)->key_code(); |
+#else |
+ NOTIMPLEMENTED(); |
+ return ui::VKEY_UNKNOWN; |
+#endif |
+} |
// Converts ibus key state flags to event flags. |
int EventFlagsFromIBusState(guint32 state) { |
@@ -50,7 +69,7 @@ int EventFlagsFromIBusState(guint32 state) { |
(state & IBUS_BUTTON3_MASK ? ui::EF_RIGHT_BUTTON_DOWN : 0); |
} |
-// Converts event flags to ibus key state flags. |
+// Converts event flags to ibus key state flags. |
guint32 IBusStateFromEventFlags(int flags) { |
return (flags & ui::EF_CAPS_LOCK_DOWN ? IBUS_LOCK_MASK : 0) | |
(flags & ui::EF_CONTROL_DOWN ? IBUS_CONTROL_MASK : 0) | |
@@ -61,18 +80,14 @@ guint32 IBusStateFromEventFlags(int flags) { |
(flags & ui::EF_RIGHT_BUTTON_DOWN ? IBUS_BUTTON3_MASK : 0); |
} |
-void IBusKeyEventFromViewsKeyEvent(const views::KeyEvent& key, |
- guint32* ibus_keyval, |
- guint32* ibus_keycode, |
- guint32* ibus_state) { |
+void IBusKeyEventFromNativeKeyEvent(gfx::NativeEvent native_key_event, |
+ guint32* ibus_keyval, |
+ guint32* ibus_keycode, |
+ guint32* ibus_state) { |
#if defined(USE_AURA) |
- // TODO(yusukes): Handle native_event()? |
- *ibus_keyval = ui::XKeysymForWindowsKeyCode( |
- key.key_code(), key.IsShiftDown() ^ key.IsCapsLockDown()); |
- *ibus_keycode = 0; |
-#elif defined(TOUCH_UI) |
- if (key.native_event()) { |
- XKeyEvent* x_key = reinterpret_cast<XKeyEvent*>(key.native_event()); |
+ aura::KeyEvent* key = GetKeyEvent(native_key_event); |
+ if (key->native_event()) { |
+ XKeyEvent* x_key = reinterpret_cast<XKeyEvent*>(key->native_event()); |
// Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't |
// translate Shift and CapsLock states. |
KeySym keysym = NoSymbol; |
@@ -81,24 +96,17 @@ void IBusKeyEventFromViewsKeyEvent(const views::KeyEvent& key, |
*ibus_keycode = x_key->keycode; |
} else { |
*ibus_keyval = ui::XKeysymForWindowsKeyCode( |
- key.key_code(), key.IsShiftDown() ^ key.IsCapsLockDown()); |
+ key->key_code(), key->IsShiftDown() ^ key->IsCapsLockDown()); |
*ibus_keycode = 0; |
} |
-#elif defined(TOOLKIT_USES_GTK) |
- if (key.gdk_event()) { |
- GdkEventKey* gdk_key = reinterpret_cast<GdkEventKey*>(key.gdk_event()); |
- *ibus_keyval = gdk_key->keyval; |
- *ibus_keycode = gdk_key->hardware_keycode; |
- } else { |
- *ibus_keyval = ui::GdkKeyCodeForWindowsKeyCode( |
- key.key_code(), key.IsShiftDown() ^ key.IsCapsLockDown()); |
- *ibus_keycode = 0; |
- } |
-#endif |
- *ibus_state = IBusStateFromEventFlags(key.flags()); |
- if (key.type() == ui::ET_KEY_RELEASED) |
+ *ibus_state = IBusStateFromEventFlags(key->flags()); |
+ if (key->type() == ui::ET_KEY_RELEASED) |
*ibus_state |= IBUS_RELEASE_MASK; |
+#else |
+ NOTIMPLEMENTED(); |
+ *ibus_keyval = *ibus_keycode = *ibus_state = 0; |
+#endif |
} |
void ExtractCompositionTextFromIBusPreedit(IBusText* text, |
@@ -174,22 +182,20 @@ void ExtractCompositionTextFromIBusPreedit(IBusText* text, |
} |
} |
-// A switch to enable InputMethodIBus |
-const char kEnableInputMethodIBusSwitch[] = "enable-inputmethod-ibus"; |
- |
} // namespace |
-namespace views { |
+namespace ui { |
-// InputMethodIBus::PendingKeyEvent implementation ---------------------------- |
+// InputMethodIBus::PendingKeyEvent implementation ------------------------ |
class InputMethodIBus::PendingKeyEvent { |
public: |
- PendingKeyEvent(InputMethodIBus* input_method, const KeyEvent& key, |
+ PendingKeyEvent(InputMethodIBus* input_method, |
+ gfx::NativeEvent native_key_event, |
guint32 ibus_keyval); |
~PendingKeyEvent(); |
// Abandon this pending key event. Its result will just be discarded. |
- void abandon() { input_method_ = NULL; } |
+ void Abandon() { input_method_ = NULL; } |
InputMethodIBus* input_method() const { return input_method_; } |
@@ -200,42 +206,47 @@ class InputMethodIBus::PendingKeyEvent { |
private: |
InputMethodIBus* input_method_; |
- // Complete information of a views::KeyEvent. Sadly, views::KeyEvent doesn't |
- // support copy. |
- ui::EventType type_; |
+#if defined(USE_AURA) |
+ // Complete information of an aura::KeyEvent which doesn't support copy. |
+ EventType type_; |
int flags_; |
- ui::KeyboardCode key_code_; |
+ KeyboardCode key_code_; |
uint16 character_; |
uint16 unmodified_character_; |
- guint32 ibus_keyval_; |
- |
-#if defined(TOUCH_UI) |
- // corresponding XEvent data of a views::KeyEvent. It's a plain struct so we |
+ // corresponding XEvent data of an aura::KeyEvent. It's a plain struct so we |
// can do bitwise copy. |
XKeyEvent x_event_; |
#endif |
+ const guint32 ibus_keyval_; |
+ |
DISALLOW_COPY_AND_ASSIGN(PendingKeyEvent); |
}; |
-InputMethodIBus::PendingKeyEvent::PendingKeyEvent(InputMethodIBus* input_method, |
- const KeyEvent& key, |
- guint32 ibus_keyval) |
+InputMethodIBus::PendingKeyEvent::PendingKeyEvent( |
+ InputMethodIBus* input_method, |
+ gfx::NativeEvent native_key_event, |
+ guint32 ibus_keyval) |
: input_method_(input_method), |
- type_(key.type()), |
- flags_(key.flags()), |
- key_code_(key.key_code()), |
- character_(key.GetCharacter()), |
- unmodified_character_(key.GetUnmodifiedCharacter()), |
+#if defined(USE_AURA) |
+ type_(native_key_event->type()), |
+ flags_(native_key_event->flags()), |
+ key_code_(GetKeyEvent(native_key_event)->key_code()), |
+ character_(GetKeyEvent(native_key_event)->GetCharacter()), |
+ unmodified_character_( |
+ GetKeyEvent(native_key_event)->GetUnmodifiedCharacter()), |
+#endif |
ibus_keyval_(ibus_keyval) { |
DCHECK(input_method_); |
-#if defined(TOUCH_UI) |
- if (key.native_event()) |
- x_event_ = *reinterpret_cast<XKeyEvent*>(key.native_event()); |
+#if defined(USE_AURA) |
+ if (native_key_event->native_event()) |
+ x_event_ = *reinterpret_cast<XKeyEvent*>(native_key_event->native_event()); |
else |
memset(&x_event_, 0, sizeof(x_event_)); |
+#else |
+ NOTIMPLEMENTED(); |
#endif |
} |
@@ -248,22 +259,25 @@ void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) { |
if (!input_method_) |
return; |
-#if defined(TOUCH_UI) |
+#if defined(USE_AURA) |
if (x_event_.type == KeyPress || x_event_.type == KeyRelease) { |
- KeyEvent key(reinterpret_cast<XEvent*>(&x_event_)); |
- input_method_->ProcessKeyEventPostIME(key, ibus_keyval_, handled); |
+ aura::KeyEvent key( |
+ reinterpret_cast<XEvent*>(&x_event_), false /* is_char */); |
+ input_method_->ProcessKeyEventPostIME(&key, ibus_keyval_, handled); |
return; |
} |
-#endif |
- KeyEvent key(type_, key_code_, flags_); |
- if (key_code_ == ui::VKEY_UNKNOWN) { |
+ aura::KeyEvent key(type_, key_code_, flags_); |
+ if (key_code_ == VKEY_UNKNOWN) { |
key.set_character(character_); |
key.set_unmodified_character(unmodified_character_); |
} |
- input_method_->ProcessKeyEventPostIME(key, ibus_keyval_, handled); |
+ input_method_->ProcessKeyEventPostIME(&key, ibus_keyval_, handled); |
+#else |
+ NOTIMPLEMENTED(); |
+#endif |
} |
-// InputMethodIBus::PendingCreateICRequest implementation --------------------- |
+// InputMethodIBus::PendingCreateICRequest implementation ----------------- |
class InputMethodIBus::PendingCreateICRequest { |
public: |
PendingCreateICRequest(InputMethodIBus* input_method, |
@@ -271,7 +285,7 @@ class InputMethodIBus::PendingCreateICRequest { |
~PendingCreateICRequest(); |
// Abandon this pending key event. Its result will just be discarded. |
- void abandon() { |
+ void Abandon() { |
input_method_ = NULL; |
request_ptr_ = NULL; |
} |
@@ -311,8 +325,9 @@ void InputMethodIBus::PendingCreateICRequest::StoreOrAbandonInputContext( |
} |
} |
-// InputMethodIBus implementation --------------------------------------------- |
-InputMethodIBus::InputMethodIBus(internal::InputMethodDelegate* delegate) |
+// InputMethodIBus implementation ----------------------------------------- |
+InputMethodIBus::InputMethodIBus( |
+ internal::InputMethodDelegate* delegate) |
: context_(NULL), |
pending_create_ic_request_(NULL), |
context_focused_(false), |
@@ -333,20 +348,7 @@ InputMethodIBus::~InputMethodIBus() { |
GetIBus(), reinterpret_cast<gpointer>(OnIBusDisconnectedThunk), this); |
} |
-void InputMethodIBus::OnFocus() { |
- DCHECK(!widget_focused()); |
- InputMethodBase::OnFocus(); |
- UpdateContextFocusState(); |
-} |
- |
-void InputMethodIBus::OnBlur() { |
- DCHECK(widget_focused()); |
- ConfirmCompositionText(); |
- InputMethodBase::OnBlur(); |
- UpdateContextFocusState(); |
-} |
- |
-void InputMethodIBus::Init(Widget* widget) { |
+void InputMethodIBus::Init() { |
// Initializes the connection to ibus daemon. It may happen asynchronously, |
// and as soon as the connection is established, the |context_| will be |
// created automatically. |
@@ -362,34 +364,34 @@ void InputMethodIBus::Init(Widget* widget) { |
// case, we will not get "connected" signal. |
if (ibus_bus_is_connected(bus)) |
CreateContext(); |
- |
- InputMethodBase::Init(widget); |
} |
-void InputMethodIBus::DispatchKeyEvent(const KeyEvent& key) { |
- DCHECK(key.type() == ui::ET_KEY_PRESSED || key.type() == ui::ET_KEY_RELEASED); |
- DCHECK(widget_focused()); |
+void InputMethodIBus::DispatchKeyEvent(gfx::NativeEvent native_key_event) { |
+ DCHECK(native_key_event && (native_key_event->type() == ET_KEY_PRESSED || |
+ native_key_event->type() == ET_KEY_RELEASED)); |
guint32 ibus_keyval = 0; |
guint32 ibus_keycode = 0; |
guint32 ibus_state = 0; |
- IBusKeyEventFromViewsKeyEvent(key, &ibus_keyval, &ibus_keycode, &ibus_state); |
+ IBusKeyEventFromNativeKeyEvent( |
+ native_key_event, &ibus_keyval, &ibus_keycode, &ibus_state); |
// If |context_| is not usable, then we can only dispatch the key event as is. |
// We also dispatch the key event directly if the current text input type is |
- // ui::TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
+ // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
// Note: We need to send the key event to ibus even if the |context_| is not |
// enabled, so that ibus can have a chance to enable the |context_|. |
if (!context_focused_ || |
- GetTextInputType() == ui::TEXT_INPUT_TYPE_PASSWORD) { |
- if (key.type() == ui::ET_KEY_PRESSED) |
- ProcessUnfilteredKeyPressEvent(key, ibus_keyval); |
+ GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD) { |
+ if (native_key_event->type() == ET_KEY_PRESSED) |
+ ProcessUnfilteredKeyPressEvent(native_key_event, ibus_keyval); |
else |
- DispatchKeyEventPostIME(key); |
+ DispatchKeyEventPostIME(native_key_event); |
return; |
} |
- PendingKeyEvent* pending_key = new PendingKeyEvent(this, key, ibus_keyval); |
+ PendingKeyEvent* pending_key = |
+ new PendingKeyEvent(this, native_key_event, ibus_keyval); |
pending_key_events_.insert(pending_key); |
// Note: |
@@ -420,29 +422,32 @@ void InputMethodIBus::DispatchKeyEvent(const KeyEvent& key) { |
suppress_next_result_ = false; |
} |
-void InputMethodIBus::OnTextInputTypeChanged(View* view) { |
- if (context_ && IsViewFocused(view)) { |
+void InputMethodIBus::OnTextInputTypeChanged(gfx::NativeWindow window) { |
+ if (context_ && IsWindowFocused(window)) { |
ResetContext(); |
UpdateContextFocusState(); |
} |
- InputMethodBase::OnTextInputTypeChanged(view); |
+ InputMethodBase::OnTextInputTypeChanged(window); |
} |
-void InputMethodIBus::OnCaretBoundsChanged(View* view) { |
- if (!context_focused_ || !IsViewFocused(view)) |
+void InputMethodIBus::OnCaretBoundsChanged(gfx::NativeWindow window) { |
+ if (!context_focused_ || !IsWindowFocused(window)) |
return; |
// The current text input type should not be NONE if |context_| is focused. |
DCHECK(!IsTextInputTypeNone()); |
- gfx::Rect rect = GetTextInputClient()->GetCaretBounds(); |
+ const gfx::Rect rect = text_input_client()->GetCaretBounds(); |
gfx::Point origin = rect.origin(); |
gfx::Point end = gfx::Point(rect.right(), rect.bottom()); |
- // We need to convert the origin and end points separately, in case the View |
- // is scaled. |
- View::ConvertPointToScreen(view, &origin); |
- View::ConvertPointToScreen(view, &end); |
+#if defined(USE_AURA) |
+ aura::Desktop* desktop = aura::Desktop::GetInstance(); |
+ aura::Window::ConvertPointToWindow(window, desktop, &origin); |
+ aura::Window::ConvertPointToWindow(window, desktop, &end); |
+#else |
+ NOTIMPLEMENTED(); |
+#endif |
// This function runs asynchronously. |
ibus_input_context_set_cursor_location( |
@@ -450,14 +455,14 @@ void InputMethodIBus::OnCaretBoundsChanged(View* view) { |
end.x() - origin.x(), end.y() - origin.y()); |
} |
-void InputMethodIBus::CancelComposition(View* view) { |
- if (context_focused_ && IsViewFocused(view)) |
+void InputMethodIBus::CancelComposition(gfx::NativeWindow window) { |
+ if (context_focused_ && IsWindowFocused(window)) |
ResetContext(); |
} |
std::string InputMethodIBus::GetInputLocale() { |
// Not supported. |
- return std::string(""); |
+ return ""; |
} |
base::i18n::TextDirection InputMethodIBus::GetInputTextDirection() { |
@@ -469,35 +474,6 @@ bool InputMethodIBus::IsActive() { |
return true; |
} |
-// static |
-bool InputMethodIBus::IsInputMethodIBusEnabled() { |
-#if defined(TOUCH_UI) |
- return true; |
-#else |
- return inputmethod_ibus_enabled || |
- CommandLine::ForCurrentProcess()->HasSwitch( |
- kEnableInputMethodIBusSwitch); |
-#endif |
-} |
- |
-// static |
-void InputMethodIBus::SetEnableInputMethodIBus(bool enabled) { |
- inputmethod_ibus_enabled = enabled; |
-} |
- |
-void InputMethodIBus::OnWillChangeFocus(View* focused_before, View* focused) { |
- ConfirmCompositionText(); |
-} |
- |
-void InputMethodIBus::OnDidChangeFocus(View* focused_before, View* focused) { |
- UpdateContextFocusState(); |
- |
- // Force to update caret bounds, in case the View thinks that the caret |
- // bounds has not changed. |
- if (context_focused_) |
- OnCaretBoundsChanged(GetFocusedView()); |
-} |
- |
void InputMethodIBus::CreateContext() { |
DCHECK(!context_); |
DCHECK(GetIBus()); |
@@ -544,7 +520,7 @@ void InputMethodIBus::DestroyContext() { |
if (pending_create_ic_request_) { |
DCHECK(!context_); |
// |pending_create_ic_request_| will be deleted in CreateInputContextDone(). |
- pending_create_ic_request_->abandon(); |
+ pending_create_ic_request_->Abandon(); |
pending_create_ic_request_ = NULL; |
} else if (context_) { |
// ibus_proxy_destroy() will not really release the resource of |context_| |
@@ -556,7 +532,7 @@ void InputMethodIBus::DestroyContext() { |
} |
void InputMethodIBus::ConfirmCompositionText() { |
- ui::TextInputClient* client = GetTextInputClient(); |
+ TextInputClient* client = text_input_client(); |
if (client && client->HasCompositionText()) |
client->ConfirmCompositionText(); |
@@ -564,12 +540,9 @@ void InputMethodIBus::ConfirmCompositionText() { |
} |
void InputMethodIBus::ResetContext() { |
- if (!context_focused_ || !GetTextInputClient()) |
+ if (!context_focused_ || !text_input_client()) |
return; |
- DCHECK(widget_focused()); |
- DCHECK(GetFocusedView()); |
- |
// Because ibus runs in asynchronous mode, the input method may still send us |
// results after sending out the reset request, so we use a flag to discard |
// all results generated by previous key events. But because ibus does not |
@@ -608,8 +581,8 @@ void InputMethodIBus::UpdateContextFocusState() { |
const bool old_context_focused = context_focused_; |
// Use switch here in case we are going to add more text input types. |
switch (GetTextInputType()) { |
- case ui::TEXT_INPUT_TYPE_NONE: |
- case ui::TEXT_INPUT_TYPE_PASSWORD: |
+ case TEXT_INPUT_TYPE_NONE: |
+ case TEXT_INPUT_TYPE_PASSWORD: |
context_focused_ = false; |
break; |
default: |
@@ -625,92 +598,104 @@ void InputMethodIBus::UpdateContextFocusState() { |
ibus_input_context_focus_in(context_); |
} |
-void InputMethodIBus::ProcessKeyEventPostIME(const KeyEvent& key, |
+void InputMethodIBus::ProcessKeyEventPostIME(gfx::NativeEvent native_key_event, |
guint32 ibus_keyval, |
bool handled) { |
+ TextInputClient* client = text_input_client(); |
+ |
// If we get here without a focused text input client, then it means the key |
- // event is sent to the global ibus input context. |
- if (!GetTextInputClient()) { |
- DispatchKeyEventPostIME(key); |
+ // event is sent to the fake ibus input context. |
+ // TODO(yusukes): Can we remove this check? We no longer use the fake context. |
+ if (!client) { |
+ DispatchKeyEventPostIME(native_key_event); |
return; |
} |
- const View* old_focused_view = GetFocusedView(); |
- |
- // Same reason as above DCHECK. |
- DCHECK(old_focused_view); |
- |
- if (key.type() == ui::ET_KEY_PRESSED && handled) |
- ProcessFilteredKeyPressEvent(key); |
+ if (native_key_event->type() == ET_KEY_PRESSED && handled) |
+ ProcessFilteredKeyPressEvent(native_key_event); |
// In case the focus was changed by the key event. The |context_| should have |
- // been reset when the focused view changed. |
- if (old_focused_view != GetFocusedView()) |
+ // been reset when the focused window changed. |
+ if (client != text_input_client()) |
return; |
if (HasInputMethodResult()) |
- ProcessInputMethodResult(key, handled); |
+ ProcessInputMethodResult(native_key_event, handled); |
// In case the focus was changed when sending input method results to the |
- // focused View. |
- if (old_focused_view != GetFocusedView()) |
+ // focused window. |
+ if (client != text_input_client()) |
return; |
- if (key.type() == ui::ET_KEY_PRESSED && !handled) |
- ProcessUnfilteredKeyPressEvent(key, ibus_keyval); |
- else if (key.type() == ui::ET_KEY_RELEASED) |
- DispatchKeyEventPostIME(key); |
+ if (native_key_event->type() == ET_KEY_PRESSED && !handled) |
+ ProcessUnfilteredKeyPressEvent(native_key_event, ibus_keyval); |
+ else if (native_key_event->type() == ET_KEY_RELEASED) |
+ DispatchKeyEventPostIME(native_key_event); |
} |
-void InputMethodIBus::ProcessFilteredKeyPressEvent(const KeyEvent& key) { |
+void InputMethodIBus::ProcessFilteredKeyPressEvent( |
+ gfx::NativeEvent native_key_event) { |
if (NeedInsertChar()) { |
- DispatchKeyEventPostIME(key); |
+ DispatchKeyEventPostIME(native_key_event); |
} else { |
- KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_PROCESSKEY, key.flags()); |
- DispatchKeyEventPostIME(key); |
+#if defined(USE_AURA) |
+ aura::KeyEvent aura_key( |
+ ET_KEY_PRESSED, VKEY_PROCESSKEY, native_key_event->flags()); |
+ DispatchKeyEventPostIME(&aura_key); |
+#else |
+ NOTIMPLEMENTED(); |
+#endif |
} |
} |
-void InputMethodIBus::ProcessUnfilteredKeyPressEvent(const KeyEvent& key, |
- guint32 ibus_keyval) { |
- const View* old_focused_view = GetFocusedView(); |
- DispatchKeyEventPostIME(key); |
+void InputMethodIBus::ProcessUnfilteredKeyPressEvent( |
+ gfx::NativeEvent native_key_event, guint32 ibus_keyval) { |
+ TextInputClient* client = text_input_client(); |
+ DispatchKeyEventPostIME(native_key_event); |
- // We shouldn't dispatch the character anymore if the key event caused focus |
- // change. |
- if (old_focused_view != GetFocusedView()) |
+ // We shouldn't dispatch the character anymore if the key event dispatch |
+ // caused focus change. For example, in the following scenario, |
+ // 1. visit a web page which has a <textarea>. |
+ // 2. click Omnibox. |
+ // 3. enable Korean IME, press A, then press Tab to move the focus to the web |
+ // page. |
+ // We should return here not to send the Tab key event to RWHV. |
+ if (client != text_input_client()) |
return; |
// Process compose and dead keys |
if (character_composer_.FilterKeyPress(ibus_keyval)) { |
string16 composed = character_composer_.composed_character(); |
if (!composed.empty()) { |
- ui::TextInputClient* client = GetTextInputClient(); |
+ client = text_input_client(); |
if (client) |
client->InsertText(composed); |
} |
return; |
} |
+ |
// If a key event was not filtered by |context_| and |character_composer_|, |
// then it means the key event didn't generate any result text. So we need |
// to send corresponding character to the focused text input client. |
+ client = text_input_client(); |
+ const aura::KeyEvent* aura_key_event = GetKeyEvent(native_key_event); |
+ const KeyboardCode code = aura_key_event->key_code(); |
+ const char16 ch = aura_key_event->GetCharacter(); |
- ui::TextInputClient* client = GetTextInputClient(); |
- char16 ch = key.GetCharacter(); |
- if (ch && client) |
- client->InsertChar(ch, key.flags()); |
+ if (client && InputMethod::ShouldSendCharEventForKeyboardCode(code) && ch) |
+ client->InsertChar(ch, native_key_event->flags()); |
} |
-void InputMethodIBus::ProcessInputMethodResult(const KeyEvent& key, |
- bool handled) { |
- ui::TextInputClient* client = GetTextInputClient(); |
+void InputMethodIBus::ProcessInputMethodResult( |
+ gfx::NativeEvent native_key_event, bool handled) { |
+ TextInputClient* client = text_input_client(); |
DCHECK(client); |
if (result_text_.length()) { |
if (handled && NeedInsertChar()) { |
for (string16::const_iterator i = result_text_.begin(); |
i != result_text_.end(); ++i) { |
- client->InsertChar(*i, key.flags()); |
+ client->InsertChar(*i, native_key_event->flags()); |
} |
} else { |
client->InsertText(result_text_); |
@@ -734,7 +719,7 @@ void InputMethodIBus::ProcessInputMethodResult(const KeyEvent& key, |
} |
bool InputMethodIBus::NeedInsertChar() const { |
- return GetTextInputClient() && |
+ return text_input_client() && |
(IsTextInputTypeNone() || |
(!composing_text_ && result_text_.length() == 1)); |
} |
@@ -744,9 +729,13 @@ bool InputMethodIBus::HasInputMethodResult() const { |
} |
void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const { |
- KeyEvent key(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED, |
- ui::VKEY_PROCESSKEY, 0); |
- DispatchKeyEventPostIME(key); |
+#if defined(USE_AURA) |
+ aura::KeyEvent key(pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED, |
+ VKEY_PROCESSKEY, 0); |
+ DispatchKeyEventPostIME(&key); |
+#else |
+ NOTIMPLEMENTED(); |
+#endif |
} |
void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEvent* pending_key) { |
@@ -760,20 +749,21 @@ void InputMethodIBus::AbandonAllPendingKeyEvents() { |
for (std::set<PendingKeyEvent*>::iterator i = pending_key_events_.begin(); |
i != pending_key_events_.end(); ++i) { |
// The object will be deleted in ProcessKeyEventDone(). |
- (*i)->abandon(); |
+ (*i)->Abandon(); |
} |
pending_key_events_.clear(); |
} |
-void InputMethodIBus::OnCommitText(IBusInputContext* context, IBusText* text) { |
+void InputMethodIBus::OnCommitText( |
+ IBusInputContext* context, IBusText* text) { |
DCHECK_EQ(context_, context); |
if (suppress_next_result_ || !text || !text->text) |
return; |
// We need to receive input method result even if the text input type is |
- // ui::TEXT_INPUT_TYPE_NONE, to make sure we can always send correct |
+ // TEXT_INPUT_TYPE_NONE, to make sure we can always send correct |
// character for each key event to the focused text input client. |
- if (!GetTextInputClient()) |
+ if (!text_input_client()) |
return; |
string16 utf16_text(UTF8ToUTF16(text->text)); |
@@ -786,7 +776,7 @@ void InputMethodIBus::OnCommitText(IBusInputContext* context, IBusText* text) { |
// focused text input client does not support text input. |
if (pending_key_events_.empty() && !IsTextInputTypeNone()) { |
SendFakeProcessKeyEvent(true); |
- GetTextInputClient()->InsertText(utf16_text); |
+ text_input_client()->InsertText(utf16_text); |
SendFakeProcessKeyEvent(false); |
result_text_.clear(); |
} |
@@ -798,29 +788,33 @@ void InputMethodIBus::OnForwardKeyEvent(IBusInputContext* context, |
guint state) { |
DCHECK_EQ(context_, context); |
- ui::KeyboardCode key_code = ui::VKEY_UNKNOWN; |
-#if defined(USE_AURA) || defined(TOUCH_UI) |
- key_code = ui::KeyboardCodeFromXKeysym(keyval); |
-#elif defined(TOOLKIT_USES_GTK) |
- key_code = ui::WindowsKeyCodeForGdkKeyCode(keyval); |
+ KeyboardCode key_code = VKEY_UNKNOWN; |
+#if defined(USE_AURA) |
+ key_code = KeyboardCodeFromXKeysym(keyval); |
+#else |
+ NOTIMPLEMENTED(); |
#endif |
if (!key_code) |
return; |
- KeyEvent key(state & IBUS_RELEASE_MASK ? |
- ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED, |
- key_code, EventFlagsFromIBusState(state)); |
+#if defined(USE_AURA) |
+ aura::KeyEvent key(state & IBUS_RELEASE_MASK ? |
+ ET_KEY_RELEASED : ET_KEY_PRESSED, |
+ key_code, EventFlagsFromIBusState(state)); |
// It is not clear when the input method will forward us a fake key event. |
// If there is a pending key event, then we may already received some input |
// method results, so we dispatch this fake key event directly rather than |
// calling ProcessKeyEventPostIME(), which will clear pending input method |
// results. |
- if (key.type() == ui::ET_KEY_PRESSED) |
- ProcessUnfilteredKeyPressEvent(key, keyval); |
+ if (key.type() == ET_KEY_PRESSED) |
+ ProcessUnfilteredKeyPressEvent(&key, keyval); |
else |
- DispatchKeyEventPostIME(key); |
+ DispatchKeyEventPostIME(&key); |
+#else |
+ NOTIMPLEMENTED(); |
+#endif |
} |
void InputMethodIBus::OnShowPreeditText(IBusInputContext* context) { |
@@ -863,7 +857,7 @@ void InputMethodIBus::OnUpdatePreeditText(IBusInputContext* context, |
// send it to the focused text input client directly. |
if (pending_key_events_.empty()) { |
SendFakeProcessKeyEvent(true); |
- GetTextInputClient()->SetCompositionText(composition_); |
+ text_input_client()->SetCompositionText(composition_); |
SendFakeProcessKeyEvent(false); |
composition_changed_ = false; |
composition_.Clear(); |
@@ -880,7 +874,7 @@ void InputMethodIBus::OnHidePreeditText(IBusInputContext* context) { |
composition_.Clear(); |
if (pending_key_events_.empty()) { |
- ui::TextInputClient* client = GetTextInputClient(); |
+ TextInputClient* client = text_input_client(); |
if (client && client->HasCompositionText()) |
client->ClearCompositionText(); |
composition_changed_ = false; |
@@ -958,4 +952,4 @@ void InputMethodIBus::CreateInputContextDone(IBusBus* bus, |
delete data; |
} |
-} // namespace views |
+} // namespace ui |