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 explicit KeyboardWindowDelegate() {} |
sadrul
2015/04/01 06:43:48
Don't need explicit
bshe
2015/04/01 20:41:33
Done.
| |
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(gfx::Canvas* canvas) override {} | 82 void OnPaint(gfx::Canvas* canvas) 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 instance_ = controller; | 227 instance_ = controller; |
269 } | 228 } |
270 | 229 |
271 // static | 230 // static |
272 KeyboardController* KeyboardController::GetInstance() { | 231 KeyboardController* KeyboardController::GetInstance() { |
273 return instance_; | 232 return instance_; |
274 } | 233 } |
275 | 234 |
276 aura::Window* KeyboardController::GetContainerWindow() { | 235 aura::Window* KeyboardController::GetContainerWindow() { |
277 if (!container_.get()) { | 236 if (!container_.get()) { |
278 container_.reset(new aura::Window( | 237 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"); | 238 container_->SetName("KeyboardContainer"); |
283 container_->set_owned_by_parent(false); | 239 container_->set_owned_by_parent(false); |
284 container_->Init(aura::WINDOW_LAYER_NOT_DRAWN); | 240 container_->Init(aura::WINDOW_LAYER_NOT_DRAWN); |
285 container_->AddObserver(this); | 241 container_->AddObserver(this); |
286 container_->SetLayoutManager(new KeyboardLayoutManager(this)); | 242 container_->SetLayoutManager(new KeyboardLayoutManager(this)); |
287 } | 243 } |
288 return container_.get(); | 244 return container_.get(); |
289 } | 245 } |
290 | 246 |
291 void KeyboardController::NotifyKeyboardBoundsChanging( | 247 void KeyboardController::NotifyKeyboardBoundsChanging( |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 const ui::InputMethod* input_method) { | 390 const ui::InputMethod* input_method) { |
435 DCHECK_EQ(input_method_, input_method); | 391 DCHECK_EQ(input_method_, input_method); |
436 input_method_ = NULL; | 392 input_method_ = NULL; |
437 } | 393 } |
438 | 394 |
439 void KeyboardController::OnShowImeIfNeeded() { | 395 void KeyboardController::OnShowImeIfNeeded() { |
440 ShowKeyboardInternal(); | 396 ShowKeyboardInternal(); |
441 } | 397 } |
442 | 398 |
443 bool KeyboardController::ShouldEnableInsets(aura::Window* window) { | 399 bool KeyboardController::ShouldEnableInsets(aura::Window* window) { |
444 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | 400 aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); |
445 return (keyboard_window->GetRootWindow() == window->GetRootWindow() && | 401 return (keyboard_window->GetRootWindow() == window->GetRootWindow() && |
446 keyboard::IsKeyboardOverscrollEnabled() && | 402 keyboard::IsKeyboardOverscrollEnabled() && |
447 proxy_->GetKeyboardWindow()->IsVisible() && | 403 keyboard_window->IsVisible() && keyboard_visible_); |
448 keyboard_visible_); | |
449 } | 404 } |
450 | 405 |
451 void KeyboardController::UpdateWindowInsets(aura::Window* window) { | 406 void KeyboardController::UpdateWindowInsets(aura::Window* window) { |
452 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | 407 aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); |
453 if (window == keyboard_window) | 408 if (window == keyboard_window) |
454 return; | 409 return; |
455 | 410 |
456 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 411 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
457 content::RenderWidgetHost::GetRenderWidgetHosts()); | 412 content::RenderWidgetHost::GetRenderWidgetHosts()); |
458 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 413 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
459 content::RenderWidgetHostView* view = widget->GetView(); | 414 content::RenderWidgetHostView* view = widget->GetView(); |
460 if (view && window->Contains(view->GetNativeView())) { | 415 if (view && window->Contains(view->GetNativeView())) { |
461 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); | 416 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); |
462 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | 417 gfx::Rect intersect = |
463 proxy_->GetKeyboardWindow()->bounds()); | 418 gfx::IntersectRects(window_bounds, keyboard_window->bounds()); |
464 int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; | 419 int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; |
465 if (overlap > 0 && overlap < window_bounds.height()) | 420 if (overlap > 0 && overlap < window_bounds.height()) |
466 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | 421 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
467 else | 422 else |
468 view->SetInsets(gfx::Insets()); | 423 view->SetInsets(gfx::Insets()); |
469 return; | 424 return; |
470 } | 425 } |
471 } | 426 } |
472 } | 427 } |
473 | 428 |
429 void KeyboardController::OnRootWindowResized(const gfx::Rect& bounds) { | |
430 // Keep the same height when window resize. It gets called when screen rotate. | |
431 if (!keyboard_container_initialized() || !proxy_->GetKeyboardWindow()) | |
432 return; | |
433 | |
434 int container_height = container_->bounds().height(); | |
435 if (keyboard_mode_ == FULL_WIDTH) { | |
436 container_->SetBounds(gfx::Rect(bounds.x(), | |
437 bounds.bottom() - container_height, | |
438 bounds.width(), container_height)); | |
439 } else if (keyboard_mode_ == FLOATING) { | |
440 // When screen rotate, horizontally center floating virtual keyboard window | |
441 // and vertically align it to the bottom. | |
442 int container_width = container_->bounds().width(); | |
443 container_->SetBounds(gfx::Rect( | |
444 bounds.x() + (bounds.width() - container_width) / 2, | |
445 bounds.bottom() - container_height, container_width, container_height)); | |
446 } | |
447 } | |
448 | |
474 void KeyboardController::ShowKeyboardInternal() { | 449 void KeyboardController::ShowKeyboardInternal() { |
475 if (!container_.get()) | 450 if (!container_.get()) |
476 return; | 451 return; |
477 | 452 |
478 if (container_->children().empty()) { | 453 if (container_->children().empty()) { |
479 keyboard::MarkKeyboardLoadStarted(); | 454 keyboard::MarkKeyboardLoadStarted(); |
480 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | 455 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
481 keyboard->Show(); | 456 keyboard->Show(); |
482 container_->AddChild(keyboard); | 457 container_->AddChild(keyboard); |
483 keyboard->set_owned_by_parent(false); | 458 keyboard->set_owned_by_parent(false); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 window_bounds_observer_->RemoveAllObservedWindows(); | 532 window_bounds_observer_->RemoveAllObservedWindows(); |
558 } | 533 } |
559 | 534 |
560 bool KeyboardController::WillHideKeyboard() const { | 535 bool KeyboardController::WillHideKeyboard() const { |
561 return weak_factory_.HasWeakPtrs(); | 536 return weak_factory_.HasWeakPtrs(); |
562 } | 537 } |
563 | 538 |
564 void KeyboardController::ShowAnimationFinished() { | 539 void KeyboardController::ShowAnimationFinished() { |
565 // Notify observers after animation finished to prevent reveal desktop | 540 // Notify observers after animation finished to prevent reveal desktop |
566 // background during animation. | 541 // background during animation. |
567 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); | 542 NotifyKeyboardBoundsChanging(container_->bounds()); |
568 proxy_->EnsureCaretInWorkArea(); | 543 proxy_->EnsureCaretInWorkArea(); |
569 } | 544 } |
570 | 545 |
571 void KeyboardController::HideAnimationFinished() { | 546 void KeyboardController::HideAnimationFinished() { |
572 proxy_->HideKeyboardContainer(container_.get()); | 547 proxy_->HideKeyboardContainer(container_.get()); |
573 } | 548 } |
574 | 549 |
575 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { | 550 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { |
576 aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; | 551 aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; |
577 if (target_window) | 552 if (target_window) |
578 window_bounds_observer_->AddObservedWindow(target_window); | 553 window_bounds_observer_->AddObservedWindow(target_window); |
579 } | 554 } |
580 | 555 |
581 } // namespace keyboard | 556 } // namespace keyboard |
OLD | NEW |