void WorkspaceLayoutManager::OnKeyboardBoundsChanging(
const gfx::Rect& new_bounds) {
- aura::Window* root_window = window_->GetRootWindow();
ui::InputMethod* input_method =
- root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
+ root_window_->GetProperty(aura::client::kRootWindowInputMethodKey);
ui::TextInputClient* text_input_client = input_method->GetTextInputClient();
if (!text_input_client)
return;
- aura::Window *window = text_input_client->GetAttachedWindow();
+ aura::Window *window =
+ text_input_client->GetAttachedWindow()->GetToplevelWindow();
if (!window || !window_->Contains(window))
return;
- gfx::Rect window_bounds = ScreenUtil::ConvertRectToScreen(
- window_,
- window->GetTargetBounds());
- gfx::Rect intersect = gfx::IntersectRects(window_bounds, new_bounds);
- int shift = std::min(intersect.height(),
- window->bounds().y() - work_area_in_parent_.y());
- if (shift > 0) {
- gfx::Point origin(window->bounds().x(), window->bounds().y() - shift);
- SetChildBounds(window, gfx::Rect(origin, window->bounds().size()));
+ wm::WindowState* window_state = wm::GetWindowState(window);
+ if (!new_bounds.IsEmpty()) {
+ // Store existing bounds to be restored before resizing for keyboard if it
+ // is not already stored.
+ if (!window_state->HasRestoreBounds())
+ window_state->SaveCurrentBoundsForRestore();
+
+ gfx::Rect window_bounds = ScreenUtil::ConvertRectToScreen(
+ window_,
+ window->GetTargetBounds());
+ int vertical_displacement =
+ std::max(0, window_bounds.bottom() - new_bounds.y());
+ int shift = std::min(vertical_displacement,
+ window_bounds.y() - work_area_in_parent_.y());
+ if (shift > 0) {
+ gfx::Point origin(window_bounds.x(), window_bounds.y() - shift);
+ SetChildBounds(window, gfx::Rect(origin, window_bounds.size()));
+ }
+ } else if (window_state->HasRestoreBounds()) {
+ // Keyboard hidden, restore original bounds if they exist. If the user has
+ // resized or dragged the window in the meantime, WorkspaceWindowResizer
+ // will have cleared the restore bounds and this code will not accidentally
+ // override user intent.
+ window_state->SetAndClearRestoreBounds();
}
}