1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/base/ime/input_method_linux_x11.h"
7 #include "ui/base/ime/linux/linux_input_method_context_factory.h"
8 #include "ui/base/ime/text_input_client.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_utils.h"
11 #include "ui/events/keycodes/keyboard_code_conversion.h"
12 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
16 InputMethodLinuxX11::InputMethodLinuxX11(
17 internal::InputMethodDelegate* delegate) {
18 SetDelegate(delegate);
21 InputMethodLinuxX11::~InputMethodLinuxX11() {}
23 // Overriden from InputMethod.
25 void InputMethodLinuxX11::Init(bool focused) {
26 CHECK(LinuxInputMethodContextFactory::instance());
27 input_method_context_ =
28 LinuxInputMethodContextFactory::instance()->CreateInputMethodContext(
30 CHECK(input_method_context_.get());
32 InputMethodBase::Init(focused);
35 input_method_context_->OnTextInputTypeChanged(
36 GetTextInputClient() ?
37 GetTextInputClient()->GetTextInputType() :
38 TEXT_INPUT_TYPE_TEXT);
42 bool InputMethodLinuxX11::OnUntranslatedIMEMessage(
43 const base::NativeEvent& event,
44 NativeEventResult* result) {
48 bool InputMethodLinuxX11::DispatchKeyEvent(
49 const base::NativeEvent& native_key_event) {
50 EventType event_type = EventTypeFromNative(native_key_event);
51 DCHECK(event_type == ET_KEY_PRESSED || event_type == ET_KEY_RELEASED);
52 DCHECK(system_toplevel_window_focused());
54 // If no text input client, do nothing.
55 if (!GetTextInputClient())
56 return DispatchKeyEventPostIME(native_key_event);
58 // Let an IME handle the key event first.
59 if (input_method_context_->DispatchKeyEvent(native_key_event)) {
60 if (event_type == ET_KEY_PRESSED)
61 DispatchFabricatedKeyEventPostIME(ET_KEY_PRESSED, VKEY_PROCESSKEY,
62 EventFlagsFromNative(native_key_event));
66 // Otherwise, insert the character.
67 const bool handled = DispatchKeyEventPostIME(native_key_event);
68 if (event_type == ET_KEY_PRESSED && GetTextInputClient()) {
70 const int flags = EventFlagsFromNative(native_key_event);
71 if (!(flags & EF_CONTROL_DOWN))
72 ch = GetCharacterFromXEvent(native_key_event);
74 ch = GetCharacterFromKeyCode(KeyboardCodeFromNative(native_key_event),
77 GetTextInputClient()->InsertChar(ch, flags);
84 bool InputMethodLinuxX11::DispatchFabricatedKeyEvent(
85 const ui::KeyEvent& event) {
86 // Let a post IME handler handle the key event.
87 if (DispatchFabricatedKeyEventPostIME(event.type(), event.key_code(),
91 // Otherwise, insert the character.
92 if (event.type() == ET_KEY_PRESSED && GetTextInputClient()) {
93 const uint16 ch = event.GetCharacter();
95 GetTextInputClient()->InsertChar(ch, event.flags());
103 void InputMethodLinuxX11::OnTextInputTypeChanged(
104 const TextInputClient* client) {
105 if (IsTextInputClientFocused(client)) {
106 input_method_context_->Reset();
107 // TODO(yoichio): Support inputmode HTML attribute.
108 input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
110 InputMethodBase::OnTextInputTypeChanged(client);
113 void InputMethodLinuxX11::OnCaretBoundsChanged(const TextInputClient* client) {
114 if (IsTextInputClientFocused(client)) {
115 input_method_context_->OnCaretBoundsChanged(
116 GetTextInputClient()->GetCaretBounds());
118 InputMethodBase::OnCaretBoundsChanged(client);
121 void InputMethodLinuxX11::CancelComposition(const TextInputClient* client) {
122 if (!IsTextInputClientFocused(client))
125 input_method_context_->Reset();
126 input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
129 void InputMethodLinuxX11::OnInputLocaleChanged() {
130 InputMethodBase::OnInputLocaleChanged();
133 std::string InputMethodLinuxX11::GetInputLocale() {
137 base::i18n::TextDirection InputMethodLinuxX11::GetInputTextDirection() {
138 return input_method_context_->GetInputTextDirection();
141 bool InputMethodLinuxX11::IsActive() {
142 // InputMethodLinuxX11 is always ready and up.
146 bool InputMethodLinuxX11::IsCandidatePopupOpen() const {
147 // There seems no way to detect candidate windows or any popups.
151 // Overriden from ui::LinuxInputMethodContextDelegate
153 void InputMethodLinuxX11::OnCommit(const base::string16& text) {
154 TextInputClient* text_input_client = GetTextInputClient();
155 if (text_input_client)
156 text_input_client->InsertText(text);
159 void InputMethodLinuxX11::OnPreeditChanged(
160 const CompositionText& composition_text) {
161 TextInputClient* text_input_client = GetTextInputClient();
162 if (text_input_client)
163 text_input_client->SetCompositionText(composition_text);
166 void InputMethodLinuxX11::OnPreeditEnd() {
167 TextInputClient* text_input_client = GetTextInputClient();
168 if (text_input_client && text_input_client->HasCompositionText())
169 text_input_client->ClearCompositionText();
172 void InputMethodLinuxX11::OnPreeditStart() {}
174 // Overridden from InputMethodBase.
176 void InputMethodLinuxX11::OnDidChangeFocusedClient(
177 TextInputClient* focused_before,
178 TextInputClient* focused) {
179 input_method_context_->Reset();
180 input_method_context_->OnTextInputTypeChanged(
181 focused ? focused->GetTextInputType() : TEXT_INPUT_TYPE_NONE);
183 InputMethodBase::OnDidChangeFocusedClient(focused_before, focused);