Index: ui/keyboard/keyboard_controller.cc |
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc |
index 1685451d32f433835afb163f79059c467de0dd97..f74ff7a612e1b63b927472462f1de31f6665b55f 100644 |
--- a/ui/keyboard/keyboard_controller.cc |
+++ b/ui/keyboard/keyboard_controller.cc |
@@ -11,6 +11,7 @@ |
#include "content/public/browser/render_widget_host_view.h" |
#include "ui/aura/window.h" |
#include "ui/aura/window_delegate.h" |
+#include "ui/aura/window_observer.h" |
#include "ui/base/cursor/cursor.h" |
#include "ui/base/hit_test.h" |
#include "ui/base/ime/input_method.h" |
@@ -141,6 +142,17 @@ void ToggleTouchEventLogging(bool enable) { |
#endif |
} |
+aura::Window *GetFrameWindow(aura::Window *window) { |
+ // Each container window has a non-negative id. Stop traversing at the child |
+ // of a container window. |
+ if (!window) |
+ return NULL; |
+ while(window->parent() && window->parent()->id() < 0) { |
+ window = window->parent(); |
+ } |
+ return window; |
+} |
+ |
} // namespace |
namespace keyboard { |
@@ -189,6 +201,20 @@ void CallbackAnimationObserver::OnLayerAnimationAborted( |
animator_->RemoveObserver(this); |
} |
+class WindowBoundsChangeObserver : public aura::WindowObserver { |
+ public: |
+ virtual void OnWindowBoundsChanged(aura::Window* window, |
+ const gfx::Rect& old_bounds, |
+ const gfx::Rect& new_bounds) OVERRIDE; |
+}; |
+ |
+void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, |
+ const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { |
+ KeyboardController* controller = KeyboardController::GetInstance(); |
+ if (controller) |
+ controller->UpdateWindowInsets(window); |
+} |
+ |
// static |
KeyboardController* KeyboardController::instance_ = NULL; |
@@ -202,6 +228,7 @@ KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
CHECK(proxy); |
input_method_ = proxy_->GetInputMethod(); |
input_method_->AddObserver(this); |
+ window_bounds_observer_.reset(new WindowBoundsChangeObserver()); |
} |
KeyboardController::~KeyboardController() { |
@@ -270,9 +297,8 @@ void KeyboardController::NotifyKeyboardBoundsChanging( |
if (overlap > 0 && overlap < window_bounds.height()) |
view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
else |
- view->SetInsets(gfx::Insets(0, 0, 0, 0)); |
- // TODO(kevers): Add window observer to native window to update |
- // insets on a window move or resize. |
+ view->SetInsets(gfx::Insets()); |
+ AddBoundsChangedObserver(window); |
} |
} |
} |
@@ -384,6 +410,33 @@ void KeyboardController::OnShowImeIfNeeded() { |
ShowKeyboardInternal(); |
} |
+void KeyboardController::UpdateWindowInsets(aura::Window* window) { |
+ aura::Window *keyboard_window = proxy_->GetKeyboardWindow(); |
+ if (window == keyboard_window) |
+ return; |
+ |
+ bool enableInsets = (keyboard_window->GetRootWindow() == |
+ window->GetRootWindow()) && keyboard::IsKeyboardOverscrollEnabled() && |
+ proxy_->GetKeyboardWindow()->IsVisible(); |
+ |
+ scoped_ptr<content::RenderWidgetHostIterator> widgets( |
+ content::RenderWidgetHost::GetRenderWidgetHosts()); |
+ while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
+ content::RenderWidgetHostView* view = widget->GetView(); |
+ if (view && window->Contains(view->GetNativeView())) { |
+ gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); |
+ gfx::Rect intersect = gfx::IntersectRects(window_bounds, |
+ proxy_->GetKeyboardWindow()->bounds()); |
+ int overlap = enableInsets ? intersect.height() : 0; |
+ if (overlap > 0 && overlap < window_bounds.height()) |
+ view->SetInsets(gfx::Insets(0, 0, overlap, 0)); |
+ else |
+ view->SetInsets(gfx::Insets()); |
+ return; |
+ } |
+ } |
+} |
+ |
void KeyboardController::ShowKeyboardInternal() { |
if (!container_.get()) |
return; |
@@ -460,8 +513,11 @@ void KeyboardController::ResetWindowInsets() { |
content::RenderWidgetHost::GetRenderWidgetHosts()); |
while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { |
content::RenderWidgetHostView* view = widget->GetView(); |
- if (view) |
+ if (view) { |
view->SetInsets(insets); |
+ aura::Window *window = view->GetNativeView(); |
+ RemoveBoundsChangedObserver(window); |
+ } |
} |
} |
@@ -480,4 +536,20 @@ void KeyboardController::HideAnimationFinished() { |
proxy_->HideKeyboardContainer(container_.get()); |
} |
+void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { |
+ aura::Window* target_window = GetFrameWindow(window); |
+ if (target_window && |
+ !target_window->HasObserver(window_bounds_observer_.get())) { |
+ target_window->AddObserver(window_bounds_observer_.get()); |
+ } |
+} |
+ |
+void KeyboardController::RemoveBoundsChangedObserver(aura::Window* window) { |
+ aura::Window* target_window = GetFrameWindow(window); |
+ if (target_window && |
+ target_window->HasObserver(window_bounds_observer_.get())) { |
+ target_window->RemoveObserver(window_bounds_observer_.get()); |
+ } |
+} |
+ |
} // namespace keyboard |