| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 command.AppendArg("1"); | 135 command.AppendArg("1"); |
| 135 else | 136 else |
| 136 command.AppendArg("0"); | 137 command.AppendArg("0"); |
| 137 VLOG(1) << "Running " << command.GetCommandLineString(); | 138 VLOG(1) << "Running " << command.GetCommandLineString(); |
| 138 base::LaunchOptions options; | 139 base::LaunchOptions options; |
| 139 options.wait = true; | 140 options.wait = true; |
| 140 base::LaunchProcess(command, options, NULL); | 141 base::LaunchProcess(command, options, NULL); |
| 141 #endif | 142 #endif |
| 142 } | 143 } |
| 143 | 144 |
| 145 aura::Window *GetFrameWindow(aura::Window *window) { |
| 146 // Each container window has a non-negative id. Stop traversing at the child |
| 147 // of a container window. |
| 148 if (!window) |
| 149 return NULL; |
| 150 while(window->parent() && window->parent()->id() < 0) { |
| 151 window = window->parent(); |
| 152 } |
| 153 return window; |
| 154 } |
| 155 |
| 144 } // namespace | 156 } // namespace |
| 145 | 157 |
| 146 namespace keyboard { | 158 namespace keyboard { |
| 147 | 159 |
| 148 // Observer for both keyboard show and hide animations. It should be owned by | 160 // Observer for both keyboard show and hide animations. It should be owned by |
| 149 // KeyboardController. | 161 // KeyboardController. |
| 150 class CallbackAnimationObserver : public ui::LayerAnimationObserver { | 162 class CallbackAnimationObserver : public ui::LayerAnimationObserver { |
| 151 public: | 163 public: |
| 152 CallbackAnimationObserver(ui::LayerAnimator* animator, | 164 CallbackAnimationObserver(ui::LayerAnimator* animator, |
| 153 base::Callback<void(void)> callback); | 165 base::Callback<void(void)> callback); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 182 return; | 194 return; |
| 183 animator_->RemoveObserver(this); | 195 animator_->RemoveObserver(this); |
| 184 callback_.Run(); | 196 callback_.Run(); |
| 185 } | 197 } |
| 186 | 198 |
| 187 void CallbackAnimationObserver::OnLayerAnimationAborted( | 199 void CallbackAnimationObserver::OnLayerAnimationAborted( |
| 188 ui::LayerAnimationSequence* seq) { | 200 ui::LayerAnimationSequence* seq) { |
| 189 animator_->RemoveObserver(this); | 201 animator_->RemoveObserver(this); |
| 190 } | 202 } |
| 191 | 203 |
| 204 class WindowBoundsChangeObserver : public aura::WindowObserver { |
| 205 public: |
| 206 virtual void OnWindowBoundsChanged(aura::Window* window, |
| 207 const gfx::Rect& old_bounds, |
| 208 const gfx::Rect& new_bounds) OVERRIDE; |
| 209 }; |
| 210 |
| 211 void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, |
| 212 const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { |
| 213 KeyboardController* controller = KeyboardController::GetInstance(); |
| 214 if (controller) |
| 215 controller->UpdateWindowInsets(window); |
| 216 } |
| 217 |
| 192 // static | 218 // static |
| 193 KeyboardController* KeyboardController::instance_ = NULL; | 219 KeyboardController* KeyboardController::instance_ = NULL; |
| 194 | 220 |
| 195 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 221 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
| 196 : proxy_(proxy), | 222 : proxy_(proxy), |
| 197 input_method_(NULL), | 223 input_method_(NULL), |
| 198 keyboard_visible_(false), | 224 keyboard_visible_(false), |
| 199 lock_keyboard_(false), | 225 lock_keyboard_(false), |
| 200 type_(ui::TEXT_INPUT_TYPE_NONE), | 226 type_(ui::TEXT_INPUT_TYPE_NONE), |
| 201 weak_factory_(this) { | 227 weak_factory_(this) { |
| 202 CHECK(proxy); | 228 CHECK(proxy); |
| 203 input_method_ = proxy_->GetInputMethod(); | 229 input_method_ = proxy_->GetInputMethod(); |
| 204 input_method_->AddObserver(this); | 230 input_method_->AddObserver(this); |
| 231 window_bounds_observer_.reset(new WindowBoundsChangeObserver()); |
| 205 } | 232 } |
| 206 | 233 |
| 207 KeyboardController::~KeyboardController() { | 234 KeyboardController::~KeyboardController() { |
| 208 if (container_) | 235 if (container_) |
| 209 container_->RemoveObserver(this); | 236 container_->RemoveObserver(this); |
| 210 if (input_method_) | 237 if (input_method_) |
| 211 input_method_->RemoveObserver(this); | 238 input_method_->RemoveObserver(this); |
| 212 ResetWindowInsets(); | 239 ResetWindowInsets(); |
| 213 } | 240 } |
| 214 | 241 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 aura::Window *window = view->GetNativeView(); | 290 aura::Window *window = view->GetNativeView(); |
| 264 if (window != keyboard_window && | 291 if (window != keyboard_window && |
| 265 window->GetRootWindow() == root_window) { | 292 window->GetRootWindow() == root_window) { |
| 266 gfx::Rect window_bounds = window->GetBoundsInScreen(); | 293 gfx::Rect window_bounds = window->GetBoundsInScreen(); |
| 267 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | 294 gfx::Rect intersect = gfx::IntersectRects(window_bounds, |
| 268 new_bounds); | 295 new_bounds); |
| 269 int overlap = intersect.height(); | 296 int overlap = intersect.height(); |
| 270 if (overlap > 0 && overlap < window_bounds.height()) | 297 if (overlap > 0 && overlap < window_bounds.height()) |
| 271 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | 298 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
| 272 else | 299 else |
| 273 view->SetInsets(gfx::Insets(0, 0, 0, 0)); | 300 view->SetInsets(gfx::Insets()); |
| 274 // TODO(kevers): Add window observer to native window to update | 301 AddBoundsChangedObserver(window); |
| 275 // insets on a window move or resize. | |
| 276 } | 302 } |
| 277 } | 303 } |
| 278 } | 304 } |
| 279 } else { | 305 } else { |
| 280 ResetWindowInsets(); | 306 ResetWindowInsets(); |
| 281 } | 307 } |
| 282 } | 308 } |
| 283 } | 309 } |
| 284 | 310 |
| 285 void KeyboardController::HideKeyboard(HideReason reason) { | 311 void KeyboardController::HideKeyboard(HideReason reason) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 void KeyboardController::OnInputMethodDestroyed( | 403 void KeyboardController::OnInputMethodDestroyed( |
| 378 const ui::InputMethod* input_method) { | 404 const ui::InputMethod* input_method) { |
| 379 DCHECK_EQ(input_method_, input_method); | 405 DCHECK_EQ(input_method_, input_method); |
| 380 input_method_ = NULL; | 406 input_method_ = NULL; |
| 381 } | 407 } |
| 382 | 408 |
| 383 void KeyboardController::OnShowImeIfNeeded() { | 409 void KeyboardController::OnShowImeIfNeeded() { |
| 384 ShowKeyboardInternal(); | 410 ShowKeyboardInternal(); |
| 385 } | 411 } |
| 386 | 412 |
| 413 void KeyboardController::UpdateWindowInsets(aura::Window* window) { |
| 414 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); |
| 415 if (window == keyboard_window) |
| 416 return; |
| 417 |
| 418 bool enableInsets = (keyboard_window->GetRootWindow() == |
| 419 window->GetRootWindow()) && keyboard::IsKeyboardOverscrollEnabled() && |
| 420 proxy_->GetKeyboardWindow()->IsVisible(); |
| 421 |
| 422 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
| 423 content::RenderWidgetHost::GetRenderWidgetHosts()); |
| 424 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 425 content::RenderWidgetHostView* view = widget->GetView(); |
| 426 if (view && window->Contains(view->GetNativeView())) { |
| 427 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); |
| 428 gfx::Rect intersect = gfx::IntersectRects(window_bounds, |
| 429 proxy_->GetKeyboardWindow()->bounds()); |
| 430 int overlap = enableInsets ? intersect.height() : 0; |
| 431 if (overlap > 0 && overlap < window_bounds.height()) |
| 432 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
| 433 else |
| 434 view->SetInsets(gfx::Insets()); |
| 435 return; |
| 436 } |
| 437 } |
| 438 } |
| 439 |
| 387 void KeyboardController::ShowKeyboardInternal() { | 440 void KeyboardController::ShowKeyboardInternal() { |
| 388 if (!container_.get()) | 441 if (!container_.get()) |
| 389 return; | 442 return; |
| 390 | 443 |
| 391 if (container_->children().empty()) { | 444 if (container_->children().empty()) { |
| 392 keyboard::MarkKeyboardLoadStarted(); | 445 keyboard::MarkKeyboardLoadStarted(); |
| 393 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | 446 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
| 394 keyboard->Show(); | 447 keyboard->Show(); |
| 395 container_->AddChild(keyboard); | 448 container_->AddChild(keyboard); |
| 396 keyboard->set_owned_by_parent(false); | 449 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); | 506 container_->layer()->SetOpacity(1.0); |
| 454 } | 507 } |
| 455 } | 508 } |
| 456 | 509 |
| 457 void KeyboardController::ResetWindowInsets() { | 510 void KeyboardController::ResetWindowInsets() { |
| 458 const gfx::Insets insets; | 511 const gfx::Insets insets; |
| 459 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 512 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
| 460 content::RenderWidgetHost::GetRenderWidgetHosts()); | 513 content::RenderWidgetHost::GetRenderWidgetHosts()); |
| 461 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 514 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 462 content::RenderWidgetHostView* view = widget->GetView(); | 515 content::RenderWidgetHostView* view = widget->GetView(); |
| 463 if (view) | 516 if (view) { |
| 464 view->SetInsets(insets); | 517 view->SetInsets(insets); |
| 518 aura::Window *window = view->GetNativeView(); |
| 519 RemoveBoundsChangedObserver(window); |
| 520 } |
| 465 } | 521 } |
| 466 } | 522 } |
| 467 | 523 |
| 468 bool KeyboardController::WillHideKeyboard() const { | 524 bool KeyboardController::WillHideKeyboard() const { |
| 469 return weak_factory_.HasWeakPtrs(); | 525 return weak_factory_.HasWeakPtrs(); |
| 470 } | 526 } |
| 471 | 527 |
| 472 void KeyboardController::ShowAnimationFinished() { | 528 void KeyboardController::ShowAnimationFinished() { |
| 473 // Notify observers after animation finished to prevent reveal desktop | 529 // Notify observers after animation finished to prevent reveal desktop |
| 474 // background during animation. | 530 // background during animation. |
| 475 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); | 531 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); |
| 476 proxy_->EnsureCaretInWorkArea(); | 532 proxy_->EnsureCaretInWorkArea(); |
| 477 } | 533 } |
| 478 | 534 |
| 479 void KeyboardController::HideAnimationFinished() { | 535 void KeyboardController::HideAnimationFinished() { |
| 480 proxy_->HideKeyboardContainer(container_.get()); | 536 proxy_->HideKeyboardContainer(container_.get()); |
| 481 } | 537 } |
| 482 | 538 |
| 539 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { |
| 540 aura::Window* target_window = GetFrameWindow(window); |
| 541 if (target_window && |
| 542 !target_window->HasObserver(window_bounds_observer_.get())) { |
| 543 target_window->AddObserver(window_bounds_observer_.get()); |
| 544 } |
| 545 } |
| 546 |
| 547 void KeyboardController::RemoveBoundsChangedObserver(aura::Window* window) { |
| 548 aura::Window* target_window = GetFrameWindow(window); |
| 549 if (target_window && |
| 550 target_window->HasObserver(window_bounds_observer_.get())) { |
| 551 target_window->RemoveObserver(window_bounds_observer_.get()); |
| 552 } |
| 553 } |
| 554 |
| 483 } // namespace keyboard | 555 } // namespace keyboard |
| OLD | NEW |