| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/base/ime/input_method_ibus.h" | 5 #include "ui/base/ime/input_method_ibus.h" |
| 6 | 6 |
| 7 #include <X11/X.h> | 7 #include <X11/X.h> |
| 8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
| 10 #undef FocusIn | 10 #undef FocusIn |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "base/logging.h" | 21 #include "base/logging.h" |
| 22 #include "base/string_util.h" | 22 #include "base/string_util.h" |
| 23 #include "base/third_party/icu/icu_utf.h" | 23 #include "base/third_party/icu/icu_utf.h" |
| 24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 25 #include "chromeos/dbus/dbus_thread_manager.h" | 25 #include "chromeos/dbus/dbus_thread_manager.h" |
| 26 #include "chromeos/dbus/ibus/ibus_client.h" | 26 #include "chromeos/dbus/ibus/ibus_client.h" |
| 27 #include "chromeos/dbus/ibus/ibus_input_context_client.h" | 27 #include "chromeos/dbus/ibus/ibus_input_context_client.h" |
| 28 #include "chromeos/dbus/ibus/ibus_text.h" | 28 #include "chromeos/dbus/ibus/ibus_text.h" |
| 29 #include "ui/base/events/event_constants.h" | 29 #include "ui/base/events/event_constants.h" |
| 30 #include "ui/base/events/event_utils.h" | 30 #include "ui/base/events/event_utils.h" |
| 31 #include "ui/base/ime/ibus_client.h" | |
| 32 #include "ui/base/ime/text_input_client.h" | 31 #include "ui/base/ime/text_input_client.h" |
| 33 #include "ui/base/keycodes/keyboard_code_conversion.h" | 32 #include "ui/base/keycodes/keyboard_code_conversion.h" |
| 34 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 33 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 35 #include "ui/base/keycodes/keyboard_codes.h" | 34 #include "ui/base/keycodes/keyboard_codes.h" |
| 36 #include "ui/gfx/rect.h" | 35 #include "ui/gfx/rect.h" |
| 37 | 36 |
| 38 namespace { | 37 namespace { |
| 39 | 38 |
| 40 const int kIBusReleaseMask = 1 << 30; | 39 const int kIBusReleaseMask = 1 << 30; |
| 41 const char kClientName[] = "chrome"; | 40 const char kClientName[] = "chrome"; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 66 // Converts X flags to ibus key state flags. | 65 // Converts X flags to ibus key state flags. |
| 67 uint32 IBusStateFromXFlags(unsigned int flags) { | 66 uint32 IBusStateFromXFlags(unsigned int flags) { |
| 68 return (flags & (LockMask | ControlMask | ShiftMask | Mod1Mask | | 67 return (flags & (LockMask | ControlMask | ShiftMask | Mod1Mask | |
| 69 Button1Mask | Button2Mask | Button3Mask)); | 68 Button1Mask | Button2Mask | Button3Mask)); |
| 70 } | 69 } |
| 71 | 70 |
| 72 chromeos::IBusInputContextClient* GetInputContextClient() { | 71 chromeos::IBusInputContextClient* GetInputContextClient() { |
| 73 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); | 72 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); |
| 74 } | 73 } |
| 75 | 74 |
| 75 // Converts gfx::Rect to ibus::Rect. |
| 76 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { |
| 77 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); |
| 78 } |
| 79 |
| 76 } // namespace | 80 } // namespace |
| 77 | 81 |
| 78 namespace ui { | 82 namespace ui { |
| 79 | 83 |
| 80 // InputMethodIBus implementation ----------------------------------------- | 84 // InputMethodIBus implementation ----------------------------------------- |
| 81 InputMethodIBus::InputMethodIBus( | 85 InputMethodIBus::InputMethodIBus( |
| 82 internal::InputMethodDelegate* delegate) | 86 internal::InputMethodDelegate* delegate) |
| 83 : ibus_client_(new internal::IBusClient), | 87 : input_context_state_(INPUT_CONTEXT_STOP), |
| 84 input_context_state_(INPUT_CONTEXT_STOP), | |
| 85 create_input_context_fail_count_(0), | 88 create_input_context_fail_count_(0), |
| 86 context_focused_(false), | 89 context_focused_(false), |
| 87 composing_text_(false), | 90 composing_text_(false), |
| 88 composition_changed_(false), | 91 composition_changed_(false), |
| 89 suppress_next_result_(false), | 92 suppress_next_result_(false), |
| 90 current_keyevent_id_(0), | 93 current_keyevent_id_(0), |
| 91 weak_ptr_factory_(this) { | 94 weak_ptr_factory_(this) { |
| 92 SetDelegate(delegate); | 95 SetDelegate(delegate); |
| 93 } | 96 } |
| 94 | 97 |
| 95 InputMethodIBus::~InputMethodIBus() { | 98 InputMethodIBus::~InputMethodIBus() { |
| 96 AbandonAllPendingKeyEvents(); | 99 AbandonAllPendingKeyEvents(); |
| 97 if (IsContextReady()) | 100 if (IsContextReady()) |
| 98 DestroyContext(); | 101 DestroyContext(); |
| 99 if (GetInputContextClient()) | 102 if (GetInputContextClient()) |
| 100 GetInputContextClient()->SetInputContextHandler(NULL); | 103 GetInputContextClient()->SetInputContextHandler(NULL); |
| 101 } | 104 } |
| 102 | 105 |
| 103 void InputMethodIBus::set_ibus_client( | |
| 104 scoped_ptr<internal::IBusClient> new_client) { | |
| 105 ibus_client_.swap(new_client); | |
| 106 } | |
| 107 | |
| 108 internal::IBusClient* InputMethodIBus::ibus_client() const { | |
| 109 return ibus_client_.get(); | |
| 110 } | |
| 111 | |
| 112 void InputMethodIBus::OnFocus() { | 106 void InputMethodIBus::OnFocus() { |
| 113 InputMethodBase::OnFocus(); | 107 InputMethodBase::OnFocus(); |
| 114 UpdateContextFocusState(); | 108 UpdateContextFocusState(); |
| 115 } | 109 } |
| 116 | 110 |
| 117 void InputMethodIBus::OnBlur() { | 111 void InputMethodIBus::OnBlur() { |
| 118 ConfirmCompositionText(); | 112 ConfirmCompositionText(); |
| 119 InputMethodBase::OnBlur(); | 113 InputMethodBase::OnBlur(); |
| 120 UpdateContextFocusState(); | 114 UpdateContextFocusState(); |
| 121 } | 115 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 IBusKeyEventFromNativeKeyEvent( | 154 IBusKeyEventFromNativeKeyEvent( |
| 161 native_event, &ibus_keyval, &ibus_keycode, &ibus_state); | 155 native_event, &ibus_keyval, &ibus_keycode, &ibus_state); |
| 162 | 156 |
| 163 // If |context_| is not usable, then we can only dispatch the key event as is. | 157 // If |context_| is not usable, then we can only dispatch the key event as is. |
| 164 // We also dispatch the key event directly if the current text input type is | 158 // We also dispatch the key event directly if the current text input type is |
| 165 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. | 159 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
| 166 // Note: We need to send the key event to ibus even if the |context_| is not | 160 // Note: We need to send the key event to ibus even if the |context_| is not |
| 167 // enabled, so that ibus can have a chance to enable the |context_|. | 161 // enabled, so that ibus can have a chance to enable the |context_|. |
| 168 if (!context_focused_ || | 162 if (!context_focused_ || |
| 169 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || | 163 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || |
| 170 ibus_client_->GetInputMethodType() == | 164 !GetInputContextClient() || |
| 171 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) { | 165 GetInputContextClient()->IsXKBLayout()) { |
| 172 if (native_event->type == KeyPress) | 166 if (native_event->type == KeyPress) |
| 173 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); | 167 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); |
| 174 else | 168 else |
| 175 DispatchKeyEventPostIME(native_event); | 169 DispatchKeyEventPostIME(native_event); |
| 176 return; | 170 return; |
| 177 } | 171 } |
| 178 | 172 |
| 179 pending_key_events_.insert(current_keyevent_id_); | 173 pending_key_events_.insert(current_keyevent_id_); |
| 180 | 174 |
| 181 // Since |native_event| might be treated as XEvent whose size is bigger than | 175 // Since |native_event| might be treated as XEvent whose size is bigger than |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 // The current text input type should not be NONE if |context_| is focused. | 214 // The current text input type should not be NONE if |context_| is focused. |
| 221 DCHECK(!IsTextInputTypeNone()); | 215 DCHECK(!IsTextInputTypeNone()); |
| 222 const gfx::Rect rect = GetTextInputClient()->GetCaretBounds(); | 216 const gfx::Rect rect = GetTextInputClient()->GetCaretBounds(); |
| 223 | 217 |
| 224 gfx::Rect composition_head; | 218 gfx::Rect composition_head; |
| 225 if (!GetTextInputClient()->GetCompositionCharacterBounds(0, | 219 if (!GetTextInputClient()->GetCompositionCharacterBounds(0, |
| 226 &composition_head)) { | 220 &composition_head)) { |
| 227 composition_head = rect; | 221 composition_head = rect; |
| 228 } | 222 } |
| 229 | 223 |
| 230 // This function runs asynchronously. | 224 GetInputContextClient()->SetCursorLocation( |
| 231 ibus_client_->SetCursorLocation(rect, composition_head); | 225 GfxRectToIBusRect(rect), |
| 226 GfxRectToIBusRect(composition_head)); |
| 232 | 227 |
| 233 ui::Range text_range; | 228 ui::Range text_range; |
| 234 ui::Range selection_range; | 229 ui::Range selection_range; |
| 235 string16 surrounding_text; | 230 string16 surrounding_text; |
| 236 if (!GetTextInputClient()->GetTextRange(&text_range) || | 231 if (!GetTextInputClient()->GetTextRange(&text_range) || |
| 237 !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) || | 232 !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) || |
| 238 !GetTextInputClient()->GetSelectionRange(&selection_range)) { | 233 !GetTextInputClient()->GetSelectionRange(&selection_range)) { |
| 239 previous_surrounding_text_.clear(); | 234 previous_surrounding_text_.clear(); |
| 240 previous_selection_range_ = ui::Range::InvalidRange(); | 235 previous_selection_range_ = ui::Range::InvalidRange(); |
| 241 return; | 236 return; |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 } | 909 } |
| 915 | 910 |
| 916 // Use a black thin underline by default. | 911 // Use a black thin underline by default. |
| 917 if (out_composition->underlines.empty()) { | 912 if (out_composition->underlines.empty()) { |
| 918 out_composition->underlines.push_back(CompositionUnderline( | 913 out_composition->underlines.push_back(CompositionUnderline( |
| 919 0, length, SK_ColorBLACK, false /* thick */)); | 914 0, length, SK_ColorBLACK, false /* thick */)); |
| 920 } | 915 } |
| 921 } | 916 } |
| 922 | 917 |
| 923 } // namespace ui | 918 } // namespace ui |
| OLD | NEW |