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 |