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_auralinux.h"
7 #include "base/environment.h"
8 #include "ui/base/ime/linux/linux_input_method_context_factory.h"
9 #include "ui/base/ime/text_input_client.h"
10 #include "ui/events/event.h"
14 InputMethodAuraLinux::InputMethodAuraLinux(
15 internal::InputMethodDelegate
* delegate
)
16 : allowed_to_fire_vkey_process_key_(false), vkey_processkey_flags_(0) {
17 SetDelegate(delegate
);
20 InputMethodAuraLinux::~InputMethodAuraLinux() {}
22 // Overriden from InputMethod.
24 void InputMethodAuraLinux::Init(bool focused
) {
25 CHECK(LinuxInputMethodContextFactory::instance())
26 << "This failure was likely caused because "
27 << "ui::InitializeInputMethod(ForTesting) was not called "
28 << "before instantiating this class.";
29 input_method_context_
=
30 LinuxInputMethodContextFactory::instance()->CreateInputMethodContext(
32 CHECK(input_method_context_
.get());
34 InputMethodBase::Init(focused
);
37 input_method_context_
->OnTextInputTypeChanged(
38 GetTextInputClient() ?
39 GetTextInputClient()->GetTextInputType() :
40 TEXT_INPUT_TYPE_TEXT
);
44 bool InputMethodAuraLinux::OnUntranslatedIMEMessage(
45 const base::NativeEvent
& event
,
46 NativeEventResult
* result
) {
50 bool InputMethodAuraLinux::DispatchKeyEvent(const ui::KeyEvent
& 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(event
);
58 // Let an IME handle the key event first, and allow to fire a VKEY_PROCESSKEY
59 // event for keydown events. Note that DOM Level 3 Events Sepc requires that
60 // only keydown events fire keyCode=229 events and not for keyup events.
61 if (event
.type() == ET_KEY_PRESSED
&&
62 (event
.flags() & ui::EF_IME_FABRICATED_KEY
) == 0)
63 AllowToFireProcessKey(event
);
64 if (input_method_context_
->DispatchKeyEvent(event
))
66 StopFiringProcessKey();
68 // Otherwise, insert the character.
69 const bool handled
= DispatchKeyEventPostIME(event
);
70 if (event
.type() == ET_KEY_PRESSED
&& GetTextInputClient()) {
71 const uint16 ch
= event
.GetCharacter();
73 GetTextInputClient()->InsertChar(ch
, event
.flags());
80 void InputMethodAuraLinux::OnTextInputTypeChanged(
81 const TextInputClient
* client
) {
82 if (!IsTextInputClientFocused(client
))
84 input_method_context_
->Reset();
85 // TODO(yoichio): Support inputmode HTML attribute.
86 input_method_context_
->OnTextInputTypeChanged(client
->GetTextInputType());
89 void InputMethodAuraLinux::OnCaretBoundsChanged(const TextInputClient
* client
) {
90 if (!IsTextInputClientFocused(client
))
92 input_method_context_
->OnCaretBoundsChanged(
93 GetTextInputClient()->GetCaretBounds());
96 void InputMethodAuraLinux::CancelComposition(const TextInputClient
* client
) {
97 if (!IsTextInputClientFocused(client
))
99 input_method_context_
->Reset();
100 input_method_context_
->OnTextInputTypeChanged(client
->GetTextInputType());
103 void InputMethodAuraLinux::OnInputLocaleChanged() {
106 std::string
InputMethodAuraLinux::GetInputLocale() {
110 bool InputMethodAuraLinux::IsActive() {
111 // InputMethodAuraLinux is always ready and up.
115 bool InputMethodAuraLinux::IsCandidatePopupOpen() const {
116 // There seems no way to detect candidate windows or any popups.
120 // Overriden from ui::LinuxInputMethodContextDelegate
122 void InputMethodAuraLinux::OnCommit(const base::string16
& text
) {
123 MaybeFireProcessKey();
124 if (!IsTextInputTypeNone())
125 GetTextInputClient()->InsertText(text
);
128 void InputMethodAuraLinux::OnPreeditChanged(
129 const CompositionText
& composition_text
) {
130 MaybeFireProcessKey();
131 TextInputClient
* text_input_client
= GetTextInputClient();
132 if (text_input_client
)
133 text_input_client
->SetCompositionText(composition_text
);
136 void InputMethodAuraLinux::OnPreeditEnd() {
137 MaybeFireProcessKey();
138 TextInputClient
* text_input_client
= GetTextInputClient();
139 if (text_input_client
&& text_input_client
->HasCompositionText())
140 text_input_client
->ClearCompositionText();
143 void InputMethodAuraLinux::OnPreeditStart() {
144 MaybeFireProcessKey();
147 // Overridden from InputMethodBase.
149 void InputMethodAuraLinux::OnDidChangeFocusedClient(
150 TextInputClient
* focused_before
,
151 TextInputClient
* focused
) {
152 input_method_context_
->Reset();
153 input_method_context_
->OnTextInputTypeChanged(
154 focused
? focused
->GetTextInputType() : TEXT_INPUT_TYPE_NONE
);
156 InputMethodBase::OnDidChangeFocusedClient(focused_before
, focused
);
159 // Helper functions to support VKEY_PROCESSKEY.
161 void InputMethodAuraLinux::AllowToFireProcessKey(const ui::KeyEvent
& event
) {
162 allowed_to_fire_vkey_process_key_
= true;
163 vkey_processkey_flags_
= event
.flags();
166 void InputMethodAuraLinux::MaybeFireProcessKey() {
167 if (!allowed_to_fire_vkey_process_key_
)
170 const ui::KeyEvent
fabricated_event(ET_KEY_PRESSED
,
172 vkey_processkey_flags_
);
173 DispatchKeyEventPostIME(fabricated_event
);
174 StopFiringProcessKey();
177 void InputMethodAuraLinux::StopFiringProcessKey() {
178 allowed_to_fire_vkey_process_key_
= false;
179 vkey_processkey_flags_
= 0;