Chromium Code Reviews| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 command.AppendArg("1"); | 138 command.AppendArg("1"); |
| 139 else | 139 else |
| 140 command.AppendArg("0"); | 140 command.AppendArg("0"); |
| 141 VLOG(1) << "Running " << command.GetCommandLineString(); | 141 VLOG(1) << "Running " << command.GetCommandLineString(); |
| 142 base::LaunchOptions options; | 142 base::LaunchOptions options; |
| 143 options.wait = true; | 143 options.wait = true; |
| 144 base::LaunchProcess(command, options, NULL); | 144 base::LaunchProcess(command, options, NULL); |
| 145 #endif | 145 #endif |
| 146 } | 146 } |
| 147 | 147 |
| 148 aura::Window *GetFrameWindow(aura::Window *window) { | |
| 149 // Each container window has a non-negative id. Stop traversing at the child | |
| 150 // of a container window. | |
| 151 if (!window) | |
| 152 return NULL; | |
| 153 while (window->parent() && window->parent()->id() < 0) { | |
| 154 window = window->parent(); | |
| 155 } | |
| 156 return window; | |
| 157 } | |
| 158 | |
| 159 } // namespace | 148 } // namespace |
| 160 | 149 |
| 161 namespace keyboard { | 150 namespace keyboard { |
| 162 | 151 |
| 163 // Observer for both keyboard show and hide animations. It should be owned by | 152 // Observer for both keyboard show and hide animations. It should be owned by |
| 164 // KeyboardController. | 153 // KeyboardController. |
| 165 class CallbackAnimationObserver : public ui::LayerAnimationObserver { | 154 class CallbackAnimationObserver : public ui::LayerAnimationObserver { |
| 166 public: | 155 public: |
| 167 CallbackAnimationObserver(ui::LayerAnimator* animator, | 156 CallbackAnimationObserver(ui::LayerAnimator* animator, |
| 168 base::Callback<void(void)> callback); | 157 base::Callback<void(void)> callback); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 197 callback_.Run(); | 186 callback_.Run(); |
| 198 } | 187 } |
| 199 | 188 |
| 200 void CallbackAnimationObserver::OnLayerAnimationAborted( | 189 void CallbackAnimationObserver::OnLayerAnimationAborted( |
| 201 ui::LayerAnimationSequence* seq) { | 190 ui::LayerAnimationSequence* seq) { |
| 202 animator_->RemoveObserver(this); | 191 animator_->RemoveObserver(this); |
| 203 } | 192 } |
| 204 | 193 |
| 205 class WindowBoundsChangeObserver : public aura::WindowObserver { | 194 class WindowBoundsChangeObserver : public aura::WindowObserver { |
| 206 public: | 195 public: |
| 196 explicit WindowBoundsChangeObserver(aura::Window* window); | |
| 197 ~WindowBoundsChangeObserver() override; | |
| 198 | |
| 207 void OnWindowBoundsChanged(aura::Window* window, | 199 void OnWindowBoundsChanged(aura::Window* window, |
| 208 const gfx::Rect& old_bounds, | 200 const gfx::Rect& old_bounds, |
| 209 const gfx::Rect& new_bounds) override; | 201 const gfx::Rect& new_bounds) override; |
| 210 void OnWindowDestroyed(aura::Window* window) override; | 202 void OnWindowDestroyed(aura::Window* window) override; |
| 211 | 203 |
| 212 void AddObservedWindow(aura::Window* window); | 204 private: |
| 213 void RemoveAllObservedWindows(); | 205 aura::Window* window_; |
| 214 | 206 |
| 215 private: | 207 DISALLOW_COPY_AND_ASSIGN(WindowBoundsChangeObserver); |
| 216 std::set<aura::Window*> observed_windows_; | |
| 217 }; | 208 }; |
| 218 | 209 |
| 210 WindowBoundsChangeObserver::WindowBoundsChangeObserver(aura::Window* window) | |
| 211 : window_(window) { | |
| 212 window_->AddObserver(this); | |
| 213 } | |
| 214 | |
| 215 WindowBoundsChangeObserver::~WindowBoundsChangeObserver() { | |
| 216 if (window_) | |
| 217 window_->RemoveObserver(this); | |
| 218 } | |
| 219 | |
| 219 void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, | 220 void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, |
| 220 const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { | 221 const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { |
| 221 KeyboardController* controller = KeyboardController::GetInstance(); | 222 KeyboardController* controller = KeyboardController::GetInstance(); |
| 222 if (controller) | 223 if (controller) |
| 223 controller->UpdateWindowInsets(window); | 224 controller->UpdateWindowInsets(window); |
| 224 } | 225 } |
| 225 | 226 |
| 226 void WindowBoundsChangeObserver::OnWindowDestroyed(aura::Window* window) { | 227 void WindowBoundsChangeObserver::OnWindowDestroyed(aura::Window* window) { |
| 227 if (window->HasObserver(this)) | 228 window_ = nullptr; |
| 228 window->RemoveObserver(this); | |
| 229 observed_windows_.erase(window); | |
| 230 } | |
| 231 | |
| 232 void WindowBoundsChangeObserver::AddObservedWindow(aura::Window* window) { | |
| 233 if (!window->HasObserver(this)) { | |
| 234 window->AddObserver(this); | |
| 235 observed_windows_.insert(window); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 void WindowBoundsChangeObserver::RemoveAllObservedWindows() { | |
| 240 for (std::set<aura::Window*>::iterator it = observed_windows_.begin(); | |
| 241 it != observed_windows_.end(); ++it) | |
| 242 (*it)->RemoveObserver(this); | |
| 243 observed_windows_.clear(); | |
| 244 } | 229 } |
| 245 | 230 |
| 246 // static | 231 // static |
| 247 KeyboardController* KeyboardController::instance_ = NULL; | 232 KeyboardController* KeyboardController::instance_ = NULL; |
| 248 | 233 |
| 249 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 234 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
| 250 : proxy_(proxy), | 235 : proxy_(proxy), |
| 251 input_method_(NULL), | 236 input_method_(NULL), |
| 252 keyboard_visible_(false), | 237 keyboard_visible_(false), |
| 253 show_on_resize_(false), | 238 show_on_resize_(false), |
| 254 lock_keyboard_(false), | 239 lock_keyboard_(false), |
| 255 type_(ui::TEXT_INPUT_TYPE_NONE), | 240 type_(ui::TEXT_INPUT_TYPE_NONE), |
| 256 weak_factory_(this) { | 241 weak_factory_(this) { |
| 257 CHECK(proxy); | 242 CHECK(proxy); |
| 258 input_method_ = proxy_->GetInputMethod(); | 243 input_method_ = proxy_->GetInputMethod(); |
| 259 input_method_->AddObserver(this); | 244 input_method_->AddObserver(this); |
| 260 window_bounds_observer_.reset(new WindowBoundsChangeObserver()); | |
| 261 } | 245 } |
| 262 | 246 |
| 263 KeyboardController::~KeyboardController() { | 247 KeyboardController::~KeyboardController() { |
| 264 if (container_) | 248 if (container_) |
| 265 container_->RemoveObserver(this); | 249 container_->RemoveObserver(this); |
| 266 if (input_method_) | 250 if (input_method_) |
| 267 input_method_->RemoveObserver(this); | 251 input_method_->RemoveObserver(this); |
| 268 ResetWindowInsets(); | 252 ResetWindowInsets(); |
| 269 } | 253 } |
| 270 | 254 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 FOR_EACH_OBSERVER(KeyboardControllerObserver, | 286 FOR_EACH_OBSERVER(KeyboardControllerObserver, |
| 303 observer_list_, | 287 observer_list_, |
| 304 OnKeyboardBoundsChanging(new_bounds)); | 288 OnKeyboardBoundsChanging(new_bounds)); |
| 305 if (keyboard::IsKeyboardOverscrollEnabled()) { | 289 if (keyboard::IsKeyboardOverscrollEnabled()) { |
| 306 // Adjust the height of the viewport for visible windows on the primary | 290 // Adjust the height of the viewport for visible windows on the primary |
| 307 // display. | 291 // display. |
| 308 // TODO(kevers): Add EnvObserver to properly initialize insets if a | 292 // TODO(kevers): Add EnvObserver to properly initialize insets if a |
| 309 // window is created while the keyboard is visible. | 293 // window is created while the keyboard is visible. |
| 310 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 294 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
| 311 content::RenderWidgetHost::GetRenderWidgetHosts()); | 295 content::RenderWidgetHost::GetRenderWidgetHosts()); |
| 312 aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); | 296 aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); |
| 313 aura::Window *root_window = keyboard_window->GetRootWindow(); | 297 aura::Window* root_window = keyboard_window->GetRootWindow(); |
| 314 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 298 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 315 content::RenderWidgetHostView* view = widget->GetView(); | 299 content::RenderWidgetHostView* view = widget->GetView(); |
| 316 // Can be NULL, e.g. if the RenderWidget is being destroyed or | 300 // Can be NULL, e.g. if the RenderWidget is being destroyed or |
| 317 // the render process crashed. | 301 // the render process crashed. |
| 318 if (view) { | 302 if (view) { |
| 319 aura::Window *window = view->GetNativeView(); | 303 aura::Window *window = view->GetNativeView(); |
| 320 // If virtual keyboard failed to load, a widget that displays error | 304 // If virtual keyboard failed to load, a widget that displays error |
| 321 // message will be created and adds as a child of the virtual keyboard | 305 // message will be created and added as a child of the virtual |
| 322 // window. We want to avoid add BoundsChangedObserver to that window. | 306 // keyboard window. |
|
pkotwicz
2014/11/12 06:01:14
Kevin do you have any suggestions for comments her
| |
| 323 if (GetFrameWindow(window) != keyboard_window && | 307 if (!keyboard_window->Contains(window) && |
| 324 window->GetRootWindow() == root_window) { | 308 window->GetRootWindow() == root_window) { |
| 325 gfx::Rect window_bounds = window->GetBoundsInScreen(); | 309 gfx::Rect window_bounds = window->GetBoundsInScreen(); |
| 326 gfx::Rect intersect = gfx::IntersectRects(window_bounds, | 310 gfx::Rect intersect = gfx::IntersectRects(window_bounds, |
| 327 new_bounds); | 311 new_bounds); |
| 328 int overlap = intersect.height(); | 312 int overlap = intersect.height(); |
| 329 if (overlap > 0 && overlap < window_bounds.height()) | 313 if (overlap > 0 && overlap < window_bounds.height()) |
| 330 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); | 314 view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
| 331 else | 315 else |
| 332 view->SetInsets(gfx::Insets()); | 316 view->SetInsets(gfx::Insets()); |
| 333 AddBoundsChangedObserver(window); | |
| 334 } | 317 } |
| 335 } | 318 } |
| 336 } | 319 } |
| 320 root_window_bounds_observer_.reset( | |
| 321 new WindowBoundsChangeObserver(root_window)); | |
| 337 } else { | 322 } else { |
| 338 ResetWindowInsets(); | 323 ResetWindowInsets(); |
| 339 } | 324 } |
| 340 } else { | 325 } else { |
| 341 current_keyboard_bounds_ = gfx::Rect(); | 326 current_keyboard_bounds_ = gfx::Rect(); |
| 342 } | 327 } |
| 343 } | 328 } |
| 344 | 329 |
| 345 void KeyboardController::HideKeyboard(HideReason reason) { | 330 void KeyboardController::HideKeyboard(HideReason reason) { |
| 346 keyboard_visible_ = false; | 331 keyboard_visible_ = false; |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 | 535 |
| 551 void KeyboardController::ResetWindowInsets() { | 536 void KeyboardController::ResetWindowInsets() { |
| 552 const gfx::Insets insets; | 537 const gfx::Insets insets; |
| 553 scoped_ptr<content::RenderWidgetHostIterator> widgets( | 538 scoped_ptr<content::RenderWidgetHostIterator> widgets( |
| 554 content::RenderWidgetHost::GetRenderWidgetHosts()); | 539 content::RenderWidgetHost::GetRenderWidgetHosts()); |
| 555 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { | 540 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
| 556 content::RenderWidgetHostView* view = widget->GetView(); | 541 content::RenderWidgetHostView* view = widget->GetView(); |
| 557 if (view) | 542 if (view) |
| 558 view->SetInsets(insets); | 543 view->SetInsets(insets); |
| 559 } | 544 } |
| 560 window_bounds_observer_->RemoveAllObservedWindows(); | 545 root_window_bounds_observer_.reset(); |
| 561 } | 546 } |
| 562 | 547 |
| 563 bool KeyboardController::WillHideKeyboard() const { | 548 bool KeyboardController::WillHideKeyboard() const { |
| 564 return weak_factory_.HasWeakPtrs(); | 549 return weak_factory_.HasWeakPtrs(); |
| 565 } | 550 } |
| 566 | 551 |
| 567 void KeyboardController::ShowAnimationFinished() { | 552 void KeyboardController::ShowAnimationFinished() { |
| 568 // Notify observers after animation finished to prevent reveal desktop | 553 // Notify observers after animation finished to prevent reveal desktop |
| 569 // background during animation. | 554 // background during animation. |
| 570 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); | 555 NotifyKeyboardBoundsChanging(proxy_->GetKeyboardWindow()->bounds()); |
| 571 proxy_->EnsureCaretInWorkArea(); | 556 proxy_->EnsureCaretInWorkArea(); |
| 572 } | 557 } |
| 573 | 558 |
| 574 void KeyboardController::HideAnimationFinished() { | 559 void KeyboardController::HideAnimationFinished() { |
| 575 proxy_->HideKeyboardContainer(container_.get()); | 560 proxy_->HideKeyboardContainer(container_.get()); |
| 576 } | 561 } |
| 577 | 562 |
| 578 void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { | |
| 579 aura::Window* target_window = GetFrameWindow(window); | |
| 580 if (target_window) | |
| 581 window_bounds_observer_->AddObservedWindow(target_window); | |
| 582 } | |
| 583 | |
| 584 } // namespace keyboard | 563 } // namespace keyboard |
| OLD | NEW |