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 "content/public/browser/render_widget_host.h" | 9 #include "content/public/browser/render_widget_host.h" |
10 #include "content/public/browser/render_widget_host_iterator.h" | 10 #include "content/public/browser/render_widget_host_iterator.h" |
11 #include "content/public/browser/render_widget_host_view.h" | 11 #include "content/public/browser/render_widget_host_view.h" |
12 #include "ui/aura/window.h" | 12 #include "ui/aura/window.h" |
13 #include "ui/aura/window_delegate.h" | 13 #include "ui/aura/window_delegate.h" |
14 #include "ui/aura/window_observer.h" | |
14 #include "ui/base/cursor/cursor.h" | 15 #include "ui/base/cursor/cursor.h" |
15 #include "ui/base/hit_test.h" | 16 #include "ui/base/hit_test.h" |
16 #include "ui/base/ime/input_method.h" | 17 #include "ui/base/ime/input_method.h" |
17 #include "ui/base/ime/text_input_client.h" | 18 #include "ui/base/ime/text_input_client.h" |
18 #include "ui/compositor/layer_animation_observer.h" | 19 #include "ui/compositor/layer_animation_observer.h" |
19 #include "ui/compositor/scoped_layer_animation_settings.h" | 20 #include "ui/compositor/scoped_layer_animation_settings.h" |
20 #include "ui/gfx/path.h" | 21 #include "ui/gfx/path.h" |
21 #include "ui/gfx/rect.h" | 22 #include "ui/gfx/rect.h" |
22 #include "ui/gfx/skia_util.h" | 23 #include "ui/gfx/skia_util.h" |
23 #include "ui/keyboard/keyboard_controller_observer.h" | 24 #include "ui/keyboard/keyboard_controller_observer.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 return; | 183 return; |
183 animator_->RemoveObserver(this); | 184 animator_->RemoveObserver(this); |
184 callback_.Run(); | 185 callback_.Run(); |
185 } | 186 } |
186 | 187 |
187 void CallbackAnimationObserver::OnLayerAnimationAborted( | 188 void CallbackAnimationObserver::OnLayerAnimationAborted( |
188 ui::LayerAnimationSequence* seq) { | 189 ui::LayerAnimationSequence* seq) { |
189 animator_->RemoveObserver(this); | 190 animator_->RemoveObserver(this); |
190 } | 191 } |
191 | 192 |
193 class WindowBoundsChangeObserver : public aura::WindowObserver { | |
194 public: | |
195 virtual void OnWindowBoundsChanged(aura::Window* window, | |
196 const gfx::Rect& old_bounds, | |
197 const gfx::Rect& new_bounds) OVERRIDE; | |
198 }; | |
199 | |
200 void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, | |
201 const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { | |
202 KeyboardController* controller = KeyboardController::GetInstance(); | |
203 if (controller) | |
204 controller->UpdateWindowInsets(window); | |
205 } | |
206 | |
192 // static | 207 // static |
193 KeyboardController* KeyboardController::instance_ = NULL; | 208 KeyboardController* KeyboardController::instance_ = NULL; |
194 | 209 |
195 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 210 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
196 : proxy_(proxy), | 211 : proxy_(proxy), |
197 input_method_(NULL), | 212 input_method_(NULL), |
198 keyboard_visible_(false), | 213 keyboard_visible_(false), |
199 lock_keyboard_(false), | 214 lock_keyboard_(false), |
200 type_(ui::TEXT_INPUT_TYPE_NONE), | 215 type_(ui::TEXT_INPUT_TYPE_NONE), |
201 weak_factory_(this) { | 216 weak_factory_(this) { |
202 CHECK(proxy); | 217 CHECK(proxy); |
203 input_method_ = proxy_->GetInputMethod(); | 218 input_method_ = proxy_->GetInputMethod(); |
204 input_method_->AddObserver(this); | 219 input_method_->AddObserver(this); |
220 window_bounds_observer_.reset(new WindowBoundsChangeObserver()); | |
205 } | 221 } |
206 | 222 |
207 KeyboardController::~KeyboardController() { | 223 KeyboardController::~KeyboardController() { |
208 if (container_) | 224 if (container_) |
209 container_->RemoveObserver(this); | 225 container_->RemoveObserver(this); |
210 if (input_method_) | 226 if (input_method_) |
211 input_method_->RemoveObserver(this); | 227 input_method_->RemoveObserver(this); |
212 ResetWindowInsets(); | 228 ResetWindowInsets(); |
213 } | 229 } |
214 | 230 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 if (window != keyboard_window && | 280 if (window != keyboard_window && |
265 window->GetRootWindow() == root_window) { | 281 window->GetRootWindow() == root_window) { |
266 gfx::Rect window_bounds = window->GetBoundsInScreen(); | 282 gfx::Rect window_bounds = window->GetBoundsInScreen(); |
267 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | 283 gfx::Rect intersect = gfx::IntersectRects(window_bounds, |
268 new_bounds); | 284 new_bounds); |
269 int overlap = intersect.height(); | 285 int overlap = intersect.height(); |
270 if (overlap > 0 && overlap < window_bounds.height()) | 286 if (overlap > 0 && overlap < window_bounds.height()) |
271 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | 287 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
272 else | 288 else |
273 view->SetInsets(gfx::Insets(0, 0, 0, 0)); | 289 view->SetInsets(gfx::Insets(0, 0, 0, 0)); |
274 // TODO(kevers): Add window observer to native window to update | 290 AddBoundsChangedObserver(window); |
275 // insets on a window move or resize. | |
276 } | 291 } |
277 } | 292 } |
278 } | 293 } |
279 } else { | 294 } else { |
280 ResetWindowInsets(); | 295 ResetWindowInsets(); |
281 } | 296 } |
282 } | 297 } |
283 } | 298 } |
284 | 299 |
285 void KeyboardController::HideKeyboard(HideReason reason) { | 300 void KeyboardController::HideKeyboard(HideReason reason) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 void KeyboardController::OnInputMethodDestroyed( | 392 void KeyboardController::OnInputMethodDestroyed( |
378 const ui::InputMethod* input_method) { | 393 const ui::InputMethod* input_method) { |
379 DCHECK_EQ(input_method_, input_method); | 394 DCHECK_EQ(input_method_, input_method); |
380 input_method_ = NULL; | 395 input_method_ = NULL; |
381 } | 396 } |
382 | 397 |
383 void KeyboardController::OnShowImeIfNeeded() { | 398 void KeyboardController::OnShowImeIfNeeded() { |
384 ShowKeyboardInternal(); | 399 ShowKeyboardInternal(); |
385 } | 400 } |
386 | 401 |
402 void KeyboardController::UpdateWindowInsets(aura::Window* window) { | |
403 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | |
404 if (window == keyboard_window) | |
405 return; | |
406 | |
407 bool enableInsets = (keyboard_window->GetRootWindow() == | |
408 window->GetRootWindow()) && keyboard::IsKeyboardOverscrollEnabled() && | |
409 proxy_->HasKeyboardWindow() && proxy_->GetKeyboardWindow()->IsVisible(); | |
bshe
2014/07/04 13:03:57
nit: Do you need HasKeyboardWindow? It should alwa
kevers
2014/07/18 14:06:23
Done.
| |
410 | |
411 scoped_ptr<content::RenderWidgetHostIterator> widgets( | |
412 content::RenderWidgetHost::GetRenderWidgetHosts()); | |
413 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | |
414 content::RenderWidgetHostView* view = widget->GetView(); | |
415 if (view && window->Contains(view->GetNativeView())) { | |
416 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); | |
417 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | |
418 proxy_->GetKeyboardWindow()->bounds()); | |
419 int overlap = enableInsets ? intersect.height() : 0; | |
420 if (overlap > 0 && overlap < window_bounds.height()) | |
421 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | |
422 else | |
423 view->SetInsets(gfx::Insets(0, 0, 0, 0)); | |
bshe
2014/07/04 13:03:57
nit: probably gfx::Insets()?
kevers
2014/07/18 14:06:23
Done.
| |
424 return; | |
425 } | |
426 } | |
427 } | |
428 | |
387 void KeyboardController::ShowKeyboardInternal() { | 429 void KeyboardController::ShowKeyboardInternal() { |
388 if (!container_.get()) | 430 if (!container_.get()) |
389 return; | 431 return; |
390 | 432 |
391 if (container_->children().empty()) { | 433 if (container_->children().empty()) { |
392 keyboard::MarkKeyboardLoadStarted(); | 434 keyboard::MarkKeyboardLoadStarted(); |
393 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | 435 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
394 keyboard->Show(); | 436 keyboard->Show(); |
395 container_->AddChild(keyboard); | 437 container_->AddChild(keyboard); |
396 keyboard->set_owned_by_parent(false); | 438 keyboard->set_owned_by_parent(false); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 container_->layer()->SetOpacity(1.0); | 495 container_->layer()->SetOpacity(1.0); |
454 } | 496 } |
455 } | 497 } |
456 | 498 |
457 void KeyboardController::ResetWindowInsets() { | 499 void KeyboardController::ResetWindowInsets() { |
458 const gfx::Insets insets; | 500 const gfx::Insets insets; |
459 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 501 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
460 content::RenderWidgetHost::GetRenderWidgetHosts()); | 502 content::RenderWidgetHost::GetRenderWidgetHosts()); |
461 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 503 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
462 content::RenderWidgetHostView* view = widget->GetView(); | 504 content::RenderWidgetHostView* view = widget->GetView(); |
463 if (view) | 505 if (view) { |
464 view->SetInsets(insets); | 506 view->SetInsets(insets); |
507 aura::Window *window = view->GetNativeView(); | |
508 RemoveBoundsChangedObserver(window); | |
509 } | |
465 } | 510 } |
466 } | 511 } |
467 | 512 |
468 bool KeyboardController::WillHideKeyboard() const { | 513 bool KeyboardController::WillHideKeyboard() const { |
469 return weak_factory_.HasWeakPtrs(); | 514 return weak_factory_.HasWeakPtrs(); |
470 } | 515 } |
471 | 516 |
472 void KeyboardController::ShowAnimationFinished() { | 517 void KeyboardController::ShowAnimationFinished() { |
473 // Notify observers after animation finished to prevent reveal desktop | 518 // Notify observers after animation finished to prevent reveal desktop |
474 // background during animation. | 519 // background during animation. |
475 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); | 520 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); |
476 proxy_->EnsureCaretInWorkArea(); | 521 proxy_->EnsureCaretInWorkArea(); |
477 } | 522 } |
478 | 523 |
479 void KeyboardController::HideAnimationFinished() { | 524 void KeyboardController::HideAnimationFinished() { |
480 proxy_->HideKeyboardContainer(container_.get()); | 525 proxy_->HideKeyboardContainer(container_.get()); |
481 } | 526 } |
482 | 527 |
528 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { | |
529 while(window->parent() && window->parent()->id() < 0) { | |
bshe
2014/07/04 13:03:57
nit: do you mind to add a comment on why do we che
kevers
2014/07/18 14:06:23
Done.
| |
530 window = window->parent(); | |
531 } | |
532 if (!window->HasObserver(window_bounds_observer_.get())) | |
533 window->AddObserver(window_bounds_observer_.get()); | |
534 } | |
535 | |
536 void KeyboardController::RemoveBoundsChangedObserver(aura::Window* window) { | |
537 while(window->parent() && window->parent()->id() < 0) { | |
538 window = window->parent(); | |
539 } | |
540 if (window && window->HasObserver(window_bounds_observer_.get())) | |
bshe
2014/07/04 13:03:57
nit: you probably dont need to check if window is
kevers
2014/07/18 14:06:23
Done.
| |
541 window->RemoveObserver(window_bounds_observer_.get()); | |
542 } | |
543 | |
483 } // namespace keyboard | 544 } // namespace keyboard |
OLD | NEW |