| 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 <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 // The virtual keyboard show/hide animation duration. | 41 // The virtual keyboard show/hide animation duration. |
| 42 const int kShowAnimationDurationMs = 350; | 42 const int kShowAnimationDurationMs = 350; |
| 43 const int kHideAnimationDurationMs = 100; | 43 const int kHideAnimationDurationMs = 100; |
| 44 | 44 |
| 45 // The opacity of virtual keyboard container when show animation starts or | 45 // The opacity of virtual keyboard container when show animation starts or |
| 46 // hide animation finishes. This cannot be zero because we call Show() on the | 46 // hide animation finishes. This cannot be zero because we call Show() on the |
| 47 // keyboard window before setting the opacity back to 1.0. Since windows are not | 47 // keyboard window before setting the opacity back to 1.0. Since windows are not |
| 48 // allowed to be shown with zero opacity, we always animate to 0.01 instead. | 48 // allowed to be shown with zero opacity, we always animate to 0.01 instead. |
| 49 const float kAnimationStartOrAfterHideOpacity = 0.01f; | 49 const float kAnimationStartOrAfterHideOpacity = 0.01f; |
| 50 | 50 |
| 51 // Event targeter for the keyboard container. | |
| 52 class KeyboardContainerTargeter : public wm::MaskedWindowTargeter { | |
| 53 public: | |
| 54 KeyboardContainerTargeter(aura::Window* container, | |
| 55 keyboard::KeyboardControllerProxy* proxy) | |
| 56 : wm::MaskedWindowTargeter(container), | |
| 57 proxy_(proxy) { | |
| 58 } | |
| 59 | |
| 60 ~KeyboardContainerTargeter() override {} | |
| 61 | |
| 62 private: | |
| 63 // wm::MaskedWindowTargeter: | |
| 64 bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const override { | |
| 65 if (proxy_ && !proxy_->HasKeyboardWindow()) | |
| 66 return true; | |
| 67 gfx::Rect keyboard_bounds = proxy_ ? proxy_->GetKeyboardWindow()->bounds() : | |
| 68 keyboard::DefaultKeyboardBoundsFromWindowBounds(window->bounds()); | |
| 69 mask->addRect(RectToSkRect(keyboard_bounds)); | |
| 70 return true; | |
| 71 } | |
| 72 | |
| 73 keyboard::KeyboardControllerProxy* proxy_; | |
| 74 | |
| 75 DISALLOW_COPY_AND_ASSIGN(KeyboardContainerTargeter); | |
| 76 }; | |
| 77 | |
| 78 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. | 51 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. |
| 79 // This is necessary to make sure that the synthetic key-events reach the target | 52 // This is necessary to make sure that the synthetic key-events reach the target |
| 80 // window. | 53 // window. |
| 81 // The delegate deletes itself when the window is destroyed. | 54 // The delegate deletes itself when the window is destroyed. |
| 82 class KeyboardWindowDelegate : public aura::WindowDelegate { | 55 class KeyboardWindowDelegate : public aura::WindowDelegate { |
| 83 public: | 56 public: |
| 84 explicit KeyboardWindowDelegate(keyboard::KeyboardControllerProxy* proxy) | 57 KeyboardWindowDelegate() {} |
| 85 : proxy_(proxy) {} | |
| 86 ~KeyboardWindowDelegate() override {} | 58 ~KeyboardWindowDelegate() override {} |
| 87 | 59 |
| 88 private: | 60 private: |
| 89 // Overridden from aura::WindowDelegate: | 61 // Overridden from aura::WindowDelegate: |
| 90 gfx::Size GetMinimumSize() const override { return gfx::Size(); } | 62 gfx::Size GetMinimumSize() const override { return gfx::Size(); } |
| 91 gfx::Size GetMaximumSize() const override { return gfx::Size(); } | 63 gfx::Size GetMaximumSize() const override { return gfx::Size(); } |
| 92 void OnBoundsChanged(const gfx::Rect& old_bounds, | 64 void OnBoundsChanged(const gfx::Rect& old_bounds, |
| 93 const gfx::Rect& new_bounds) override { | 65 const gfx::Rect& new_bounds) override {} |
| 94 bounds_ = new_bounds; | |
| 95 } | |
| 96 ui::TextInputClient* GetFocusedTextInputClient() override { | 66 ui::TextInputClient* GetFocusedTextInputClient() override { |
| 97 return nullptr; | 67 return nullptr; |
| 98 } | 68 } |
| 99 gfx::NativeCursor GetCursor(const gfx::Point& point) override { | 69 gfx::NativeCursor GetCursor(const gfx::Point& point) override { |
| 100 return gfx::kNullCursor; | 70 return gfx::kNullCursor; |
| 101 } | 71 } |
| 102 int GetNonClientComponent(const gfx::Point& point) const override { | 72 int GetNonClientComponent(const gfx::Point& point) const override { |
| 103 return HTNOWHERE; | 73 return HTNOWHERE; |
| 104 } | 74 } |
| 105 bool ShouldDescendIntoChildForEventHandling( | 75 bool ShouldDescendIntoChildForEventHandling( |
| 106 aura::Window* child, | 76 aura::Window* child, |
| 107 const gfx::Point& location) override { | 77 const gfx::Point& location) override { |
| 108 return true; | 78 return true; |
| 109 } | 79 } |
| 110 bool CanFocus() override { return false; } | 80 bool CanFocus() override { return false; } |
| 111 void OnCaptureLost() override {} | 81 void OnCaptureLost() override {} |
| 112 void OnPaint(const ui::PaintContext& context) override {} | 82 void OnPaint(const ui::PaintContext& context) override {} |
| 113 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} | 83 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} |
| 114 void OnWindowDestroying(aura::Window* window) override {} | 84 void OnWindowDestroying(aura::Window* window) override {} |
| 115 void OnWindowDestroyed(aura::Window* window) override { delete this; } | 85 void OnWindowDestroyed(aura::Window* window) override { delete this; } |
| 116 void OnWindowTargetVisibilityChanged(bool visible) override {} | 86 void OnWindowTargetVisibilityChanged(bool visible) override {} |
| 117 bool HasHitTestMask() const override { | 87 bool HasHitTestMask() const override { return false; } |
| 118 return !proxy_ || proxy_->HasKeyboardWindow(); | 88 void GetHitTestMask(gfx::Path* mask) const override {} |
| 119 } | |
| 120 void GetHitTestMask(gfx::Path* mask) const override { | |
| 121 if (proxy_ && !proxy_->HasKeyboardWindow()) | |
| 122 return; | |
| 123 gfx::Rect keyboard_bounds = proxy_ ? proxy_->GetKeyboardWindow()->bounds() : | |
| 124 keyboard::DefaultKeyboardBoundsFromWindowBounds(bounds_); | |
| 125 mask->addRect(RectToSkRect(keyboard_bounds)); | |
| 126 } | |
| 127 | |
| 128 gfx::Rect bounds_; | |
| 129 keyboard::KeyboardControllerProxy* proxy_; | |
| 130 | 89 |
| 131 DISALLOW_COPY_AND_ASSIGN(KeyboardWindowDelegate); | 90 DISALLOW_COPY_AND_ASSIGN(KeyboardWindowDelegate); |
| 132 }; | 91 }; |
| 133 | 92 |
| 134 void ToggleTouchEventLogging(bool enable) { | 93 void ToggleTouchEventLogging(bool enable) { |
| 135 #if defined(OS_CHROMEOS) | 94 #if defined(OS_CHROMEOS) |
| 136 if (!base::SysInfo::IsRunningOnChromeOS()) | 95 if (!base::SysInfo::IsRunningOnChromeOS()) |
| 137 return; | 96 return; |
| 138 base::CommandLine command( | 97 base::CommandLine command( |
| 139 base::FilePath("/opt/google/touchscreen/toggle_touch_event_logging")); | 98 base::FilePath("/opt/google/touchscreen/toggle_touch_event_logging")); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 keyboard_mode_(FULL_WIDTH), | 206 keyboard_mode_(FULL_WIDTH), |
| 248 type_(ui::TEXT_INPUT_TYPE_NONE), | 207 type_(ui::TEXT_INPUT_TYPE_NONE), |
| 249 weak_factory_(this) { | 208 weak_factory_(this) { |
| 250 CHECK(proxy); | 209 CHECK(proxy); |
| 251 input_method_ = proxy_->GetInputMethod(); | 210 input_method_ = proxy_->GetInputMethod(); |
| 252 input_method_->AddObserver(this); | 211 input_method_->AddObserver(this); |
| 253 window_bounds_observer_.reset(new WindowBoundsChangeObserver()); | 212 window_bounds_observer_.reset(new WindowBoundsChangeObserver()); |
| 254 } | 213 } |
| 255 | 214 |
| 256 KeyboardController::~KeyboardController() { | 215 KeyboardController::~KeyboardController() { |
| 257 if (container_) | 216 if (container_) { |
| 217 if (container_->GetRootWindow()) |
| 218 container_->GetRootWindow()->RemoveObserver(this); |
| 258 container_->RemoveObserver(this); | 219 container_->RemoveObserver(this); |
| 220 } |
| 259 if (input_method_) | 221 if (input_method_) |
| 260 input_method_->RemoveObserver(this); | 222 input_method_->RemoveObserver(this); |
| 261 ResetWindowInsets(); | 223 ResetWindowInsets(); |
| 262 } | 224 } |
| 263 | 225 |
| 264 // static | 226 // static |
| 265 void KeyboardController::ResetInstance(KeyboardController* controller) { | 227 void KeyboardController::ResetInstance(KeyboardController* controller) { |
| 266 if (instance_ && instance_ != controller) | 228 if (instance_ && instance_ != controller) |
| 267 delete instance_; | 229 delete instance_; |
| 268 instance_ = controller; | 230 instance_ = controller; |
| 269 } | 231 } |
| 270 | 232 |
| 271 // static | 233 // static |
| 272 KeyboardController* KeyboardController::GetInstance() { | 234 KeyboardController* KeyboardController::GetInstance() { |
| 273 return instance_; | 235 return instance_; |
| 274 } | 236 } |
| 275 | 237 |
| 276 aura::Window* KeyboardController::GetContainerWindow() { | 238 aura::Window* KeyboardController::GetContainerWindow() { |
| 277 if (!container_.get()) { | 239 if (!container_.get()) { |
| 278 container_.reset(new aura::Window( | 240 container_.reset(new aura::Window(new KeyboardWindowDelegate())); |
| 279 new KeyboardWindowDelegate(proxy_.get()))); | |
| 280 container_->SetEventTargeter(scoped_ptr<ui::EventTargeter>( | |
| 281 new KeyboardContainerTargeter(container_.get(), proxy_.get()))); | |
| 282 container_->SetName("KeyboardContainer"); | 241 container_->SetName("KeyboardContainer"); |
| 283 container_->set_owned_by_parent(false); | 242 container_->set_owned_by_parent(false); |
| 284 container_->Init(ui::LAYER_NOT_DRAWN); | 243 container_->Init(ui::LAYER_NOT_DRAWN); |
| 285 container_->AddObserver(this); | 244 container_->AddObserver(this); |
| 286 container_->SetLayoutManager(new KeyboardLayoutManager(this)); | 245 container_->SetLayoutManager(new KeyboardLayoutManager(this)); |
| 287 } | 246 } |
| 288 return container_.get(); | 247 return container_.get(); |
| 289 } | 248 } |
| 290 | 249 |
| 291 void KeyboardController::NotifyKeyboardBoundsChanging( | 250 void KeyboardController::NotifyKeyboardBoundsChanging( |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 set_lock_keyboard(lock); | 340 set_lock_keyboard(lock); |
| 382 ShowKeyboardInternal(); | 341 ShowKeyboardInternal(); |
| 383 } | 342 } |
| 384 | 343 |
| 385 void KeyboardController::OnWindowHierarchyChanged( | 344 void KeyboardController::OnWindowHierarchyChanged( |
| 386 const HierarchyChangeParams& params) { | 345 const HierarchyChangeParams& params) { |
| 387 if (params.new_parent && params.target == container_.get()) | 346 if (params.new_parent && params.target == container_.get()) |
| 388 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); | 347 OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); |
| 389 } | 348 } |
| 390 | 349 |
| 350 void KeyboardController::OnWindowAddedToRootWindow(aura::Window* window) { |
| 351 if (!window->GetRootWindow()->HasObserver(this)) |
| 352 window->GetRootWindow()->AddObserver(this); |
| 353 } |
| 354 |
| 355 void KeyboardController::OnWindowRemovingFromRootWindow(aura::Window* window, |
| 356 aura::Window* new_root) { |
| 357 if (window->GetRootWindow()->HasObserver(this)) |
| 358 window->GetRootWindow()->RemoveObserver(this); |
| 359 } |
| 360 |
| 361 void KeyboardController::OnWindowBoundsChanged(aura::Window* window, |
| 362 const gfx::Rect& old_bounds, |
| 363 const gfx::Rect& new_bounds) { |
| 364 if (!window->IsRootWindow()) |
| 365 return; |
| 366 // Keep the same height when window resize. It gets called when screen |
| 367 // rotate. |
| 368 if (!keyboard_container_initialized() || !proxy_->HasKeyboardWindow()) |
| 369 return; |
| 370 |
| 371 int container_height = container_->bounds().height(); |
| 372 if (keyboard_mode_ == FULL_WIDTH) { |
| 373 container_->SetBounds(gfx::Rect(new_bounds.x(), |
| 374 new_bounds.bottom() - container_height, |
| 375 new_bounds.width(), |
| 376 container_height)); |
| 377 } else if (keyboard_mode_ == FLOATING) { |
| 378 // When screen rotate, horizontally center floating virtual keyboard |
| 379 // window and vertically align it to the bottom. |
| 380 int container_width = container_->bounds().width(); |
| 381 container_->SetBounds(gfx::Rect( |
| 382 new_bounds.x() + (new_bounds.width() - container_width) / 2, |
| 383 new_bounds.bottom() - container_height, |
| 384 container_width, |
| 385 container_height)); |
| 386 } |
| 387 } |
| 388 |
| 391 void KeyboardController::Reload() { | 389 void KeyboardController::Reload() { |
| 392 if (proxy_->HasKeyboardWindow()) { | 390 if (proxy_->HasKeyboardWindow()) { |
| 393 // A reload should never try to show virtual keyboard. If keyboard is not | 391 // A reload should never try to show virtual keyboard. If keyboard is not |
| 394 // visible before reload, it should keep invisible after reload. | 392 // visible before reload, it should keep invisible after reload. |
| 395 show_on_resize_ = false; | 393 show_on_resize_ = false; |
| 396 proxy_->ReloadKeyboardIfNeeded(); | 394 proxy_->ReloadKeyboardIfNeeded(); |
| 397 } | 395 } |
| 398 } | 396 } |
| 399 | 397 |
| 400 void KeyboardController::OnTextInputStateChanged( | 398 void KeyboardController::OnTextInputStateChanged( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 const ui::InputMethod* input_method) { | 432 const ui::InputMethod* input_method) { |
| 435 DCHECK_EQ(input_method_, input_method); | 433 DCHECK_EQ(input_method_, input_method); |
| 436 input_method_ = NULL; | 434 input_method_ = NULL; |
| 437 } | 435 } |
| 438 | 436 |
| 439 void KeyboardController::OnShowImeIfNeeded() { | 437 void KeyboardController::OnShowImeIfNeeded() { |
| 440 ShowKeyboardInternal(); | 438 ShowKeyboardInternal(); |
| 441 } | 439 } |
| 442 | 440 |
| 443 bool KeyboardController::ShouldEnableInsets(aura::Window* window) { | 441 bool KeyboardController::ShouldEnableInsets(aura::Window* window) { |
| 444 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | 442 aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); |
| 445 return (keyboard_window->GetRootWindow() == window->GetRootWindow() && | 443 return (keyboard_window->GetRootWindow() == window->GetRootWindow() && |
| 446 keyboard::IsKeyboardOverscrollEnabled() && | 444 keyboard::IsKeyboardOverscrollEnabled() && |
| 447 proxy_->GetKeyboardWindow()->IsVisible() && | 445 keyboard_window->IsVisible() && keyboard_visible_); |
| 448 keyboard_visible_); | |
| 449 } | 446 } |
| 450 | 447 |
| 451 void KeyboardController::UpdateWindowInsets(aura::Window* window) { | 448 void KeyboardController::UpdateWindowInsets(aura::Window* window) { |
| 452 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | 449 aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); |
| 453 if (window == keyboard_window) | 450 if (window == keyboard_window) |
| 454 return; | 451 return; |
| 455 | 452 |
| 456 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 453 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
| 457 content::RenderWidgetHost::GetRenderWidgetHosts()); | 454 content::RenderWidgetHost::GetRenderWidgetHosts()); |
| 458 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 455 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 459 content::RenderWidgetHostView* view = widget->GetView(); | 456 content::RenderWidgetHostView* view = widget->GetView(); |
| 460 if (view && window->Contains(view->GetNativeView())) { | 457 if (view && window->Contains(view->GetNativeView())) { |
| 461 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); | 458 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); |
| 462 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | 459 gfx::Rect intersect = |
| 463 proxy_->GetKeyboardWindow()->bounds()); | 460 gfx::IntersectRects(window_bounds, keyboard_window->bounds()); |
| 464 int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; | 461 int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; |
| 465 if (overlap > 0 && overlap < window_bounds.height()) | 462 if (overlap > 0 && overlap < window_bounds.height()) |
| 466 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | 463 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
| 467 else | 464 else |
| 468 view->SetInsets(gfx::Insets()); | 465 view->SetInsets(gfx::Insets()); |
| 469 return; | 466 return; |
| 470 } | 467 } |
| 471 } | 468 } |
| 472 } | 469 } |
| 473 | 470 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 window_bounds_observer_->RemoveAllObservedWindows(); | 554 window_bounds_observer_->RemoveAllObservedWindows(); |
| 558 } | 555 } |
| 559 | 556 |
| 560 bool KeyboardController::WillHideKeyboard() const { | 557 bool KeyboardController::WillHideKeyboard() const { |
| 561 return weak_factory_.HasWeakPtrs(); | 558 return weak_factory_.HasWeakPtrs(); |
| 562 } | 559 } |
| 563 | 560 |
| 564 void KeyboardController::ShowAnimationFinished() { | 561 void KeyboardController::ShowAnimationFinished() { |
| 565 // Notify observers after animation finished to prevent reveal desktop | 562 // Notify observers after animation finished to prevent reveal desktop |
| 566 // background during animation. | 563 // background during animation. |
| 567 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); | 564 NotifyKeyboardBoundsChanging(container_->bounds()); |
| 568 proxy_->EnsureCaretInWorkArea(); | 565 proxy_->EnsureCaretInWorkArea(); |
| 569 } | 566 } |
| 570 | 567 |
| 571 void KeyboardController::HideAnimationFinished() { | 568 void KeyboardController::HideAnimationFinished() { |
| 572 proxy_->HideKeyboardContainer(container_.get()); | 569 proxy_->HideKeyboardContainer(container_.get()); |
| 573 } | 570 } |
| 574 | 571 |
| 575 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { | 572 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { |
| 576 aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; | 573 aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; |
| 577 if (target_window) | 574 if (target_window) |
| 578 window_bounds_observer_->AddObservedWindow(target_window); | 575 window_bounds_observer_->AddObservedWindow(target_window); |
| 579 } | 576 } |
| 580 | 577 |
| 581 } // namespace keyboard | 578 } // namespace keyboard |
| OLD | NEW |