OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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_auralinux.h" | 5 #include "ui/base/ime/input_method_auralinux.h" |
6 | 6 |
7 #include "base/environment.h" | 7 #include "base/environment.h" |
8 #include "ui/base/ime/linux/linux_input_method_context_factory.h" | 8 #include "ui/base/ime/linux/linux_input_method_context_factory.h" |
9 #include "ui/base/ime/text_input_client.h" | 9 #include "ui/base/ime/text_input_client.h" |
10 #include "ui/events/event.h" | 10 #include "ui/events/event.h" |
11 | 11 |
12 namespace ui { | 12 namespace ui { |
13 | 13 |
14 InputMethodAuraLinux::InputMethodAuraLinux( | 14 InputMethodAuraLinux::InputMethodAuraLinux( |
15 internal::InputMethodDelegate* delegate) { | 15 internal::InputMethodDelegate* delegate) |
| 16 : allowed_to_fire_vkey_process_key_(false), vkey_processkey_flags_(0) { |
16 SetDelegate(delegate); | 17 SetDelegate(delegate); |
17 } | 18 } |
18 | 19 |
19 InputMethodAuraLinux::~InputMethodAuraLinux() {} | 20 InputMethodAuraLinux::~InputMethodAuraLinux() {} |
20 | 21 |
21 // Overriden from InputMethod. | 22 // Overriden from InputMethod. |
22 | 23 |
23 void InputMethodAuraLinux::Init(bool focused) { | 24 void InputMethodAuraLinux::Init(bool focused) { |
24 CHECK(LinuxInputMethodContextFactory::instance()) | 25 CHECK(LinuxInputMethodContextFactory::instance()) |
25 << "This failure was likely caused because " | 26 << "This failure was likely caused because " |
(...skipping 21 matching lines...) Expand all Loading... |
47 } | 48 } |
48 | 49 |
49 bool InputMethodAuraLinux::DispatchKeyEvent(const ui::KeyEvent& event) { | 50 bool InputMethodAuraLinux::DispatchKeyEvent(const ui::KeyEvent& event) { |
50 DCHECK(event.type() == ET_KEY_PRESSED || event.type() == ET_KEY_RELEASED); | 51 DCHECK(event.type() == ET_KEY_PRESSED || event.type() == ET_KEY_RELEASED); |
51 DCHECK(system_toplevel_window_focused()); | 52 DCHECK(system_toplevel_window_focused()); |
52 | 53 |
53 // If no text input client, do nothing. | 54 // If no text input client, do nothing. |
54 if (!GetTextInputClient()) | 55 if (!GetTextInputClient()) |
55 return DispatchKeyEventPostIME(event); | 56 return DispatchKeyEventPostIME(event); |
56 | 57 |
57 // Let an IME handle the key event first. | 58 // Let an IME handle the key event first, and allow to fire a VKEY_PROCESSKEY |
58 if (input_method_context_->DispatchKeyEvent(event)) { | 59 // event for keydown events. Note that DOM Level 3 Events Sepc requires that |
59 if (event.type() == ET_KEY_PRESSED && | 60 // only keydown events fire keyCode=229 events and not for keyup events. |
60 (event.flags() & ui::EF_IME_FABRICATED_KEY) == 0) { | 61 if (event.type() == ET_KEY_PRESSED && |
61 const ui::KeyEvent fabricated_event(ET_KEY_PRESSED, | 62 (event.flags() & ui::EF_IME_FABRICATED_KEY) == 0) |
62 VKEY_PROCESSKEY, | 63 AllowToFireProcessKey(event); |
63 event.flags(), | 64 if (input_method_context_->DispatchKeyEvent(event)) |
64 false); // is_char | |
65 DispatchKeyEventPostIME(fabricated_event); | |
66 } | |
67 return true; | 65 return true; |
68 } | 66 StopFiringProcessKey(); |
69 | 67 |
70 // Otherwise, insert the character. | 68 // Otherwise, insert the character. |
71 const bool handled = DispatchKeyEventPostIME(event); | 69 const bool handled = DispatchKeyEventPostIME(event); |
72 if (event.type() == ET_KEY_PRESSED && GetTextInputClient()) { | 70 if (event.type() == ET_KEY_PRESSED && GetTextInputClient()) { |
73 const uint16 ch = event.GetCharacter(); | 71 const uint16 ch = event.GetCharacter(); |
74 if (ch) { | 72 if (ch) { |
75 GetTextInputClient()->InsertChar(ch, event.flags()); | 73 GetTextInputClient()->InsertChar(ch, event.flags()); |
76 return true; | 74 return true; |
77 } | 75 } |
78 } | 76 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 113 } |
116 | 114 |
117 bool InputMethodAuraLinux::IsCandidatePopupOpen() const { | 115 bool InputMethodAuraLinux::IsCandidatePopupOpen() const { |
118 // There seems no way to detect candidate windows or any popups. | 116 // There seems no way to detect candidate windows or any popups. |
119 return false; | 117 return false; |
120 } | 118 } |
121 | 119 |
122 // Overriden from ui::LinuxInputMethodContextDelegate | 120 // Overriden from ui::LinuxInputMethodContextDelegate |
123 | 121 |
124 void InputMethodAuraLinux::OnCommit(const base::string16& text) { | 122 void InputMethodAuraLinux::OnCommit(const base::string16& text) { |
| 123 MaybeFireProcessKey(); |
125 if (!IsTextInputTypeNone()) | 124 if (!IsTextInputTypeNone()) |
126 GetTextInputClient()->InsertText(text); | 125 GetTextInputClient()->InsertText(text); |
127 } | 126 } |
128 | 127 |
129 void InputMethodAuraLinux::OnPreeditChanged( | 128 void InputMethodAuraLinux::OnPreeditChanged( |
130 const CompositionText& composition_text) { | 129 const CompositionText& composition_text) { |
| 130 MaybeFireProcessKey(); |
131 TextInputClient* text_input_client = GetTextInputClient(); | 131 TextInputClient* text_input_client = GetTextInputClient(); |
132 if (text_input_client) | 132 if (text_input_client) |
133 text_input_client->SetCompositionText(composition_text); | 133 text_input_client->SetCompositionText(composition_text); |
134 } | 134 } |
135 | 135 |
136 void InputMethodAuraLinux::OnPreeditEnd() { | 136 void InputMethodAuraLinux::OnPreeditEnd() { |
| 137 MaybeFireProcessKey(); |
137 TextInputClient* text_input_client = GetTextInputClient(); | 138 TextInputClient* text_input_client = GetTextInputClient(); |
138 if (text_input_client && text_input_client->HasCompositionText()) | 139 if (text_input_client && text_input_client->HasCompositionText()) |
139 text_input_client->ClearCompositionText(); | 140 text_input_client->ClearCompositionText(); |
140 } | 141 } |
141 | 142 |
142 void InputMethodAuraLinux::OnPreeditStart() {} | 143 void InputMethodAuraLinux::OnPreeditStart() { |
| 144 MaybeFireProcessKey(); |
| 145 } |
143 | 146 |
144 // Overridden from InputMethodBase. | 147 // Overridden from InputMethodBase. |
145 | 148 |
146 void InputMethodAuraLinux::OnDidChangeFocusedClient( | 149 void InputMethodAuraLinux::OnDidChangeFocusedClient( |
147 TextInputClient* focused_before, | 150 TextInputClient* focused_before, |
148 TextInputClient* focused) { | 151 TextInputClient* focused) { |
149 input_method_context_->Reset(); | 152 input_method_context_->Reset(); |
150 input_method_context_->OnTextInputTypeChanged( | 153 input_method_context_->OnTextInputTypeChanged( |
151 focused ? focused->GetTextInputType() : TEXT_INPUT_TYPE_NONE); | 154 focused ? focused->GetTextInputType() : TEXT_INPUT_TYPE_NONE); |
152 | 155 |
153 InputMethodBase::OnDidChangeFocusedClient(focused_before, focused); | 156 InputMethodBase::OnDidChangeFocusedClient(focused_before, focused); |
154 } | 157 } |
155 | 158 |
| 159 // Helper functions to support VKEY_PROCESSKEY. |
| 160 |
| 161 void InputMethodAuraLinux::AllowToFireProcessKey(const ui::KeyEvent& event) { |
| 162 allowed_to_fire_vkey_process_key_ = true; |
| 163 vkey_processkey_flags_ = event.flags(); |
| 164 } |
| 165 |
| 166 void InputMethodAuraLinux::MaybeFireProcessKey() { |
| 167 if (!allowed_to_fire_vkey_process_key_) |
| 168 return; |
| 169 |
| 170 const ui::KeyEvent fabricated_event(ET_KEY_PRESSED, |
| 171 VKEY_PROCESSKEY, |
| 172 vkey_processkey_flags_, |
| 173 false); // is_char |
| 174 DispatchKeyEventPostIME(fabricated_event); |
| 175 StopFiringProcessKey(); |
| 176 } |
| 177 |
| 178 void InputMethodAuraLinux::StopFiringProcessKey() { |
| 179 allowed_to_fire_vkey_process_key_ = false; |
| 180 vkey_processkey_flags_ = 0; |
| 181 } |
| 182 |
156 } // namespace ui | 183 } // namespace ui |
OLD | NEW |