Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / wm / window_positioner.cc
index 4b0b033..55d2060 100644 (file)
@@ -20,6 +20,7 @@
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/screen.h"
 #include "ui/wm/core/window_animations.h"
+#include "ui/wm/core/window_util.h"
 
 namespace ash {
 
@@ -108,11 +109,33 @@ bool MoveRectToOneSide(const gfx::Rect& work_area,
   return false;
 }
 
-// Move a |window| to a new |bound|. Animate if desired by user.
-// Note: The function will do nothing if the bounds did not change.
-void SetBoundsAnimated(aura::Window* window, const gfx::Rect& bounds) {
-  if (bounds == window->GetTargetBounds())
-    return;
+// Move a |window| to new |bounds|. Animate if desired by user.
+// Moves the transient children of the |window| as well by the same |offset| as
+// the parent |window|.
+void SetBoundsAndOffsetTransientChildren(aura::Window* window,
+                                         const gfx::Rect& bounds,
+                                         const gfx::Rect& work_area,
+                                         const gfx::Vector2d& offset) {
+  aura::Window::Windows transient_children =
+      ::wm::GetTransientChildren(window);
+  for (aura::Window::Windows::iterator iter = transient_children.begin();
+      iter != transient_children.end(); ++iter) {
+    aura::Window* transient_child = *iter;
+    gfx::Rect child_bounds = transient_child->bounds();
+    gfx::Rect new_child_bounds = child_bounds + offset;
+    if ((child_bounds.x() <= work_area.x() &&
+         new_child_bounds.x() <= work_area.x()) ||
+        (child_bounds.right() >= work_area.right() &&
+         new_child_bounds.right() >= work_area.right())) {
+      continue;
+    }
+    if (new_child_bounds.right() > work_area.right())
+      new_child_bounds.set_x(work_area.right() - bounds.width());
+    else if (new_child_bounds.x() < work_area.x())
+      new_child_bounds.set_x(work_area.x());
+    SetBoundsAndOffsetTransientChildren(transient_child,
+                                        new_child_bounds, work_area, offset);
+  }
 
   if (::wm::WindowAnimationsDisabled(window)) {
     window->SetBounds(bounds);
@@ -125,6 +148,18 @@ void SetBoundsAnimated(aura::Window* window, const gfx::Rect& bounds) {
   window->SetBounds(bounds);
 }
 
+// Move a |window| to new |bounds|. Animate if desired by user.
+// Note: The function will do nothing if the bounds did not change.
+void SetBoundsAnimated(aura::Window* window,
+                       const gfx::Rect& bounds,
+                       const gfx::Rect& work_area) {
+  gfx::Rect old_bounds = window->GetTargetBounds();
+  if (bounds == old_bounds)
+    return;
+  gfx::Vector2d offset(bounds.origin() - old_bounds.origin());
+  SetBoundsAndOffsetTransientChildren(window, bounds, work_area, offset);
+}
+
 // Move |window| into the center of the screen - or restore it to the previous
 // position.
 void AutoPlaceSingleWindow(aura::Window* window, bool animated) {
@@ -141,7 +176,7 @@ void AutoPlaceSingleWindow(aura::Window* window, bool animated) {
   }
 
   if (animated)
-    SetBoundsAnimated(window, bounds);
+    SetBoundsAnimated(window, bounds, work_area);
   else
     window->SetBounds(bounds);
 }
@@ -178,6 +213,8 @@ aura::Window* GetReferenceWindow(const aura::Window* root_window,
   aura::Window* found = NULL;
   for (int i = index + windows.size(); i >= 0; i--) {
     aura::Window* window = windows[i % windows.size()];
+    while (::wm::GetTransientParent(window))
+      window = ::wm::GetTransientParent(window);
     if (window != exclude && window->type() == ui::wm::WINDOW_TYPE_NORMAL &&
         window->GetRootWindow() == root_window && window->TargetVisibility() &&
         wm::GetWindowState(window)->window_position_managed()) {
@@ -300,7 +337,7 @@ void WindowPositioner::RearrangeVisibleWindowOnShow(
   if (!UseAutoWindowManager(added_window) ||
       added_window_state->bounds_changed_by_user()) {
     if (added_window_state->minimum_visibility()) {
-      // Guarante minimum visibility within the work area.
+      // Guarantee minimum visibility within the work area.
       gfx::Rect work_area = GetWorkAreaForWindowInParent(added_window);
       gfx::Rect bounds = added_window->bounds();
       gfx::Rect new_bounds = bounds;
@@ -348,7 +385,7 @@ void WindowPositioner::RearrangeVisibleWindowOnShow(
 
       // Push away the other window after remembering its current position.
       if (MoveRectToOneSide(work_area, move_other_right, &other_bounds))
-        SetBoundsAnimated(other_shown_window, other_bounds);
+        SetBoundsAnimated(other_shown_window, other_bounds, work_area);
     }
   }