OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/keyboard/keyboard_controller.h" | 5 #include "ui/keyboard/keyboard_controller.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "ui/aura/layout_manager.h" | 9 #include "ui/aura/layout_manager.h" |
10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 input_method_(NULL), | 171 input_method_(NULL), |
172 keyboard_visible_(false), | 172 keyboard_visible_(false), |
173 lock_keyboard_(false), | 173 lock_keyboard_(false), |
174 weak_factory_(this) { | 174 weak_factory_(this) { |
175 CHECK(proxy); | 175 CHECK(proxy); |
176 input_method_ = proxy_->GetInputMethod(); | 176 input_method_ = proxy_->GetInputMethod(); |
177 input_method_->AddObserver(this); | 177 input_method_->AddObserver(this); |
178 } | 178 } |
179 | 179 |
180 KeyboardController::~KeyboardController() { | 180 KeyboardController::~KeyboardController() { |
181 if (container_) { | 181 if (container_) |
182 container_->RemoveObserver(this); | 182 container_->RemoveObserver(this); |
183 // Remove the keyboard window from the children because the keyboard window | |
184 // is owned by proxy and it should be destroyed by proxy. | |
185 if (container_->Contains(proxy_->GetKeyboardWindow())) | |
186 container_->RemoveChild(proxy_->GetKeyboardWindow()); | |
187 } | |
188 if (input_method_) | 183 if (input_method_) |
189 input_method_->RemoveObserver(this); | 184 input_method_->RemoveObserver(this); |
190 } | 185 } |
191 | 186 |
192 aura::Window* KeyboardController::GetContainerWindow() { | 187 aura::Window* KeyboardController::GetContainerWindow() { |
193 if (!container_.get()) { | 188 if (!container_.get()) { |
194 container_.reset(new aura::Window( | 189 container_.reset(new aura::Window( |
195 new KeyboardWindowDelegate(proxy_.get()))); | 190 new KeyboardWindowDelegate(proxy_.get()))); |
196 container_->set_event_targeter(scoped_ptr<ui::EventTargeter>( | 191 container_->set_event_targeter(scoped_ptr<ui::EventTargeter>( |
197 new KeyboardContainerTargeter(container_.get(), proxy_.get()))); | 192 new KeyboardContainerTargeter(container_.get(), proxy_.get()))); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 | 237 |
243 void KeyboardController::SetOverrideContentUrl(const GURL& url) { | 238 void KeyboardController::SetOverrideContentUrl(const GURL& url) { |
244 proxy_->SetOverrideContentUrl(url); | 239 proxy_->SetOverrideContentUrl(url); |
245 } | 240 } |
246 | 241 |
247 void KeyboardController::OnTextInputStateChanged( | 242 void KeyboardController::OnTextInputStateChanged( |
248 const ui::TextInputClient* client) { | 243 const ui::TextInputClient* client) { |
249 if (!container_.get()) | 244 if (!container_.get()) |
250 return; | 245 return; |
251 | 246 |
252 bool was_showing = keyboard_visible_; | 247 if (IsKeyboardUsabilityExperimentEnabled()) { |
253 bool should_show = was_showing; | 248 OnShowImeIfNeeded(); |
| 249 return; |
| 250 } |
| 251 |
254 ui::TextInputType type = | 252 ui::TextInputType type = |
255 client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE; | 253 client ? client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE; |
256 if (type == ui::TEXT_INPUT_TYPE_NONE && | 254 if (type == ui::TEXT_INPUT_TYPE_NONE && !lock_keyboard_) { |
257 !IsKeyboardUsabilityExperimentEnabled() && | 255 if (keyboard_visible_) { |
258 !lock_keyboard_) { | |
259 should_show = false; | |
260 } else { | |
261 if (container_->children().empty()) { | |
262 keyboard::MarkKeyboardLoadStarted(); | |
263 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | |
264 keyboard->Show(); | |
265 container_->AddChild(keyboard); | |
266 } | |
267 if (type != ui::TEXT_INPUT_TYPE_NONE) | |
268 proxy_->SetUpdateInputType(type); | |
269 container_->parent()->StackChildAtTop(container_.get()); | |
270 should_show = true; | |
271 } | |
272 | |
273 if (was_showing != should_show) { | |
274 if (should_show) { | |
275 keyboard_visible_ = true; | |
276 | |
277 // If the controller is in the process of hiding the keyboard, do not log | |
278 // the stat here since the keyboard will not actually be shown. | |
279 if (!WillHideKeyboard()) | |
280 keyboard::LogKeyboardControlEvent(keyboard::KEYBOARD_CONTROL_SHOW); | |
281 | |
282 weak_factory_.InvalidateWeakPtrs(); | |
283 // If |container_| has hide animation, its visibility is set to false when | |
284 // hide animation finished. So even if the container is visible at this | |
285 // point, it may in the process of hiding. We still need to show keyboard | |
286 // container in this case. | |
287 if (container_->IsVisible() && | |
288 !container_->layer()->GetAnimator()->is_animating()) { | |
289 return; | |
290 } | |
291 | |
292 NotifyKeyboardBoundsChanging(container_->children()[0]->bounds()); | |
293 | |
294 proxy_->ShowKeyboardContainer(container_.get()); | |
295 } else { | |
296 // Set the visibility state here so that any queries for visibility | 256 // Set the visibility state here so that any queries for visibility |
297 // before the timer fires returns the correct future value. | 257 // before the timer fires returns the correct future value. |
298 keyboard_visible_ = false; | 258 keyboard_visible_ = false; |
299 base::MessageLoop::current()->PostDelayedTask( | 259 base::MessageLoop::current()->PostDelayedTask( |
300 FROM_HERE, | 260 FROM_HERE, |
301 base::Bind(&KeyboardController::HideKeyboard, | 261 base::Bind(&KeyboardController::HideKeyboard, |
302 weak_factory_.GetWeakPtr(), HIDE_REASON_AUTOMATIC), | 262 weak_factory_.GetWeakPtr(), HIDE_REASON_AUTOMATIC), |
303 base::TimeDelta::FromMilliseconds(kHideKeyboardDelayMs)); | 263 base::TimeDelta::FromMilliseconds(kHideKeyboardDelayMs)); |
304 } | 264 } |
| 265 } else { |
| 266 // Abort a pending keyboard hide. |
| 267 if (WillHideKeyboard()) { |
| 268 weak_factory_.InvalidateWeakPtrs(); |
| 269 keyboard_visible_ = true; |
| 270 } |
| 271 proxy_->SetUpdateInputType(type); |
| 272 // Do not explicitly show the Virtual keyboard unless it is in the process |
| 273 // of hiding. Instead, the virtual keyboard is shown in response to a user |
| 274 // gesture (mouse or touch) that is received while an element has input |
| 275 // focus. Showing the keyboard requires an explicit call to |
| 276 // OnShowImeIfNeeded. |
305 } | 277 } |
306 // TODO(bryeung): whenever the TextInputClient changes we need to notify the | 278 // TODO(bryeung): whenever the TextInputClient changes we need to notify the |
307 // keyboard (with the TextInputType) so that it can reset it's state (e.g. | 279 // keyboard (with the TextInputType) so that it can reset it's state (e.g. |
308 // abandon compositions in progress) | 280 // abandon compositions in progress) |
309 } | 281 } |
310 | 282 |
311 void KeyboardController::OnInputMethodDestroyed( | 283 void KeyboardController::OnInputMethodDestroyed( |
312 const ui::InputMethod* input_method) { | 284 const ui::InputMethod* input_method) { |
313 DCHECK_EQ(input_method_, input_method); | 285 DCHECK_EQ(input_method_, input_method); |
314 input_method_ = NULL; | 286 input_method_ = NULL; |
315 } | 287 } |
316 | 288 |
| 289 void KeyboardController::OnShowImeIfNeeded() { |
| 290 if (!container_.get()) |
| 291 return; |
| 292 |
| 293 if (container_->children().empty()) { |
| 294 keyboard::MarkKeyboardLoadStarted(); |
| 295 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
| 296 keyboard->Show(); |
| 297 container_->AddChild(keyboard); |
| 298 keyboard->set_owned_by_parent(false); |
| 299 } |
| 300 if (keyboard_visible_) |
| 301 return; |
| 302 |
| 303 keyboard_visible_ = true; |
| 304 |
| 305 // If the controller is in the process of hiding the keyboard, do not log |
| 306 // the stat here since the keyboard will not actually be shown. |
| 307 if (!WillHideKeyboard()) |
| 308 keyboard::LogKeyboardControlEvent(keyboard::KEYBOARD_CONTROL_SHOW); |
| 309 |
| 310 weak_factory_.InvalidateWeakPtrs(); |
| 311 |
| 312 // If |container_| has hide animation, its visibility is set to false when |
| 313 // hide animation finished. So even if the container is visible at this |
| 314 // point, it may in the process of hiding. We still need to show keyboard |
| 315 // container in this case. |
| 316 if (container_->IsVisible() && |
| 317 !container_->layer()->GetAnimator()->is_animating()) { |
| 318 return; |
| 319 } |
| 320 |
| 321 NotifyKeyboardBoundsChanging(container_->children()[0]->bounds()); |
| 322 |
| 323 proxy_->ShowKeyboardContainer(container_.get()); |
| 324 } |
| 325 |
317 bool KeyboardController::WillHideKeyboard() const { | 326 bool KeyboardController::WillHideKeyboard() const { |
318 return weak_factory_.HasWeakPtrs(); | 327 return weak_factory_.HasWeakPtrs(); |
319 } | 328 } |
320 | 329 |
321 } // namespace keyboard | 330 } // namespace keyboard |
OLD | NEW |