summaryrefslogtreecommitdiffstats
path: root/chromium/ash/wm/workspace
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/ash/wm/workspace
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/ash/wm/workspace')
-rw-r--r--chromium/ash/wm/workspace/magnetism_matcher.cc194
-rw-r--r--chromium/ash/wm/workspace/magnetism_matcher.h191
-rw-r--r--chromium/ash/wm/workspace/magnetism_matcher_unittest.cc171
-rw-r--r--chromium/ash/wm/workspace/multi_window_resize_controller.cc545
-rw-r--r--chromium/ash/wm/workspace/multi_window_resize_controller.h186
-rw-r--r--chromium/ash/wm/workspace/multi_window_resize_controller_unittest.cc258
-rw-r--r--chromium/ash/wm/workspace/phantom_window_controller.cc214
-rw-r--r--chromium/ash/wm/workspace/phantom_window_controller.h103
-rw-r--r--chromium/ash/wm/workspace/snap_sizer.cc292
-rw-r--r--chromium/ash/wm/workspace/snap_sizer.h140
-rw-r--r--chromium/ash/wm/workspace/snap_sizer_unittest.cc393
-rw-r--r--chromium/ash/wm/workspace/snap_types.h23
-rw-r--r--chromium/ash/wm/workspace/workspace_event_handler.cc180
-rw-r--r--chromium/ash/wm/workspace/workspace_event_handler.h51
-rw-r--r--chromium/ash/wm/workspace/workspace_event_handler_test_helper.cc19
-rw-r--r--chromium/ash/wm/workspace/workspace_event_handler_test_helper.h31
-rw-r--r--chromium/ash/wm/workspace/workspace_event_handler_unittest.cc348
-rw-r--r--chromium/ash/wm/workspace/workspace_layout_manager.cc436
-rw-r--r--chromium/ash/wm/workspace/workspace_layout_manager.h115
-rw-r--r--chromium/ash/wm/workspace/workspace_layout_manager_unittest.cc481
-rw-r--r--chromium/ash/wm/workspace/workspace_types.h27
-rw-r--r--chromium/ash/wm/workspace/workspace_window_resizer.cc1051
-rw-r--r--chromium/ash/wm/workspace/workspace_window_resizer.h236
-rw-r--r--chromium/ash/wm/workspace/workspace_window_resizer_unittest.cc2027
24 files changed, 0 insertions, 7712 deletions
diff --git a/chromium/ash/wm/workspace/magnetism_matcher.cc b/chromium/ash/wm/workspace/magnetism_matcher.cc
deleted file mode 100644
index e7d674b850c..00000000000
--- a/chromium/ash/wm/workspace/magnetism_matcher.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/magnetism_matcher.h"
-
-#include <algorithm>
-#include <cmath>
-
-namespace ash {
-namespace internal {
-
-namespace {
-
-// Returns true if |a| is close enough to |b| that the two edges snap.
-bool IsCloseEnough(int a, int b) {
- return abs(a - b) <= MagnetismMatcher::kMagneticDistance;
-}
-
-// Returns true if the specified SecondaryMagnetismEdge can be matched with a
-// primary edge of |primary|. |edges| is a bitmask of the allowed
-// MagnetismEdges.
-bool CanMatchSecondaryEdge(MagnetismEdge primary,
- SecondaryMagnetismEdge secondary,
- uint32 edges) {
- // Convert |secondary| to a MagnetismEdge so we can compare it to |edges|.
- MagnetismEdge secondary_as_magnetism_edge = MAGNETISM_EDGE_TOP;
- switch (primary) {
- case MAGNETISM_EDGE_TOP:
- case MAGNETISM_EDGE_BOTTOM:
- if (secondary == SECONDARY_MAGNETISM_EDGE_LEADING)
- secondary_as_magnetism_edge = MAGNETISM_EDGE_LEFT;
- else if (secondary == SECONDARY_MAGNETISM_EDGE_TRAILING)
- secondary_as_magnetism_edge = MAGNETISM_EDGE_RIGHT;
- else
- NOTREACHED();
- break;
- case MAGNETISM_EDGE_LEFT:
- case MAGNETISM_EDGE_RIGHT:
- if (secondary == SECONDARY_MAGNETISM_EDGE_LEADING)
- secondary_as_magnetism_edge = MAGNETISM_EDGE_TOP;
- else if (secondary == SECONDARY_MAGNETISM_EDGE_TRAILING)
- secondary_as_magnetism_edge = MAGNETISM_EDGE_BOTTOM;
- else
- NOTREACHED();
- break;
- }
- return (edges & secondary_as_magnetism_edge) != 0;
-}
-
-} // namespace
-
-// MagnetismEdgeMatcher --------------------------------------------------------
-
-MagnetismEdgeMatcher::MagnetismEdgeMatcher(const gfx::Rect& bounds,
- MagnetismEdge edge)
- : bounds_(bounds),
- edge_(edge) {
- ranges_.push_back(GetSecondaryRange(bounds_));
-}
-
-MagnetismEdgeMatcher::~MagnetismEdgeMatcher() {
-}
-
-bool MagnetismEdgeMatcher::ShouldAttach(const gfx::Rect& bounds) {
- if (is_edge_obscured())
- return false;
-
- if (IsCloseEnough(GetPrimaryCoordinate(bounds_, edge_),
- GetPrimaryCoordinate(bounds, FlipEdge(edge_)))) {
- const Range range(GetSecondaryRange(bounds));
- Ranges::const_iterator i =
- std::lower_bound(ranges_.begin(), ranges_.end(), range);
- // Close enough, but only attach if some portion of the edge is visible.
- if ((i != ranges_.begin() && RangesIntersect(*(i - 1), range)) ||
- (i != ranges_.end() && RangesIntersect(*i, range))) {
- return true;
- }
- }
- // NOTE: this checks against the current bounds, we may want to allow some
- // flexibility here.
- const Range primary_range(GetPrimaryRange(bounds));
- if (primary_range.first <= GetPrimaryCoordinate(bounds_, edge_) &&
- primary_range.second >= GetPrimaryCoordinate(bounds_, edge_)) {
- UpdateRanges(GetSecondaryRange(bounds));
- }
- return false;
-}
-
-void MagnetismEdgeMatcher::UpdateRanges(const Range& range) {
- Ranges::const_iterator it =
- std::lower_bound(ranges_.begin(), ranges_.end(), range);
- if (it != ranges_.begin() && RangesIntersect(*(it - 1), range))
- --it;
- if (it == ranges_.end())
- return;
-
- for (size_t i = it - ranges_.begin();
- i < ranges_.size() && RangesIntersect(ranges_[i], range); ) {
- if (range.first <= ranges_[i].first &&
- range.second >= ranges_[i].second) {
- ranges_.erase(ranges_.begin() + i);
- } else if (range.first < ranges_[i].first) {
- DCHECK_GT(range.second, ranges_[i].first);
- ranges_[i] = Range(range.second, ranges_[i].second);
- ++i;
- } else {
- Range existing(ranges_[i]);
- ranges_[i].second = range.first;
- ++i;
- if (existing.second > range.second) {
- ranges_.insert(ranges_.begin() + i,
- Range(range.second, existing.second));
- ++i;
- }
- }
- }
-}
-
-// MagnetismMatcher ------------------------------------------------------------
-
-// static
-const int MagnetismMatcher::kMagneticDistance = 8;
-
-MagnetismMatcher::MagnetismMatcher(const gfx::Rect& bounds, uint32 edges)
- : edges_(edges) {
- if (edges & MAGNETISM_EDGE_TOP)
- matchers_.push_back(new MagnetismEdgeMatcher(bounds, MAGNETISM_EDGE_TOP));
- if (edges & MAGNETISM_EDGE_LEFT)
- matchers_.push_back(new MagnetismEdgeMatcher(bounds, MAGNETISM_EDGE_LEFT));
- if (edges & MAGNETISM_EDGE_BOTTOM) {
- matchers_.push_back(new MagnetismEdgeMatcher(bounds,
- MAGNETISM_EDGE_BOTTOM));
- }
- if (edges & MAGNETISM_EDGE_RIGHT)
- matchers_.push_back(new MagnetismEdgeMatcher(bounds, MAGNETISM_EDGE_RIGHT));
-}
-
-MagnetismMatcher::~MagnetismMatcher() {
-}
-
-bool MagnetismMatcher::ShouldAttach(const gfx::Rect& bounds,
- MatchedEdge* edge) {
- for (size_t i = 0; i < matchers_.size(); ++i) {
- if (matchers_[i]->ShouldAttach(bounds)) {
- edge->primary_edge = matchers_[i]->edge();
- AttachToSecondaryEdge(bounds, edge->primary_edge,
- &(edge->secondary_edge));
- return true;
- }
- }
- return false;
-}
-
-bool MagnetismMatcher::AreEdgesObscured() const {
- for (size_t i = 0; i < matchers_.size(); ++i) {
- if (!matchers_[i]->is_edge_obscured())
- return false;
- }
- return true;
-}
-
-void MagnetismMatcher::AttachToSecondaryEdge(
- const gfx::Rect& bounds,
- MagnetismEdge edge,
- SecondaryMagnetismEdge* secondary_edge) const {
- const gfx::Rect& src_bounds(matchers_[0]->bounds());
- if (edge == MAGNETISM_EDGE_LEFT || edge == MAGNETISM_EDGE_RIGHT) {
- if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_LEADING, edges_) &&
- IsCloseEnough(bounds.y(), src_bounds.y())) {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_LEADING;
- } else if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_TRAILING,
- edges_) &&
- IsCloseEnough(bounds.bottom(), src_bounds.bottom())) {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_TRAILING;
- } else {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_NONE;
- }
- } else {
- if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_LEADING, edges_) &&
- IsCloseEnough(bounds.x(), src_bounds.x())) {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_LEADING;
- } else if (CanMatchSecondaryEdge(edge, SECONDARY_MAGNETISM_EDGE_TRAILING,
- edges_) &&
- IsCloseEnough(bounds.right(), src_bounds.right())) {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_TRAILING;
- } else {
- *secondary_edge = SECONDARY_MAGNETISM_EDGE_NONE;
- }
- }
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/magnetism_matcher.h b/chromium/ash/wm/workspace/magnetism_matcher.h
deleted file mode 100644
index ff1f52810e9..00000000000
--- a/chromium/ash/wm/workspace/magnetism_matcher.h
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_MAGNETISM_MATCHER_H_
-#define ASH_WM_WORKSPACE_MAGNETISM_MATCHER_H_
-
-#include <utility>
-#include <vector>
-
-#include "ash/ash_export.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "ui/gfx/rect.h"
-
-namespace ash {
-namespace internal {
-
-enum MagnetismEdge {
- MAGNETISM_EDGE_TOP = 1 << 0,
- MAGNETISM_EDGE_LEFT = 1 << 1,
- MAGNETISM_EDGE_BOTTOM = 1 << 2,
- MAGNETISM_EDGE_RIGHT = 1 << 3,
-};
-
-const uint32 kAllMagnetismEdges =
- MAGNETISM_EDGE_TOP | MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_BOTTOM |
- MAGNETISM_EDGE_RIGHT;
-
-// MagnetismEdgeMatcher is used for matching a particular edge of a window. You
-// shouldn't need to use this directly, instead use MagnetismMatcher which takes
-// care of all edges.
-// MagnetismEdgeMatcher maintains a range of the visible portions of the
-// edge. As ShouldAttach() is invoked the visible range is updated.
-class MagnetismEdgeMatcher {
- public:
- MagnetismEdgeMatcher(const gfx::Rect& bounds, MagnetismEdge edge);
- ~MagnetismEdgeMatcher();
-
- MagnetismEdge edge() const { return edge_; }
- const gfx::Rect& bounds() const { return bounds_; }
-
- // Returns true if the edge is completely obscured. If true ShouldAttach()
- // will return false.
- bool is_edge_obscured() const { return ranges_.empty(); }
-
- // Returns true if should attach to the specified bounds.
- bool ShouldAttach(const gfx::Rect& bounds);
-
- private:
- typedef std::pair<int,int> Range;
- typedef std::vector<Range> Ranges;
-
- // Removes |range| from |ranges_|.
- void UpdateRanges(const Range& range);
-
- static int GetPrimaryCoordinate(const gfx::Rect& bounds, MagnetismEdge edge) {
- switch (edge) {
- case MAGNETISM_EDGE_TOP:
- return bounds.y();
- case MAGNETISM_EDGE_LEFT:
- return bounds.x();
- case MAGNETISM_EDGE_BOTTOM:
- return bounds.bottom();
- case MAGNETISM_EDGE_RIGHT:
- return bounds.right();
- }
- NOTREACHED();
- return 0;
- }
-
- static MagnetismEdge FlipEdge(MagnetismEdge edge) {
- switch (edge) {
- case MAGNETISM_EDGE_TOP:
- return MAGNETISM_EDGE_BOTTOM;
- case MAGNETISM_EDGE_BOTTOM:
- return MAGNETISM_EDGE_TOP;
- case MAGNETISM_EDGE_LEFT:
- return MAGNETISM_EDGE_RIGHT;
- case MAGNETISM_EDGE_RIGHT:
- return MAGNETISM_EDGE_LEFT;
- }
- NOTREACHED();
- return MAGNETISM_EDGE_LEFT;
- }
-
- Range GetPrimaryRange(const gfx::Rect& bounds) const {
- switch (edge_) {
- case MAGNETISM_EDGE_TOP:
- case MAGNETISM_EDGE_BOTTOM:
- return Range(bounds.y(), bounds.bottom());
- case MAGNETISM_EDGE_LEFT:
- case MAGNETISM_EDGE_RIGHT:
- return Range(bounds.x(), bounds.right());
- }
- NOTREACHED();
- return Range();
- }
-
- Range GetSecondaryRange(const gfx::Rect& bounds) const {
- switch (edge_) {
- case MAGNETISM_EDGE_TOP:
- case MAGNETISM_EDGE_BOTTOM:
- return Range(bounds.x(), bounds.right());
- case MAGNETISM_EDGE_LEFT:
- case MAGNETISM_EDGE_RIGHT:
- return Range(bounds.y(), bounds.bottom());
- }
- NOTREACHED();
- return Range();
- }
-
- static bool RangesIntersect(const Range& r1, const Range& r2) {
- return r2.first < r1.second && r2.second > r1.first;
- }
-
- // The bounds of window.
- const gfx::Rect bounds_;
-
- // The edge this matcher checks.
- const MagnetismEdge edge_;
-
- // Visible ranges of the edge. Initialized with GetSecondaryRange() and
- // updated as ShouldAttach() is invoked. When empty the edge is completely
- // obscured by other bounds.
- Ranges ranges_;
-
- DISALLOW_COPY_AND_ASSIGN(MagnetismEdgeMatcher);
-};
-
-enum SecondaryMagnetismEdge {
- SECONDARY_MAGNETISM_EDGE_LEADING,
- SECONDARY_MAGNETISM_EDGE_TRAILING,
- SECONDARY_MAGNETISM_EDGE_NONE,
-};
-
-// Used to identify a matched edge. |primary_edge| is relative to the source and
-// indicates the edge the two are to share. For example, if |primary_edge| is
-// MAGNETISM_EDGE_RIGHT then the right edge of the source should snap to to the
-// left edge of the target. |secondary_edge| indicates one of the edges along
-// the opposite axis should should also be aligned. For example, if
-// |primary_edge| is MAGNETISM_EDGE_RIGHT and |secondary_edge| is
-// SECONDARY_MAGNETISM_EDGE_LEADING then the source should snap to the left top
-// corner of the target.
-struct MatchedEdge {
- MagnetismEdge primary_edge;
- SecondaryMagnetismEdge secondary_edge;
-};
-
-// MagnetismMatcher is used to test if a window should snap to another window.
-// To use MagnetismMatcher do the following:
-// . Create it with the bounds of the window being dragged.
-// . Iterate over the child windows checking if the window being dragged should
-// attach to it using ShouldAttach().
-// . Use AreEdgesObscured() to test if no other windows can match (because all
-// edges are completely obscured).
-class ASH_EXPORT MagnetismMatcher {
- public:
- static const int kMagneticDistance;
-
- // |edges| is a bitmask of MagnetismEdges to match against.
- MagnetismMatcher(const gfx::Rect& bounds, uint32 edges);
- ~MagnetismMatcher();
-
- // Returns true if |bounds| is close enough to the initial bounds that the two
- // should be attached. If true is returned |edge| is set to indicates how the
- // two should snap together. See description of MatchedEdge for details.
- bool ShouldAttach(const gfx::Rect& bounds, MatchedEdge* edge);
-
- // Returns true if no other matches are possible.
- bool AreEdgesObscured() const;
-
- private:
- // Sets |secondary_edge| based on whether the secondary edges should snap.
- void AttachToSecondaryEdge(const gfx::Rect& bounds,
- MagnetismEdge edge,
- SecondaryMagnetismEdge* secondary_edge) const;
-
- // The edges to match against.
- const int32 edges_;
-
- ScopedVector<MagnetismEdgeMatcher> matchers_;
-
- DISALLOW_COPY_AND_ASSIGN(MagnetismMatcher);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_MAGNETISM_MATCHER_H_
diff --git a/chromium/ash/wm/workspace/magnetism_matcher_unittest.cc b/chromium/ash/wm/workspace/magnetism_matcher_unittest.cc
deleted file mode 100644
index 054622ff572..00000000000
--- a/chromium/ash/wm/workspace/magnetism_matcher_unittest.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/magnetism_matcher.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace ash {
-namespace internal {
-
-// Trivial test case verifying assertions on left edge.
-TEST(MagnetismMatcherTest, TrivialLeft) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 50, 60);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- EXPECT_FALSE(matcher.AreEdgesObscured());
- MatchedEdge edge;
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - distance - 10,
- initial_bounds.y() - distance - 10, 2, 3), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - 2, initial_bounds.y(), 1, 1),
- &edge));
- EXPECT_EQ(MAGNETISM_EDGE_LEFT, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_LEADING, edge.secondary_edge);
-
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - 2,
- initial_bounds.y() + distance + 1 , 1, 1),
- &edge));
- EXPECT_EQ(MAGNETISM_EDGE_LEFT, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-}
-
-// Trivial test case verifying assertions on bottom edge.
-TEST(MagnetismMatcherTest, TrivialBottom) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 50, 60);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- EXPECT_FALSE(matcher.AreEdgesObscured());
- MatchedEdge edge;
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - distance - 10,
- initial_bounds.y() - distance - 10, 2, 3), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - 2,
- initial_bounds.bottom() + 4, 10, 1), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_BOTTOM, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_LEADING, edge.secondary_edge);
-
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() + distance + 1,
- initial_bounds.bottom() + 4, 10, 1), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_BOTTOM, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.right() - 10 - 1,
- initial_bounds.bottom() + 4, 10, 1), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_BOTTOM, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_TRAILING, edge.secondary_edge);
-}
-
-// Verifies we don't match an obscured corner.
-TEST(MagnetismMatcherTest, ObscureLeading) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 150, 160);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- MatchedEdge edge;
- // Overlap with the upper right corner.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.right() - distance * 2,
- initial_bounds.y() - distance - 2,
- distance * 3,
- (distance + 2) * 2), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- // Verify doesn't match the following which is obscured by first.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.right() + 1,
- initial_bounds.y(),
- distance,
- 5), &edge));
- // Should match the following which extends into non-overlapping region.
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.right() + 1,
- initial_bounds.y() + distance + 1,
- distance,
- 15), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_RIGHT, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-}
-
-// Verifies obscuring one side doesn't obscure the other.
-TEST(MagnetismMatcherTest, DontObscureOtherSide) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 150, 160);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- MatchedEdge edge;
- // Overlap with the left side.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - distance + 1,
- initial_bounds.y() + 2,
- distance * 2 + 2,
- initial_bounds.height() + distance * 4), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- // Should match the right side since it isn't obscured.
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.right() - 1,
- initial_bounds.y() + distance + 1,
- distance,
- 5), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_RIGHT, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-}
-
-// Verifies we don't match an obscured center.
-TEST(MagnetismMatcherTest, ObscureCenter) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 150, 160);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- MatchedEdge edge;
- // Overlap with the center bottom edge.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(100, initial_bounds.bottom() - distance - 2,
- 20,
- (distance + 2) * 2), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- // Verify doesn't match the following which is obscured by first.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(110, initial_bounds.bottom() + 1,
- 10, 5), &edge));
- // Should match the following which extends into non-overlapping region.
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(90,
- initial_bounds.bottom() + 1,
- 10, 5), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_BOTTOM, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-}
-
-// Verifies we don't match an obscured trailing edge.
-TEST(MagnetismMatcherTest, ObscureTrailing) {
- const int distance = MagnetismMatcher::kMagneticDistance;
- const gfx::Rect initial_bounds(20, 10, 150, 160);
- MagnetismMatcher matcher(initial_bounds, kAllMagnetismEdges);
- MatchedEdge edge;
- // Overlap with the trailing left edge.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - distance - 2,
- 150,
- (distance + 2) * 2,
- 50), &edge));
- EXPECT_FALSE(matcher.AreEdgesObscured());
- // Verify doesn't match the following which is obscured by first.
- EXPECT_FALSE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - 4,
- 160, 3, 20), &edge));
- // Should match the following which extends into non-overlapping region.
- EXPECT_TRUE(matcher.ShouldAttach(
- gfx::Rect(initial_bounds.x() - 4,
- 140, 3, 20), &edge));
- EXPECT_EQ(MAGNETISM_EDGE_LEFT, edge.primary_edge);
- EXPECT_EQ(SECONDARY_MAGNETISM_EDGE_NONE, edge.secondary_edge);
-}
-
-} // namespace internal
-} // namespace ash
-
diff --git a/chromium/ash/wm/workspace/multi_window_resize_controller.cc b/chromium/ash/wm/workspace/multi_window_resize_controller.cc
deleted file mode 100644
index 597acbf88ec..00000000000
--- a/chromium/ash/wm/workspace/multi_window_resize_controller.cc
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/multi_window_resize_controller.h"
-
-#include "ash/screen_ash.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/coordinate_conversion.h"
-#include "ash/wm/window_animations.h"
-#include "ash/wm/workspace/workspace_event_handler.h"
-#include "ash/wm/workspace/workspace_window_resizer.h"
-#include "grit/ash_resources.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/base/hit_test.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/corewm/compound_event_filter.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-
-using aura::Window;
-
-namespace ash {
-namespace internal {
-
-namespace {
-
-// Delay before showing.
-const int kShowDelayMS = 400;
-
-// Delay before hiding.
-const int kHideDelayMS = 500;
-
-// Padding from the bottom/right edge the resize widget is shown at.
-const int kResizeWidgetPadding = 15;
-
-bool ContainsX(Window* window, int x) {
- return window->bounds().x() <= x && window->bounds().right() >= x;
-}
-
-bool ContainsY(Window* window, int y) {
- return window->bounds().y() <= y && window->bounds().bottom() >= y;
-}
-
-bool Intersects(int x1, int max_1, int x2, int max_2) {
- return x2 <= max_1 && max_2 > x1;
-}
-
-} // namespace
-
-// View contained in the widget. Passes along mouse events to the
-// MultiWindowResizeController so that it can start/stop the resize loop.
-class MultiWindowResizeController::ResizeView : public views::View {
- public:
- explicit ResizeView(MultiWindowResizeController* controller,
- Direction direction)
- : controller_(controller),
- direction_(direction),
- image_(NULL) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- int image_id =
- direction == TOP_BOTTOM ? IDR_AURA_MULTI_WINDOW_RESIZE_H :
- IDR_AURA_MULTI_WINDOW_RESIZE_V;
- image_ = rb.GetImageNamed(image_id).ToImageSkia();
- }
-
- // views::View overrides:
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- return gfx::Size(image_->width(), image_->height());
- }
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- canvas->DrawImageInt(*image_, 0, 0);
- }
- virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
- gfx::Point location(event.location());
- views::View::ConvertPointToScreen(this, &location);
- controller_->StartResize(location);
- return true;
- }
- virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
- gfx::Point location(event.location());
- views::View::ConvertPointToScreen(this, &location);
- controller_->Resize(location, event.flags());
- return true;
- }
- virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
- controller_->CompleteResize(event.flags());
- }
- virtual void OnMouseCaptureLost() OVERRIDE {
- controller_->CancelResize();
- }
- virtual gfx::NativeCursor GetCursor(
- const ui::MouseEvent& event) OVERRIDE {
- int component = (direction_ == LEFT_RIGHT) ? HTRIGHT : HTBOTTOM;
- return views::corewm::CompoundEventFilter::CursorForWindowComponent(
- component);
- }
-
- private:
- MultiWindowResizeController* controller_;
- const Direction direction_;
- const gfx::ImageSkia* image_;
-
- DISALLOW_COPY_AND_ASSIGN(ResizeView);
-};
-
-// MouseWatcherHost implementation for MultiWindowResizeController. Forwards
-// Contains() to MultiWindowResizeController.
-class MultiWindowResizeController::ResizeMouseWatcherHost :
- public views::MouseWatcherHost {
- public:
- ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {}
-
- // MouseWatcherHost overrides:
- virtual bool Contains(const gfx::Point& point_in_screen,
- MouseEventType type) OVERRIDE {
- return host_->IsOverWindows(point_in_screen);
- }
-
- private:
- MultiWindowResizeController* host_;
-
- DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost);
-};
-
-MultiWindowResizeController::ResizeWindows::ResizeWindows()
- : window1(NULL),
- window2(NULL),
- direction(TOP_BOTTOM){
-}
-
-MultiWindowResizeController::ResizeWindows::~ResizeWindows() {
-}
-
-bool MultiWindowResizeController::ResizeWindows::Equals(
- const ResizeWindows& other) const {
- return window1 == other.window1 &&
- window2 == other.window2 &&
- direction == other.direction;
-}
-
-MultiWindowResizeController::MultiWindowResizeController() {
-}
-
-MultiWindowResizeController::~MultiWindowResizeController() {
- window_resizer_.reset();
- Hide();
-}
-
-void MultiWindowResizeController::Show(Window* window,
- int component,
- const gfx::Point& point_in_window) {
- // When the resize widget is showing we ignore Show() requests. Instead we
- // only care about mouse movements from MouseWatcher. This is necessary as
- // WorkspaceEventHandler only sees mouse movements over the windows, not all
- // windows or over the desktop.
- if (resize_widget_)
- return;
-
- ResizeWindows windows(DetermineWindows(window, component, point_in_window));
- if (IsShowing()) {
- if (windows_.Equals(windows))
- return; // Over the same windows.
- DelayedHide();
- }
-
- if (!windows.is_valid())
- return;
- Hide();
- windows_ = windows;
- windows_.window1->AddObserver(this);
- windows_.window2->AddObserver(this);
- show_location_in_parent_ = point_in_window;
- Window::ConvertPointToTarget(
- window, window->parent(), &show_location_in_parent_);
- if (show_timer_.IsRunning())
- return;
- show_timer_.Start(
- FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS),
- this, &MultiWindowResizeController::ShowIfValidMouseLocation);
-}
-
-void MultiWindowResizeController::Hide() {
- hide_timer_.Stop();
- if (window_resizer_)
- return; // Ignore hides while actively resizing.
-
- if (windows_.window1) {
- windows_.window1->RemoveObserver(this);
- windows_.window1 = NULL;
- }
- if (windows_.window2) {
- windows_.window2->RemoveObserver(this);
- windows_.window2 = NULL;
- }
-
- show_timer_.Stop();
-
- if (!resize_widget_)
- return;
-
- for (size_t i = 0; i < windows_.other_windows.size(); ++i)
- windows_.other_windows[i]->RemoveObserver(this);
- mouse_watcher_.reset();
- resize_widget_.reset();
- windows_ = ResizeWindows();
-}
-
-void MultiWindowResizeController::MouseMovedOutOfHost() {
- Hide();
-}
-
-void MultiWindowResizeController::OnWindowDestroying(
- aura::Window* window) {
- // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing.
- window_resizer_.reset();
- Hide();
-}
-
-MultiWindowResizeController::ResizeWindows
-MultiWindowResizeController::DetermineWindowsFromScreenPoint(
- aura::Window* window) const {
- gfx::Point mouse_location(
- gfx::Screen::GetScreenFor(window)->GetCursorScreenPoint());
- wm::ConvertPointFromScreen(window, &mouse_location);
- const int component =
- window->delegate()->GetNonClientComponent(mouse_location);
- return DetermineWindows(window, component, mouse_location);
-}
-
-MultiWindowResizeController::ResizeWindows
-MultiWindowResizeController::DetermineWindows(
- Window* window,
- int window_component,
- const gfx::Point& point) const {
- ResizeWindows result;
- gfx::Point point_in_parent(point);
- Window::ConvertPointToTarget(window, window->parent(), &point_in_parent);
- switch (window_component) {
- case HTRIGHT:
- result.direction = LEFT_RIGHT;
- result.window1 = window;
- result.window2 = FindWindowByEdge(
- window, HTLEFT, window->bounds().right(), point_in_parent.y());
- break;
- case HTLEFT:
- result.direction = LEFT_RIGHT;
- result.window1 = FindWindowByEdge(
- window, HTRIGHT, window->bounds().x(), point_in_parent.y());
- result.window2 = window;
- break;
- case HTTOP:
- result.direction = TOP_BOTTOM;
- result.window1 = FindWindowByEdge(
- window, HTBOTTOM, point_in_parent.x(), window->bounds().y());
- result.window2 = window;
- break;
- case HTBOTTOM:
- result.direction = TOP_BOTTOM;
- result.window1 = window;
- result.window2 = FindWindowByEdge(
- window, HTTOP, point_in_parent.x(), window->bounds().bottom());
- break;
- default:
- break;
- }
- return result;
-}
-
-Window* MultiWindowResizeController::FindWindowByEdge(
- Window* window_to_ignore,
- int edge_want,
- int x,
- int y) const {
- Window* parent = window_to_ignore->parent();
- const Window::Windows& windows(parent->children());
- for (Window::Windows::const_reverse_iterator i = windows.rbegin();
- i != windows.rend(); ++i) {
- Window* window = *i;
- if (window == window_to_ignore || !window->IsVisible())
- continue;
- switch (edge_want) {
- case HTLEFT:
- if (ContainsY(window, y) && window->bounds().x() == x)
- return window;
- break;
- case HTRIGHT:
- if (ContainsY(window, y) && window->bounds().right() == x)
- return window;
- break;
- case HTTOP:
- if (ContainsX(window, x) && window->bounds().y() == y)
- return window;
- break;
- case HTBOTTOM:
- if (ContainsX(window, x) && window->bounds().bottom() == y)
- return window;
- break;
- default:
- NOTREACHED();
- }
- // Window doesn't contain the edge, but if window contains |point|
- // it's obscuring any other window that could be at the location.
- if (window->bounds().Contains(x, y))
- return NULL;
- }
- return NULL;
-}
-
-aura::Window* MultiWindowResizeController::FindWindowTouching(
- aura::Window* window,
- Direction direction) const {
- int right = window->bounds().right();
- int bottom = window->bounds().bottom();
- Window* parent = window->parent();
- const Window::Windows& windows(parent->children());
- for (Window::Windows::const_reverse_iterator i = windows.rbegin();
- i != windows.rend(); ++i) {
- Window* other = *i;
- if (other == window || !other->IsVisible())
- continue;
- switch (direction) {
- case TOP_BOTTOM:
- if (other->bounds().y() == bottom &&
- Intersects(other->bounds().x(), other->bounds().right(),
- window->bounds().x(), window->bounds().right())) {
- return other;
- }
- break;
- case LEFT_RIGHT:
- if (other->bounds().x() == right &&
- Intersects(other->bounds().y(), other->bounds().bottom(),
- window->bounds().y(), window->bounds().bottom())) {
- return other;
- }
- break;
- default:
- NOTREACHED();
- }
- }
- return NULL;
-}
-
-void MultiWindowResizeController::FindWindowsTouching(
- aura::Window* start,
- Direction direction,
- std::vector<aura::Window*>* others) const {
- while (start) {
- start = FindWindowTouching(start, direction);
- if (start)
- others->push_back(start);
- }
-}
-
-void MultiWindowResizeController::DelayedHide() {
- if (hide_timer_.IsRunning())
- return;
-
- hide_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kHideDelayMS),
- this, &MultiWindowResizeController::Hide);
-}
-
-void MultiWindowResizeController::ShowIfValidMouseLocation() {
- if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) ||
- DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) {
- ShowNow();
- } else {
- Hide();
- }
-}
-
-void MultiWindowResizeController::ShowNow() {
- DCHECK(!resize_widget_.get());
- DCHECK(windows_.is_valid());
- show_timer_.Stop();
- resize_widget_.reset(new views::Widget);
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = Shell::GetContainer(
- Shell::GetTargetRootWindow(),
- internal::kShellWindowId_AlwaysOnTopContainer);
- params.can_activate = false;
- ResizeView* view = new ResizeView(this, windows_.direction);
- resize_widget_->set_focus_on_creation(false);
- resize_widget_->Init(params);
- views::corewm::SetWindowVisibilityAnimationType(
- resize_widget_->GetNativeWindow(),
- views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
- resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController");
- resize_widget_->SetContentsView(view);
- show_bounds_in_screen_ = ScreenAsh::ConvertRectToScreen(
- windows_.window1->parent(),
- CalculateResizeWidgetBounds(show_location_in_parent_));
- resize_widget_->SetBounds(show_bounds_in_screen_);
- resize_widget_->Show();
- mouse_watcher_.reset(new views::MouseWatcher(
- new ResizeMouseWatcherHost(this),
- this));
- mouse_watcher_->set_notify_on_exit_time(
- base::TimeDelta::FromMilliseconds(kHideDelayMS));
- mouse_watcher_->Start();
-}
-
-bool MultiWindowResizeController::IsShowing() const {
- return resize_widget_.get() || show_timer_.IsRunning();
-}
-
-void MultiWindowResizeController::StartResize(
- const gfx::Point& location_in_screen) {
- DCHECK(!window_resizer_.get());
- DCHECK(windows_.is_valid());
- hide_timer_.Stop();
- gfx::Point location_in_parent(location_in_screen);
- aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())->
- ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent);
- std::vector<aura::Window*> windows;
- windows.push_back(windows_.window2);
- DCHECK(windows_.other_windows.empty());
- FindWindowsTouching(windows_.window2, windows_.direction,
- &windows_.other_windows);
- for (size_t i = 0; i < windows_.other_windows.size(); ++i) {
- windows_.other_windows[i]->AddObserver(this);
- windows.push_back(windows_.other_windows[i]);
- }
- int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM;
- window_resizer_.reset(WorkspaceWindowResizer::Create(
- windows_.window1,
- location_in_parent,
- component,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE,
- windows));
-}
-
-void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen,
- int event_flags) {
- gfx::Point location_in_parent(location_in_screen);
- aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())->
- ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent);
- window_resizer_->Drag(location_in_parent, event_flags);
- gfx::Rect bounds = ScreenAsh::ConvertRectToScreen(
- windows_.window1->parent(),
- CalculateResizeWidgetBounds(location_in_parent));
-
- if (windows_.direction == LEFT_RIGHT)
- bounds.set_y(show_bounds_in_screen_.y());
- else
- bounds.set_x(show_bounds_in_screen_.x());
- resize_widget_->SetBounds(bounds);
-}
-
-void MultiWindowResizeController::CompleteResize(int event_flags) {
- window_resizer_->CompleteDrag(event_flags);
- window_resizer_.reset();
-
- // Mouse may still be over resizer, if not hide.
- gfx::Point screen_loc = Shell::GetScreen()->GetCursorScreenPoint();
- if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) {
- Hide();
- } else {
- // If the mouse is over the resizer we need to remove observers on any of
- // the |other_windows|. If we start another resize we'll recalculate the
- // |other_windows| and invoke AddObserver() as necessary.
- for (size_t i = 0; i < windows_.other_windows.size(); ++i)
- windows_.other_windows[i]->RemoveObserver(this);
- windows_.other_windows.clear();
- }
-}
-
-void MultiWindowResizeController::CancelResize() {
- if (!window_resizer_)
- return; // Happens if window was destroyed and we nuked the WindowResizer.
- window_resizer_->RevertDrag();
- window_resizer_.reset();
- Hide();
-}
-
-gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds(
- const gfx::Point& location_in_parent) const {
- gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize();
- int x = 0, y = 0;
- if (windows_.direction == LEFT_RIGHT) {
- x = windows_.window1->bounds().right() - pref.width() / 2;
- y = location_in_parent.y() + kResizeWidgetPadding;
- if (y + pref.height() / 2 > windows_.window1->bounds().bottom() &&
- y + pref.height() / 2 > windows_.window2->bounds().bottom()) {
- y = location_in_parent.y() - kResizeWidgetPadding - pref.height();
- }
- } else {
- x = location_in_parent.x() + kResizeWidgetPadding;
- if (x + pref.height() / 2 > windows_.window1->bounds().right() &&
- x + pref.height() / 2 > windows_.window2->bounds().right()) {
- x = location_in_parent.x() - kResizeWidgetPadding - pref.width();
- }
- y = windows_.window1->bounds().bottom() - pref.height() / 2;
- }
- return gfx::Rect(x, y, pref.width(), pref.height());
-}
-
-bool MultiWindowResizeController::IsOverWindows(
- const gfx::Point& location_in_screen) const {
- if (window_resizer_)
- return true; // Ignore hides while actively resizing.
-
- if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen))
- return true;
-
- int hit1, hit2;
- if (windows_.direction == TOP_BOTTOM) {
- hit1 = HTBOTTOM;
- hit2 = HTTOP;
- } else {
- hit1 = HTRIGHT;
- hit2 = HTLEFT;
- }
-
- return IsOverWindow(windows_.window1, location_in_screen, hit1) ||
- IsOverWindow(windows_.window2, location_in_screen, hit2);
-}
-
-bool MultiWindowResizeController::IsOverWindow(
- aura::Window* window,
- const gfx::Point& location_in_screen,
- int component) const {
- if (!window->delegate())
- return false;
-
- gfx::Point window_loc(location_in_screen);
- aura::Window::ConvertPointToTarget(
- window->GetRootWindow(), window, &window_loc);
- return window->HitTest(window_loc) &&
- window->delegate()->GetNonClientComponent(window_loc) == component;
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/multi_window_resize_controller.h b/chromium/ash/wm/workspace/multi_window_resize_controller.h
deleted file mode 100644
index 02eeb2511a4..00000000000
--- a/chromium/ash/wm/workspace/multi_window_resize_controller.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_
-#define ASH_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_
-
-#include <vector>
-
-#include "ash/ash_export.h"
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
-#include "ui/aura/window_observer.h"
-#include "ui/gfx/rect.h"
-#include "ui/views/mouse_watcher.h"
-
-namespace aura {
-class Window;
-}
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-namespace internal {
-
-class MultiWindowResizeControllerTest;
-class WorkspaceWindowResizer;
-
-// Two directions resizes happen in.
-enum Direction {
- TOP_BOTTOM,
- LEFT_RIGHT,
-};
-
-// MultiWindowResizeController is responsible for determining and showing a
-// widget that allows resizing multiple windows at the same time.
-// MultiWindowResizeController is driven by WorkspaceEventFilter.
-class ASH_EXPORT MultiWindowResizeController :
- public views::MouseWatcherListener, public aura::WindowObserver {
- public:
- MultiWindowResizeController();
- virtual ~MultiWindowResizeController();
-
- // If necessary, shows the resize widget. |window| is the window the mouse
- // is over, |component| the edge and |point| the location of the mouse.
- void Show(aura::Window* window, int component, const gfx::Point& point);
-
- // Hides the resize widget.
- void Hide();
-
- // MouseWatcherListenre overrides:
- virtual void MouseMovedOutOfHost() OVERRIDE;
-
- // WindowObserver overrides:
- virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
-
- private:
- friend class MultiWindowResizeControllerTest;
-
- // Used to track the two resizable windows and direction.
- struct ResizeWindows {
- ResizeWindows();
- ~ResizeWindows();
-
- // Returns true if |other| equals this ResizeWindows. This does *not*
- // consider the windows in |other_windows|.
- bool Equals(const ResizeWindows& other) const;
-
- // Returns true if this ResizeWindows is valid.
- bool is_valid() const { return window1 && window2; }
-
- // The left/top window to resize.
- aura::Window* window1;
-
- // Other window to resize.
- aura::Window* window2;
-
- // Direction
- Direction direction;
-
- // Windows after |window2| that are to be resized. Determined at the time
- // the resize starts.
- std::vector<aura::Window*> other_windows;
- };
-
- class ResizeMouseWatcherHost;
- class ResizeView;
-
- // Returns a ResizeWindows based on the specified arguments. Use is_valid()
- // to test if the return value is a valid multi window resize location.
- ResizeWindows DetermineWindows(aura::Window* window,
- int window_component,
- const gfx::Point& point) const;
-
- // Variant of DetermineWindows() that uses the current location of the mouse
- // to determine the resize windows.
- ResizeWindows DetermineWindowsFromScreenPoint(aura::Window* window) const;
-
- // Finds a window by edge (one of the constants HitTestCompat.
- aura::Window* FindWindowByEdge(aura::Window* window_to_ignore,
- int edge_want,
- int x,
- int y) const;
-
- // Returns the first window touching |window|.
- aura::Window* FindWindowTouching(aura::Window* window,
- Direction direction) const;
-
- // Places any windows touching |start| into |others|.
- void FindWindowsTouching(aura::Window* start,
- Direction direction,
- std::vector<aura::Window*>* others) const;
-
- // Hides the window after a delay.
- void DelayedHide();
-
- // Shows the resizer if the mouse is still at a valid location. This is called
- // from the |show_timer_|.
- void ShowIfValidMouseLocation();
-
- // Shows the widget immediately.
- void ShowNow();
-
- // Returns true if the widget is showing.
- bool IsShowing() const;
-
- // Initiates a resize.
- void StartResize(const gfx::Point& location_in_screen);
-
- // Resizes to the new location.
- void Resize(const gfx::Point& location_in_screen, int event_flags);
-
- // Completes the resize.
- void CompleteResize(int event_flags);
-
- // Cancels the resize.
- void CancelResize();
-
- // Returns the bounds for the resize widget.
- gfx::Rect CalculateResizeWidgetBounds(
- const gfx::Point& location_in_parent) const;
-
- // Returns true if |location_in_screen| is over the resize windows
- // (or the resize widget itself).
- bool IsOverWindows(const gfx::Point& location_in_screen) const;
-
- // Returns true if |location_in_screen| is over |window|.
- bool IsOverWindow(aura::Window* window,
- const gfx::Point& location_in_screen,
- int component) const;
-
- // Windows and direction to resize.
- ResizeWindows windows_;
-
- // Timer before hiding.
- base::OneShotTimer<MultiWindowResizeController> hide_timer_;
-
- // Timer used before showing.
- base::OneShotTimer<MultiWindowResizeController> show_timer_;
-
- scoped_ptr<views::Widget> resize_widget_;
-
- // If non-null we're in a resize loop.
- scoped_ptr<WorkspaceWindowResizer> window_resizer_;
-
- // Mouse coordinate passed to Show() in container's coodinates.
- gfx::Point show_location_in_parent_;
-
- // Bounds the widget was last shown at in screen coordinates.
- gfx::Rect show_bounds_in_screen_;
-
- // Used to detect whether the mouse is over the windows. While
- // |resize_widget_| is non-NULL (ie the widget is showing) we ignore calls
- // to Show().
- scoped_ptr<views::MouseWatcher> mouse_watcher_;
-
- DISALLOW_COPY_AND_ASSIGN(MultiWindowResizeController);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_MULTI_WINDOW_RESIZE_CONTROLLER_H_
diff --git a/chromium/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/chromium/ash/wm/workspace/multi_window_resize_controller_unittest.cc
deleted file mode 100644
index a4756aa729d..00000000000
--- a/chromium/ash/wm/workspace/multi_window_resize_controller_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/multi_window_resize_controller.h"
-
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/test/shell_test_api.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace_controller.h"
-#include "ash/wm/workspace_controller_test_helper.h"
-#include "ash/wm/workspace/workspace_event_handler_test_helper.h"
-#include "ui/aura/test/event_generator.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window.h"
-#include "ui/base/hit_test.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
-
-namespace ash {
-namespace internal {
-
-class MultiWindowResizeControllerTest : public test::AshTestBase {
- public:
- MultiWindowResizeControllerTest() : resize_controller_(NULL) {}
- virtual ~MultiWindowResizeControllerTest() {}
-
- virtual void SetUp() OVERRIDE {
- test::AshTestBase::SetUp();
- WorkspaceController* wc =
- test::ShellTestApi(Shell::GetInstance()).workspace_controller();
- WorkspaceEventHandler* event_handler =
- WorkspaceControllerTestHelper(wc).GetEventHandler();
- resize_controller_ = WorkspaceEventHandlerTestHelper(event_handler).
- resize_controller();
- }
-
- protected:
- aura::Window* CreateTestWindow(aura::WindowDelegate* delegate,
- const gfx::Rect& bounds) {
- aura::Window* window = new aura::Window(delegate);
- window->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window->Init(ui::LAYER_TEXTURED);
- ParentWindowInPrimaryRootWindow(window);
- window->SetBounds(bounds);
- window->Show();
- return window;
- }
-
- void ShowNow() {
- resize_controller_->ShowNow();
- }
-
- bool IsShowing() {
- return resize_controller_->IsShowing();
- }
-
- bool HasPendingShow() {
- return resize_controller_->show_timer_.IsRunning();
- }
-
- bool HasPendingHide() {
- return resize_controller_->hide_timer_.IsRunning();
- }
-
- void Hide() {
- resize_controller_->Hide();
- }
-
- bool HasTarget(aura::Window* window) {
- if (!resize_controller_->windows_.is_valid())
- return false;
- if ((resize_controller_->windows_.window1 == window ||
- resize_controller_->windows_.window2 == window))
- return true;
- for (size_t i = 0;
- i < resize_controller_->windows_.other_windows.size(); ++i) {
- if (resize_controller_->windows_.other_windows[i] == window)
- return true;
- }
- return false;
- }
-
- bool IsOverWindows(const gfx::Point& loc) {
- return resize_controller_->IsOverWindows(loc);
- }
-
- views::Widget* resize_widget() {
- return resize_controller_->resize_widget_.get();
- }
-
- MultiWindowResizeController* resize_controller_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MultiWindowResizeControllerTest);
-};
-
-// Assertions around moving mouse over 2 windows.
-TEST_F(MultiWindowResizeControllerTest, BasicTests) {
- aura::test::TestWindowDelegate delegate1;
- scoped_ptr<aura::Window> w1(
- CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
- delegate1.set_window_component(HTRIGHT);
- aura::test::TestWindowDelegate delegate2;
- scoped_ptr<aura::Window> w2(
- CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
- delegate2.set_window_component(HTRIGHT);
- aura::test::EventGenerator generator(w1->GetRootWindow());
- generator.MoveMouseTo(99, 50);
- EXPECT_TRUE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Force a show now.
- ShowNow();
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- EXPECT_FALSE(IsOverWindows(gfx::Point(200, 200)));
-
- // Have to explicitly invoke this as MouseWatcher listens for native events.
- resize_controller_->MouseMovedOutOfHost();
- EXPECT_FALSE(HasPendingShow());
- EXPECT_FALSE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-}
-
-// Makes sure deleting a window hides.
-TEST_F(MultiWindowResizeControllerTest, DeleteWindow) {
- aura::test::TestWindowDelegate delegate1;
- scoped_ptr<aura::Window> w1(
- CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
- delegate1.set_window_component(HTRIGHT);
- aura::test::TestWindowDelegate delegate2;
- scoped_ptr<aura::Window> w2(
- CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
- delegate2.set_window_component(HTRIGHT);
- aura::test::EventGenerator generator(w1->GetRootWindow());
- generator.MoveMouseTo(99, 50);
- EXPECT_TRUE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Force a show now.
- ShowNow();
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Move the mouse over the resize widget.
- ASSERT_TRUE(resize_widget());
- gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
- generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Move the resize widget
- generator.PressLeftButton();
- generator.MoveMouseTo(bounds.x() + 10, bounds.y() + 10);
-
- // Delete w2.
- w2.reset();
- EXPECT_TRUE(resize_widget() == NULL);
- EXPECT_FALSE(HasPendingShow());
- EXPECT_FALSE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
- EXPECT_FALSE(HasTarget(w1.get()));
-}
-
-// Tests resizing.
-TEST_F(MultiWindowResizeControllerTest, Drag) {
- aura::test::TestWindowDelegate delegate1;
- scoped_ptr<aura::Window> w1(
- CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
- delegate1.set_window_component(HTRIGHT);
- aura::test::TestWindowDelegate delegate2;
- scoped_ptr<aura::Window> w2(
- CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
- delegate2.set_window_component(HTRIGHT);
- aura::test::EventGenerator generator(w1->GetRootWindow());
- generator.MoveMouseTo(99, 50);
- EXPECT_TRUE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Force a show now.
- ShowNow();
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Move the mouse over the resize widget.
- ASSERT_TRUE(resize_widget());
- gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
- generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // Move the resize widget
- generator.PressLeftButton();
- generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10);
- generator.ReleaseLeftButton();
-
- EXPECT_TRUE(resize_widget());
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
- EXPECT_EQ("0,0 110x100", w1->bounds().ToString());
- EXPECT_EQ("110,0 100x100", w2->bounds().ToString());
-}
-
-// Makes sure three windows are picked up.
-TEST_F(MultiWindowResizeControllerTest, Three) {
- aura::test::TestWindowDelegate delegate1;
- scoped_ptr<aura::Window> w1(
- CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
- delegate1.set_window_component(HTRIGHT);
- aura::test::TestWindowDelegate delegate2;
- scoped_ptr<aura::Window> w2(
- CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
- delegate2.set_window_component(HTRIGHT);
- aura::test::TestWindowDelegate delegate3;
- scoped_ptr<aura::Window> w3(
- CreateTestWindow(&delegate2, gfx::Rect(200, 0, 100, 100)));
- delegate3.set_window_component(HTRIGHT);
-
- aura::test::EventGenerator generator(w1->GetRootWindow());
- generator.MoveMouseTo(99, 50);
- EXPECT_TRUE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
- EXPECT_FALSE(HasTarget(w3.get()));
-
- ShowNow();
- EXPECT_FALSE(HasPendingShow());
- EXPECT_TRUE(IsShowing());
- EXPECT_FALSE(HasPendingHide());
-
- // w3 should be picked up when resize is started.
- gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
- generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
- generator.PressLeftButton();
- generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10);
-
- EXPECT_TRUE(HasTarget(w3.get()));
-
- // Release the mouse. The resizer should still be visible and a subsequent
- // press should not trigger a DCHECK.
- generator.ReleaseLeftButton();
- EXPECT_TRUE(IsShowing());
- generator.PressLeftButton();
-}
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/phantom_window_controller.cc b/chromium/ash/wm/workspace/phantom_window_controller.cc
deleted file mode 100644
index 83a0e3fdcb0..00000000000
--- a/chromium/ash/wm/workspace/phantom_window_controller.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/phantom_window_controller.h"
-
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/coordinate_conversion.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/window.h"
-#include "ui/compositor/layer.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/animation/slide_animation.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/views/background.h"
-#include "ui/views/painter.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-
-namespace ash {
-namespace internal {
-
-// EdgePainter ----------------------------------------------------------------
-
-namespace {
-
-// Paints the background of the phantom window for window snapping.
-class EdgePainter : public views::Painter {
- public:
- EdgePainter();
- virtual ~EdgePainter();
-
- // views::Painter:
- virtual gfx::Size GetMinimumSize() const OVERRIDE;
- virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(EdgePainter);
-};
-
-} // namespace
-
-
-EdgePainter::EdgePainter() {
-}
-
-EdgePainter::~EdgePainter() {
-}
-
-gfx::Size EdgePainter::GetMinimumSize() const {
- return gfx::Size();
-}
-
-void EdgePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
- const int kInsetSize = 4;
- int x = kInsetSize;
- int y = kInsetSize;
- int w = size.width() - kInsetSize * 2;
- int h = size.height() - kInsetSize * 2;
- bool inset = (w > 0 && h > 0);
- if (!inset) {
- x = 0;
- y = 0;
- w = size.width();
- h = size.height();
- }
- SkPaint paint;
- paint.setColor(SkColorSetARGB(100, 0, 0, 0));
- paint.setStyle(SkPaint::kFill_Style);
- paint.setAntiAlias(true);
- const int kRoundRectSize = 4;
- canvas->sk_canvas()->drawRoundRect(
- gfx::RectToSkRect(gfx::Rect(x, y, w, h)),
- SkIntToScalar(kRoundRectSize), SkIntToScalar(kRoundRectSize), paint);
- if (!inset)
- return;
-
- paint.setColor(SkColorSetARGB(200, 255, 255, 255));
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(SkIntToScalar(2));
- canvas->sk_canvas()->drawRoundRect(
- gfx::RectToSkRect(gfx::Rect(x, y, w, h)), SkIntToScalar(kRoundRectSize),
- SkIntToScalar(kRoundRectSize), paint);
-}
-
-
-// PhantomWindowController ----------------------------------------------------
-
-PhantomWindowController::PhantomWindowController(aura::Window* window)
- : window_(window),
- phantom_below_window_(NULL),
- phantom_widget_(NULL),
- phantom_widget_start_(NULL) {
-}
-
-PhantomWindowController::~PhantomWindowController() {
- Hide();
-}
-
-void PhantomWindowController::Show(const gfx::Rect& bounds_in_screen) {
- if (bounds_in_screen == bounds_in_screen_)
- return;
- bounds_in_screen_ = bounds_in_screen;
- aura::Window* target_root = wm::GetRootWindowMatching(bounds_in_screen);
- // Show the phantom at the current bounds of the window. We'll animate to the
- // target bounds. If phantom exists, update the start bounds.
- if (!phantom_widget_)
- start_bounds_ = window_->GetBoundsInScreen();
- else
- start_bounds_ = phantom_widget_->GetWindowBoundsInScreen();
- if (phantom_widget_ &&
- phantom_widget_->GetNativeWindow()->GetRootWindow() != target_root) {
- phantom_widget_->Close();
- phantom_widget_ = NULL;
- }
- if (!phantom_widget_)
- phantom_widget_ = CreatePhantomWidget(target_root, start_bounds_);
-
- // Create a secondary widget in a second screen if start_bounds_ lie at least
- // partially in that other screen. This allows animations to start or restart
- // in one root window and progress into another root.
- aura::Window* start_root = wm::GetRootWindowMatching(start_bounds_);
- if (start_root == target_root) {
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- for (size_t i = 0; i < root_windows.size(); ++i) {
- if (root_windows[i] != target_root &&
- root_windows[i]->GetBoundsInScreen().Intersects(start_bounds_)) {
- start_root = root_windows[i];
- break;
- }
- }
- }
- if (phantom_widget_start_ &&
- (phantom_widget_start_->GetNativeWindow()->GetRootWindow() != start_root
- || start_root == target_root)) {
- phantom_widget_start_->Close();
- phantom_widget_start_ = NULL;
- }
- if (!phantom_widget_start_ && start_root != target_root)
- phantom_widget_start_ = CreatePhantomWidget(start_root, start_bounds_);
-
- animation_.reset(new gfx::SlideAnimation(this));
- animation_->SetTweenType(gfx::Tween::EASE_IN);
- const int kAnimationDurationMS = 200;
- animation_->SetSlideDuration(kAnimationDurationMS);
- animation_->Show();
-}
-
-void PhantomWindowController::Hide() {
- if (phantom_widget_)
- phantom_widget_->Close();
- phantom_widget_ = NULL;
- if (phantom_widget_start_)
- phantom_widget_start_->Close();
- phantom_widget_start_ = NULL;
-}
-
-bool PhantomWindowController::IsShowing() const {
- return phantom_widget_ != NULL;
-}
-
-void PhantomWindowController::AnimationProgressed(
- const gfx::Animation* animation) {
- const gfx::Rect current_bounds =
- animation->CurrentValueBetween(start_bounds_, bounds_in_screen_);
- if (phantom_widget_start_)
- phantom_widget_start_->SetBounds(current_bounds);
- phantom_widget_->SetBounds(current_bounds);
-}
-
-views::Widget* PhantomWindowController::CreatePhantomWidget(
- aura::Window* root_window,
- const gfx::Rect& bounds_in_screen) {
- views::Widget* phantom_widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- // PhantomWindowController is used by FrameMaximizeButton to highlight the
- // launcher button. Put the phantom in the same window as the launcher so that
- // the phantom is visible.
- params.parent = Shell::GetContainer(root_window,
- kShellWindowId_ShelfContainer);
- params.can_activate = false;
- params.keep_on_top = true;
- phantom_widget->set_focus_on_creation(false);
- phantom_widget->Init(params);
- phantom_widget->SetVisibilityChangedAnimationsEnabled(false);
- phantom_widget->GetNativeWindow()->SetName("PhantomWindow");
- phantom_widget->GetNativeWindow()->set_id(kShellWindowId_PhantomWindow);
- views::View* content_view = new views::View;
- content_view->set_background(
- views::Background::CreateBackgroundPainter(true, new EdgePainter));
- phantom_widget->SetContentsView(content_view);
- phantom_widget->SetBounds(bounds_in_screen);
- if (phantom_below_window_)
- phantom_widget->StackBelow(phantom_below_window_);
- else
- phantom_widget->StackAbove(window_);
-
- // Show the widget after all the setups.
- phantom_widget->Show();
-
- // Fade the window in.
- ui::Layer* widget_layer = phantom_widget->GetNativeWindow()->layer();
- widget_layer->SetOpacity(0);
- ui::ScopedLayerAnimationSettings scoped_setter(widget_layer->GetAnimator());
- widget_layer->SetOpacity(1);
- return phantom_widget;
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/phantom_window_controller.h b/chromium/ash/wm/workspace/phantom_window_controller.h
deleted file mode 100644
index 77d4a286035..00000000000
--- a/chromium/ash/wm/workspace/phantom_window_controller.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_PHANTOM_WINDOW_CONTROLLER_H_
-#define ASH_WM_WORKSPACE_PHANTOM_WINDOW_CONTROLLER_H_
-
-#include "ash/ash_export.h"
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/gfx/animation/animation_delegate.h"
-#include "ui/gfx/rect.h"
-
-namespace aura {
-class Window;
-}
-
-namespace gfx {
-class SlideAnimation;
-}
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-namespace internal {
-
-// PhantomWindowController is responsible for showing a phantom representation
-// of a window. It's used used during dragging a window to show a snap location.
-class ASH_EXPORT PhantomWindowController : public gfx::AnimationDelegate {
- public:
- explicit PhantomWindowController(aura::Window* window);
- virtual ~PhantomWindowController();
-
- // Bounds last passed to Show().
- const gfx::Rect& bounds_in_screen() const { return bounds_in_screen_; }
-
- // Animates the phantom window towards |bounds_in_screen|.
- // Creates two (if start bounds intersect any root window other than the
- // root window that matches the target bounds) or one (otherwise) phantom
- // widgets to display animated rectangle in each root.
- // This does not immediately show the window.
- void Show(const gfx::Rect& bounds_in_screen);
-
- // Hides the phantom.
- void Hide();
-
- // Returns true if the phantom is showing.
- bool IsShowing() const;
-
- // If set, the phantom window is stacked below this window, otherwise it
- // is stacked above the window passed to the constructor.
- void set_phantom_below_window(aura::Window* phantom_below_window) {
- phantom_below_window_ = phantom_below_window;
- }
-
- // gfx::AnimationDelegate overrides:
- virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
-
- private:
- FRIEND_TEST_ALL_PREFIXES(WorkspaceWindowResizerTest, PhantomWindowShow);
-
- // Creates, shows and returns a phantom widget at |bounds|
- // with kShellWindowId_ShelfContainer in |root_window| as a parent.
- views::Widget* CreatePhantomWidget(aura::Window* root_window,
- const gfx::Rect& bounds_in_screen);
-
- // Window the phantom is placed beneath.
- aura::Window* window_;
-
- // If set, the phantom window should get stacked below this window.
- aura::Window* phantom_below_window_;
-
- // Initially the bounds of |window_| (in screen coordinates).
- // Each time Show() is invoked |start_bounds_| is then reset to the bounds of
- // |phantom_widget_| and |bounds_| is set to the value passed into Show().
- // The animation animates between these two values.
- gfx::Rect start_bounds_;
-
- // Target bounds of the animation in screen coordinates.
- gfx::Rect bounds_in_screen_;
-
- // The primary phantom representation of the window. It is parented by the
- // root window matching the target bounds.
- views::Widget* phantom_widget_;
-
- // If the animation starts on another display, this is the secondary phantom
- // representation of the window used on the initial display, otherwise this is
- // NULL. This allows animation to progress from one display into the other.
- views::Widget* phantom_widget_start_;
-
- // Used to transition the bounds.
- scoped_ptr<gfx::SlideAnimation> animation_;
-
- DISALLOW_COPY_AND_ASSIGN(PhantomWindowController);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_PHANTOM_WINDOW_CONTROLLER_H_
diff --git a/chromium/ash/wm/workspace/snap_sizer.cc b/chromium/ash/wm/workspace/snap_sizer.cc
deleted file mode 100644
index ba35f6ac3cc..00000000000
--- a/chromium/ash/wm/workspace/snap_sizer.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/snap_sizer.h"
-
-#include <cmath>
-
-#include "ash/ash_switches.h"
-#include "ash/screen_ash.h"
-#include "ash/wm/window_resizer.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "base/command_line.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/gfx/screen.h"
-
-namespace ash {
-namespace internal {
-
-namespace {
-
-// A list of ideal window widths in DIP which will be used to populate the
-// |usable_width_| list.
-const int kIdealWidth[] = { 1280, 1024, 768, 640 };
-
-// Windows are initially snapped to the size in |usable_width_| at index 0.
-// The index into |usable_width_| is changed if any of the following happen:
-// . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then
-// moves the mouse again.
-// . The mouse moves |kPixelsBeforeAdjust| horizontal pixels.
-// . The mouse is against the edge of the screen and the mouse is moved
-// |kMovesBeforeAdjust| times.
-const int kDelayBeforeIncreaseMS = 500;
-const int kMovesBeforeAdjust = 25;
-const int kPixelsBeforeAdjust = 100;
-
-// The maximum fraction of the screen width that a snapped window is allowed
-// to take up.
-const int kMaximumScreenPercent = 90;
-
-// The width that a window should be snapped to if resizing is disabled in the
-// SnapSizer for devices with small screen resolutions.
-const int kDefaultWidthSmallScreen = 1024;
-
-// Returns the minimum width that |window| can be snapped to. The returned width
-// may not be in the width list generated by BuildIdealWidthList().
-int GetMinWidth(aura::Window* window) {
- return window->delegate() ? window->delegate()->GetMinimumSize().width() : 0;
-}
-
-// Returns the maximum width that |window| can be snapped to. The returned width
-// may not be in the width list generated by BuildIdealWidthList().
-// The aura::WindowDelegate's max size is ignored because
-// ash::wm::CanSnapWindow() returns false when a max size is specified.
-int GetMaxWidth(aura::Window* window) {
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
- return std::max(work_area.width() * kMaximumScreenPercent / 100,
- GetMinWidth(window));
-}
-
-// Returns the width that |window| should be snapped to if resizing is disabled
-// in the SnapSizer.
-int GetDefaultWidth(aura::Window* window) {
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
-
- int width = 0;
- if (!CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshMultipleSnapWindowWidths)) {
- width = work_area.width() / 2;
- } else {
- width = std::max(kDefaultWidthSmallScreen, work_area.width() / 2);
- }
-
- width = std::min(width, GetMaxWidth(window));
- return std::max(width, GetMinWidth(window));
-}
-
-// Creates the list of possible width for the current screen configuration:
-// Returns a list with items from |kIdealWidth| which fit on the screen and
-// supplement it with the 'half of screen' size. Furthermore, add an entry for
-// 90% of the screen size if it is smaller than the biggest value in the
-// |kIdealWidth| list (to get a step between the values).
-std::vector<int> BuildIdealWidthList(aura::Window* window) {
- if (!CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshMultipleSnapWindowWidths)) {
- return std::vector<int>(1u, GetDefaultWidth(window));
- }
-
- int minimum_width = GetMinWidth(window);
- int maximum_width = GetMaxWidth(window);
-
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
- int half_width = work_area.width() / 2;
- if (half_width < minimum_width || half_width > maximum_width)
- half_width = 0;
-
- std::vector<int> ideal_width_list;
- for (size_t i = 0; i < arraysize(kIdealWidth); i++) {
- if (kIdealWidth[i] >= minimum_width && kIdealWidth[i] <= maximum_width) {
- if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i])
- ideal_width_list.push_back(maximum_width);
- if (half_width > kIdealWidth[i])
- ideal_width_list.push_back(half_width);
- if (half_width >= kIdealWidth[i])
- half_width = 0;
- ideal_width_list.push_back(kIdealWidth[i]);
- }
- }
- if (half_width)
- ideal_width_list.push_back(half_width);
- if (ideal_width_list.empty()) {
- if (minimum_width > 0)
- ideal_width_list.push_back(minimum_width);
- else
- ideal_width_list.push_back(maximum_width);
- }
-
- return ideal_width_list;
-}
-
-// Changes |window|'s bounds to |snap_bounds| while preserving the restore
-// bounds.
-void SnapWindowToBounds(wm::WindowState* window_state,
- SnapSizer::Edge edge,
- const gfx::Rect& snap_bounds) {
- if (edge == SnapSizer::LEFT_EDGE) {
- window_state->SnapLeft(snap_bounds);
- } else {
- window_state->SnapRight(snap_bounds);
- }
-}
-
-} // namespace
-
-SnapSizer::SnapSizer(wm::WindowState* window_state,
- const gfx::Point& start,
- Edge edge,
- InputType input_type)
- : window_state_(window_state),
- edge_(edge),
- time_last_update_(base::TimeTicks::Now()),
- size_index_(0),
- end_of_sequence_(false),
- resize_disabled_(false),
- num_moves_since_adjust_(0),
- last_adjust_x_(start.x()),
- last_update_x_(start.x()),
- start_x_(start.x()),
- input_type_(input_type),
- usable_width_(BuildIdealWidthList(window_state->window())) {
- DCHECK(!usable_width_.empty());
- target_bounds_ = GetTargetBounds();
-}
-
-SnapSizer::~SnapSizer() {
-}
-
-void SnapSizer::SnapWindow(wm::WindowState* window_state,
- SnapSizer::Edge edge) {
- if (!window_state->CanSnap())
- return;
- internal::SnapSizer sizer(window_state, gfx::Point(), edge,
- internal::SnapSizer::OTHER_INPUT);
- SnapWindowToBounds(window_state, edge,
- sizer.GetSnapBounds(window_state->window()->bounds()));
-}
-
-void SnapSizer::SnapWindowToTargetBounds() {
- SnapWindowToBounds(window_state_, edge_, target_bounds());
-}
-
-void SnapSizer::Update(const gfx::Point& location) {
- // See description above for details on this behavior.
- num_moves_since_adjust_++;
- if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() >
- kDelayBeforeIncreaseMS) {
- ChangeBounds(location.x(),
- CalculateIncrement(location.x(), last_update_x_));
- } else {
- bool along_edge = AlongEdge(location.x());
- int pixels_before_adjust = kPixelsBeforeAdjust;
- if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) {
- const gfx::Rect& workspace_bounds =
- window_state_->window()->parent()->bounds();
- if (start_x_ > location.x()) {
- pixels_before_adjust =
- std::min(pixels_before_adjust, start_x_ / 10);
- } else {
- pixels_before_adjust =
- std::min(pixels_before_adjust,
- (workspace_bounds.width() - start_x_) / 10);
- }
- }
- if (std::abs(location.x() - last_adjust_x_) >= pixels_before_adjust ||
- (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) {
- ChangeBounds(location.x(),
- CalculateIncrement(location.x(), last_adjust_x_));
- }
- }
- last_update_x_ = location.x();
- time_last_update_ = base::TimeTicks::Now();
-}
-
-gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) {
- int current = 0;
- if (!resize_disabled_) {
- for (current = usable_width_.size() - 1; current >= 0; current--) {
- gfx::Rect target = GetTargetBoundsForSize(current);
- if (target == bounds) {
- ++current;
- break;
- }
- }
- }
- if (current < 0)
- current = 0;
- return GetTargetBoundsForSize(current % usable_width_.size());
-}
-
-void SnapSizer::SelectDefaultSizeAndDisableResize() {
- resize_disabled_ = true;
- size_index_ = 0;
- end_of_sequence_ = false;
- target_bounds_ = GetTargetBounds();
-}
-
-gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_state_->window()));
- int y = work_area.y();
- int max_y = work_area.bottom();
- int width = 0;
- if (resize_disabled_) {
- width = GetDefaultWidth(window_state_->window());
- } else {
- DCHECK(size_index < usable_width_.size());
- width = usable_width_[size_index];
- }
-
- if (edge_ == LEFT_EDGE) {
- int x = work_area.x();
- int mid_x = x + width;
- return gfx::Rect(x, y, mid_x - x, max_y - y);
- }
- int max_x = work_area.right();
- int x = max_x - width;
- return gfx::Rect(x , y, max_x - x, max_y - y);
-}
-
-int SnapSizer::CalculateIncrement(int x, int reference_x) const {
- if (AlongEdge(x))
- return 1;
- if (x == reference_x)
- return 0;
- if (edge_ == LEFT_EDGE) {
- if (x < reference_x)
- return 1;
- return -1;
- }
- // edge_ == RIGHT_EDGE.
- if (x > reference_x)
- return 1;
- return -1;
-}
-
-void SnapSizer::ChangeBounds(int x, int delta) {
- end_of_sequence_ =
- delta > 0 && size_index_ == static_cast<int>(usable_width_.size()) - 1;
- int index = std::min(static_cast<int>(usable_width_.size()) - 1,
- std::max(size_index_ + delta, 0));
- if (index != size_index_) {
- size_index_ = index;
- target_bounds_ = GetTargetBounds();
- }
- num_moves_since_adjust_ = 0;
- last_adjust_x_ = x;
-}
-
-gfx::Rect SnapSizer::GetTargetBounds() const {
- return GetTargetBoundsForSize(size_index_);
-}
-
-bool SnapSizer::AlongEdge(int x) const {
- gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_state_->window()));
- return (x <= area.x()) || (x >= area.right() - 1);
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/snap_sizer.h b/chromium/ash/wm/workspace/snap_sizer.h
deleted file mode 100644
index b32c3c8c310..00000000000
--- a/chromium/ash/wm/workspace/snap_sizer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_SNAP_SIZER_H_
-#define ASH_WM_WORKSPACE_SNAP_SIZER_H_
-
-#include <vector>
-
-#include "ash/ash_export.h"
-#include "base/basictypes.h"
-#include "base/time/time.h"
-#include "ui/gfx/rect.h"
-
-namespace ash {
-namespace wm {
-class WindowState;
-}
-
-namespace internal {
-
-// SnapSizer is responsible for determining the resulting bounds of a window
-// that is being snapped to the left or right side of the screen.
-// The bounds used in this class are in the container's coordinates.
-class ASH_EXPORT SnapSizer {
- public:
- enum Edge {
- LEFT_EDGE,
- RIGHT_EDGE
- };
-
- enum InputType {
- TOUCH_MAXIMIZE_BUTTON_INPUT,
- OTHER_INPUT
- };
-
- // Set |input_type| to |TOUCH_MAXIMIZE_BUTTON_INPUT| when called by a touch
- // operation by the maximize button. This will allow the user to snap resize
- // the window beginning close to the border.
- SnapSizer(wm::WindowState* window_state,
- const gfx::Point& start,
- Edge edge,
- InputType input_type);
- virtual ~SnapSizer();
-
- // Snaps a window left or right.
- static void SnapWindow(wm::WindowState* window_state, Edge edge);
-
- // Snaps |window_| to the target bounds.
- void SnapWindowToTargetBounds();
-
- // Updates the target bounds based on a mouse move.
- void Update(const gfx::Point& location);
-
- // Bounds to position the window at.
- const gfx::Rect& target_bounds() const { return target_bounds_; }
-
- // Returns the appropriate snap bounds (e.g. if a window is already snapped,
- // then it returns the next snap-bounds).
- gfx::Rect GetSnapBounds(const gfx::Rect& bounds);
-
- // Set the snap sizer to the button press default size and prevent resizing.
- void SelectDefaultSizeAndDisableResize();
-
- // Returns the target bounds based on the edge and the provided |size_index|.
- // For unit test purposes this function is not private.
- gfx::Rect GetTargetBoundsForSize(size_t size_index) const;
-
- // Returns true when snapping sequence is at its last (docking) step.
- bool end_of_sequence() const { return end_of_sequence_; }
-
- private:
- // Calculates the amount to increment by. This returns one of -1, 0 or 1 and
- // is intended to by applied to |size_index_|. |x| is the current
- // x-coordinate, and |reference_x| is used to determine whether to increase
- // or decrease the position. It's one of |last_adjust_x_| or |last_update_x_|.
- int CalculateIncrement(int x, int reference_x) const;
-
- // Changes the bounds. |x| is the current x-coordinate and |delta| the amount
- // to increase by. |delta| comes from CalculateIncrement() and is applied
- // to |size_index_|.
- void ChangeBounds(int x, int delta);
-
- // Returns the target bounds based on the edge and |size_index_|.
- gfx::Rect GetTargetBounds() const;
-
- // Returns true if the specified point is along the edge of the screen.
- bool AlongEdge(int x) const;
-
- // WindowState of the window being snapped.
- wm::WindowState* window_state_;
-
- const Edge edge_;
-
- // Current target bounds for the snap.
- gfx::Rect target_bounds_;
-
- // Time Update() was last invoked.
- base::TimeTicks time_last_update_;
-
- // Index into |kSizes| that dictates the width of the screen the target
- // bounds should get.
- int size_index_;
-
- // Set to true when an attempt is made to increment |size_index_| past
- // the size of |usable_width_|.
- bool end_of_sequence_;
-
- // If set, |size_index_| will get ignored and the single button default
- // setting will be used instead.
- bool resize_disabled_;
-
- // Number of times Update() has been invoked since last ChangeBounds().
- int num_moves_since_adjust_;
-
- // X-coordinate the last time ChangeBounds() was invoked.
- int last_adjust_x_;
-
- // X-coordinate last supplied to Update().
- int last_update_x_;
-
- // Initial x-coordinate.
- const int start_x_;
-
- // |TOUCH_MAXIMIZE_BUTTON_INPUT| if the snap sizer was created through a
- // touch & drag operation of the maximizer button. It changes the behavior of
- // the drag / resize behavior when the dragging starts close to the border.
- const InputType input_type_;
-
- // A list of usable window widths for size. This gets created when the
- // sizer gets created.
- const std::vector<int> usable_width_;
-
- DISALLOW_COPY_AND_ASSIGN(SnapSizer);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_SNAP_SIZER_H_
diff --git a/chromium/ash/wm/workspace/snap_sizer_unittest.cc b/chromium/ash/wm/workspace/snap_sizer_unittest.cc
deleted file mode 100644
index 81a09f93940..00000000000
--- a/chromium/ash/wm/workspace/snap_sizer_unittest.cc
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/snap_sizer.h"
-
-#include "ash/ash_switches.h"
-#include "ash/screen_ash.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "base/command_line.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window.h"
-#include "ui/gfx/screen.h"
-
-namespace ash {
-
-typedef test::AshTestBase SnapSizerTest;
-
-using internal::SnapSizer;
-
-// Test that a window gets properly snapped to the display's edges in a
-// multi monitor environment.
-TEST_F(SnapSizerTest, MultipleDisplays) {
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("0+0-500x400, 0+500-600x400");
- const gfx::Rect kPrimaryDisplayWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
- const gfx::Rect kSecondaryDisplayWorkAreaBounds =
- ScreenAsh::GetSecondaryDisplay().work_area();
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- gfx::Rect expected = gfx::Rect(
- kPrimaryDisplayWorkAreaBounds.x(),
- kPrimaryDisplayWorkAreaBounds.y(),
- window->bounds().width(), // No expectation for the width.
- kPrimaryDisplayWorkAreaBounds.height());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- // The width should not change when a window switches from being snapped to
- // the left edge to being snapped to the right edge.
- expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Move the window to the secondary display.
- window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
- ScreenAsh::GetSecondaryDisplay());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected = gfx::Rect(
- kSecondaryDisplayWorkAreaBounds.right() - window->bounds().width(),
- kSecondaryDisplayWorkAreaBounds.y(),
- window->bounds().width(), // No expectation for the width.
- kSecondaryDisplayWorkAreaBounds.height());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- // The width should not change when a window switches from being snapped to
- // the right edge to being snapped to the left edge.
- expected.set_x(kSecondaryDisplayWorkAreaBounds.x());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-// Test how the minimum and maximum size specified by the aura::WindowDelegate
-// affect snapping.
-TEST_F(SnapSizerTest, MinimumSize) {
- if (!SupportsHostWindowResize())
- return;
-
- UpdateDisplay("0+0-600x800");
- const gfx::Rect kWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-
- aura::test::TestWindowDelegate delegate;
- scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
- &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100)));
-
- // It should be possible to snap a window with a minimum size.
- delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- EXPECT_TRUE(window_state->CanSnap());
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1,
- kWorkAreaBounds.y(),
- kWorkAreaBounds.width() - 1,
- kWorkAreaBounds.height());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // It should not be possible to snap a window with a maximum size.
- delegate.set_minimum_size(gfx::Size());
- delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, INT_MAX));
- EXPECT_FALSE(window_state->CanSnap());
-}
-
-// Test that repeatedly calling SnapSizer::SnapWindow() when the
-// --ash-multiple-snap-window-widths flag is set steps through the ideal widths
-// in descending order as well as 90% and 50% of the work area's width.
-TEST_F(SnapSizerTest, StepThroughSizes) {
- if (!SupportsHostWindowResize())
- return;
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kAshMultipleSnapWindowWidths);
-
- UpdateDisplay("1024x800");
- const gfx::Rect kWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- // Make sure that the work area is the size we expect it to be.
- EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768);
-
- // The first width should be 1024 * 0.9 because the larger ideal widths
- // (1280, 1024) > 1024 * 0.9.
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
- kWorkAreaBounds.y(),
- kWorkAreaBounds.width() * 0.9,
- kWorkAreaBounds.height());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- expected.set_width(768);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- expected.set_width(640);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- expected.set_width(kWorkAreaBounds.width() * 0.5);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Wrap around.
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- expected.set_width(kWorkAreaBounds.width() * 0.9);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Repeat the test snapping right.
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_width(kWorkAreaBounds.width() * 0.9);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_width(768);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_width(640);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_width(kWorkAreaBounds.width() * 0.5);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Wrap around.
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_width(kWorkAreaBounds.width() * 0.9);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-// Test that a SnapSizer's target bounds always start from the widest possible
-// bounds and that calling Update() steps through the ideal widths in descending
-// order as well as 90% and 50% of the work area's width.
-TEST_F(SnapSizerTest, Update) {
- if (!SupportsHostWindowResize())
- return;
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kAshMultipleSnapWindowWidths);
- UpdateDisplay("1024x800");
- const gfx::Rect kWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-
- // Make sure that the work area is the size we expect it to be.
- EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768);
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
- kWorkAreaBounds.y(),
- 768,
- kWorkAreaBounds.height());
-
- // The SnapSizer's target bounds should always start from the widest bounds
- // (instead of the bounds with the next ideal width).
- SnapSizer sizer(window_state, gfx::Point(800, 0), SnapSizer::LEFT_EDGE,
- SnapSizer::OTHER_INPUT);
- sizer.SnapWindowToTargetBounds();
- expected.set_width(kWorkAreaBounds.width() * .9);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- sizer.Update(gfx::Point(600, 0));
- sizer.SnapWindowToTargetBounds();
- expected.set_width(768);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- sizer.Update(gfx::Point(400, 0));
- sizer.SnapWindowToTargetBounds();
- expected.set_width(640);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- sizer.Update(gfx::Point(200, 0));
- sizer.SnapWindowToTargetBounds();
- expected.set_width(kWorkAreaBounds.width() * 0.5);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Do not wrap around.
- sizer.Update(gfx::Point(0, 0));
- sizer.SnapWindowToTargetBounds();
- expected.set_width(kWorkAreaBounds.width() * 0.5);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-// Tests the SnapSizer's target bounds when resizing is disabled and the
-// --ash-multiple-snap-window-widths flag is set.
-TEST_F(SnapSizerTest, Default) {
- if (!SupportsHostWindowResize())
- return;
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kAshMultipleSnapWindowWidths);
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- SnapSizer sizer(wm::GetWindowState(window.get()), gfx::Point(),
- SnapSizer::LEFT_EDGE, SnapSizer::OTHER_INPUT);
-
- // For small workspace widths, we should snap to 90% of the workspace width
- // because it is the largest width the window can snap to.
- UpdateDisplay("0+0-800x600");
- sizer.SelectDefaultSizeAndDisableResize();
-
- gfx::Rect work_area =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
- gfx::Rect expected(work_area);
- expected.set_width(work_area.width() * 0.9);
- EXPECT_EQ(expected.ToString(),
- ScreenAsh::ConvertRectToScreen(window->parent(),
- sizer.target_bounds()).ToString());
-
- // If the largest width the window can snap to is between 1024 and 1280, we
- // should snap to 1024.
- UpdateDisplay("0+0-1280x800");
- sizer.SelectDefaultSizeAndDisableResize();
- sizer.SnapWindowToTargetBounds();
- EXPECT_EQ(1024, window->bounds().width());
-
- // We should snap to a width of 50% of the work area if it is the largest
- // width the window can snap to.
- UpdateDisplay("0+0-2560x1080");
- work_area = ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
- sizer.SelectDefaultSizeAndDisableResize();
- sizer.SnapWindowToTargetBounds();
- EXPECT_EQ(work_area.width() / 2, window->bounds().width());
-}
-
-// Test that the window only snaps to 50% of the work area width when the
-// --ash-multiple-snap-window-widths flag is not set.
-TEST_F(SnapSizerTest, SingleSnapWindowWidth) {
- if (!SupportsHostWindowResize())
- return;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshMultipleSnapWindowWidths)) {
- return;
- }
-
- UpdateDisplay("0+0-800x600");
- const gfx::Rect kWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
- kWorkAreaBounds.y(),
- kWorkAreaBounds.width() / 2,
- kWorkAreaBounds.height());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Because a window can only be snapped to one size when using the alternate
- // caption button style, a second call to SnapSizer::SnapWindow() should have
- // no effect.
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // It should still be possible to switch a window from being snapped to the
- // left edge to being snapped to the right edge.
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- expected.set_x(kWorkAreaBounds.right() - expected.width());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // If resizing is disabled, the window should be snapped to 50% too.
- SnapSizer sizer1(window_state, gfx::Point(), SnapSizer::RIGHT_EDGE,
- SnapSizer::OTHER_INPUT);
- sizer1.SelectDefaultSizeAndDisableResize();
- sizer1.SnapWindowToTargetBounds();
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-
- // Snapping to a SnapSizer's initial bounds snaps to 50% too.
- SnapSizer sizer2(window_state, gfx::Point(), SnapSizer::LEFT_EDGE,
- SnapSizer::OTHER_INPUT);
- sizer2.SnapWindowToTargetBounds();
- expected.set_x(kWorkAreaBounds.x());
- EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-// Test that snapping left/right preserves the restore bounds.
-TEST_F(SnapSizerTest, RestoreBounds) {
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- EXPECT_TRUE(window_state->IsNormalShowState());
-
- // 1) Start with restored window with restore bounds set.
- gfx::Rect restore_bounds = window->GetBoundsInScreen();
- restore_bounds.set_width(restore_bounds.width() + 1);
- window_state->SetRestoreBoundsInScreen(restore_bounds);
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
- EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
- EXPECT_EQ(restore_bounds.ToString(),
- window_state->GetRestoreBoundsInScreen().ToString());
- window_state->Restore();
- EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
-
- // 2) Start with restored bounds set as a result of maximizing the window.
- window_state->Maximize();
- gfx::Rect maximized_bounds = window->GetBoundsInScreen();
- EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString());
- EXPECT_EQ(restore_bounds.ToString(),
- window_state->GetRestoreBoundsInScreen().ToString());
-
- SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
- EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
- EXPECT_NE(maximized_bounds.ToString(),
- window->GetBoundsInScreen().ToString());
- EXPECT_EQ(restore_bounds.ToString(),
- window_state->GetRestoreBoundsInScreen().ToString());
-
- window_state->Restore();
- EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-// Test that maximizing an auto managed window, then snapping it puts the window
-// at the snapped bounds and not at the auto-managed (centered) bounds.
-TEST_F(SnapSizerTest, AutoManaged) {
- scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->set_window_position_managed(true);
- window->Hide();
- window->SetBounds(gfx::Rect(100, 100, 100, 100));
- window->Show();
-
- window_state->Maximize();
- SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
-
- const gfx::Rect kWorkAreaBounds =
- ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
- gfx::Rect expected_snapped_bounds(
- kWorkAreaBounds.right() - window->bounds().width(),
- kWorkAreaBounds.y(),
- window->bounds().width(), // No expectation for the width.
- kWorkAreaBounds.height());
- EXPECT_EQ(expected_snapped_bounds.ToString(),
- window->GetBoundsInScreen().ToString());
-
- // The window should still be auto managed despite being right maximized.
- EXPECT_TRUE(window_state->window_position_managed());
-}
-
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/snap_types.h b/chromium/ash/wm/workspace/snap_types.h
deleted file mode 100644
index 482a7dd583b..00000000000
--- a/chromium/ash/wm/workspace/snap_types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_SNAP_TYPES_H_
-#define ASH_WM_WORKSPACE_SNAP_TYPES_H_
-
-namespace ash {
-
-// These are the window snap types which can be used for window resizing.
-// Their main use case is the class FrameMaximizeButton.
-enum SnapType {
- SNAP_LEFT,
- SNAP_RIGHT,
- SNAP_MAXIMIZE,
- SNAP_MINIMIZE,
- SNAP_RESTORE,
- SNAP_NONE
-};
-
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_SNAP_TYPES_H_
diff --git a/chromium/ash/wm/workspace/workspace_event_handler.cc b/chromium/ash/wm/workspace/workspace_event_handler.cc
deleted file mode 100644
index bcd7e9e1d64..00000000000
--- a/chromium/ash/wm/workspace/workspace_event_handler.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_event_handler.h"
-
-#include "ash/metrics/user_metrics_recorder.h"
-#include "ash/screen_ash.h"
-#include "ash/shell.h"
-#include "ash/touch/touch_uma.h"
-#include "ash/wm/coordinate_conversion.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace/workspace_window_resizer.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/base/hit_test.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/events/event.h"
-#include "ui/events/event_utils.h"
-#include "ui/gfx/screen.h"
-
-namespace ash {
-namespace {
-
-void SingleAxisMaximize(wm::WindowState* window_state,
- const gfx::Rect& maximize_rect_in_screen) {
- window_state->SaveCurrentBoundsForRestore();
- window_state->SetBoundsInScreen(maximize_rect_in_screen);
-}
-
-void SingleAxisUnmaximize(wm::WindowState* window_state,
- const gfx::Rect& restore_bounds_in_screen) {
- window_state->SetBoundsInScreen(restore_bounds_in_screen);
- window_state->ClearRestoreBounds();
-}
-
-void ToggleMaximizedState(wm::WindowState* window_state) {
- if (window_state->HasRestoreBounds()) {
- if (window_state->GetShowState() == ui::SHOW_STATE_NORMAL) {
- window_state->window()->SetBounds(
- window_state->GetRestoreBoundsInParent());
- window_state->ClearRestoreBounds();
- } else {
- window_state->Restore();
- }
- } else if (window_state->CanMaximize()) {
- window_state->Maximize();
- }
-}
-
-} // namespace
-
-namespace internal {
-
-WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* owner)
- : ToplevelWindowEventHandler(owner) {
-}
-
-WorkspaceEventHandler::~WorkspaceEventHandler() {
-}
-
-void WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
- aura::Window* target = static_cast<aura::Window*>(event->target());
- switch (event->type()) {
- case ui::ET_MOUSE_MOVED: {
- int component =
- target->delegate()->GetNonClientComponent(event->location());
- multi_window_resize_controller_.Show(target, component,
- event->location());
- break;
- }
- case ui::ET_MOUSE_ENTERED:
- break;
- case ui::ET_MOUSE_CAPTURE_CHANGED:
- case ui::ET_MOUSE_EXITED:
- break;
- case ui::ET_MOUSE_PRESSED: {
- // Maximize behavior is implemented as post-target handling so the target
- // can cancel it.
- if (ui::EventCanceledDefaultHandling(*event)) {
- ToplevelWindowEventHandler::OnMouseEvent(event);
- return;
- }
- wm::WindowState* target_state = wm::GetWindowState(target);
- if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
- event->IsOnlyLeftMouseButton() &&
- target->delegate()->GetNonClientComponent(event->location()) ==
- HTCAPTION) {
- ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
- ash::UMA_TOGGLE_MAXIMIZE_CAPTION_CLICK);
- ToggleMaximizedState(target_state);
- }
- multi_window_resize_controller_.Hide();
- HandleVerticalResizeDoubleClick(target_state, event);
- break;
- }
- default:
- break;
- }
- ToplevelWindowEventHandler::OnMouseEvent(event);
-}
-
-void WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
- aura::Window* target = static_cast<aura::Window*>(event->target());
- if (event->type() == ui::ET_GESTURE_TAP &&
- target->delegate()->GetNonClientComponent(event->location()) ==
- HTCAPTION) {
- if (event->details().tap_count() == 2) {
- ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
- ash::UMA_TOGGLE_MAXIMIZE_CAPTION_GESTURE);
- // Note: TouchUMA::GESTURE_FRAMEVIEW_TAP is counted twice each time
- // TouchUMA::GESTURE_MAXIMIZE_DOUBLETAP is counted once.
- TouchUMA::GetInstance()->RecordGestureAction(
- TouchUMA::GESTURE_MAXIMIZE_DOUBLETAP);
- ToggleMaximizedState(wm::GetWindowState(target));
- event->StopPropagation();
- return;
- } else {
- // Note: TouchUMA::GESTURE_FRAMEVIEW_TAP is counted twice for each tap.
- TouchUMA::GetInstance()->RecordGestureAction(
- TouchUMA::GESTURE_FRAMEVIEW_TAP);
- }
- }
- ToplevelWindowEventHandler::OnGestureEvent(event);
-}
-
-void WorkspaceEventHandler::HandleVerticalResizeDoubleClick(
- wm::WindowState* target_state,
- ui::MouseEvent* event) {
- aura::Window* target = target_state->window();
- gfx::Rect max_size(target->delegate()->GetMaximumSize());
- if (event->flags() & ui::EF_IS_DOUBLE_CLICK && !target_state->IsMaximized()) {
- int component =
- target->delegate()->GetNonClientComponent(event->location());
- gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- target).work_area();
- if (component == HTBOTTOM || component == HTTOP) {
- // Don't maximize vertically if the window has a max height defined.
- if (max_size.height() != 0)
- return;
- if (target_state->HasRestoreBounds() &&
- (target->bounds().height() == work_area.height() &&
- target->bounds().y() == work_area.y())) {
- SingleAxisUnmaximize(target_state,
- target_state->GetRestoreBoundsInScreen());
- } else {
- gfx::Point origin = target->bounds().origin();
- wm::ConvertPointToScreen(target->parent(), &origin);
- SingleAxisMaximize(target_state,
- gfx::Rect(origin.x(),
- work_area.y(),
- target->bounds().width(),
- work_area.height()));
- }
- } else if (component == HTLEFT || component == HTRIGHT) {
- // Don't maximize horizontally if the window has a max width defined.
- if (max_size.width() != 0)
- return;
- if (target_state->HasRestoreBounds() &&
- (target->bounds().width() == work_area.width() &&
- target->bounds().x() == work_area.x())) {
- SingleAxisUnmaximize(target_state,
- target_state->GetRestoreBoundsInScreen());
- } else {
- gfx::Point origin = target->bounds().origin();
- wm::ConvertPointToScreen(target->parent(), &origin);
- SingleAxisMaximize(target_state,
- gfx::Rect(work_area.x(),
- origin.y(),
- work_area.width(),
- target->bounds().height()));
- }
- }
- }
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_event_handler.h b/chromium/ash/wm/workspace/workspace_event_handler.h
deleted file mode 100644
index e8507e167bf..00000000000
--- a/chromium/ash/wm/workspace/workspace_event_handler.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_H_
-#define ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_H_
-
-#include "ash/wm/toplevel_window_event_handler.h"
-#include "ash/wm/workspace/multi_window_resize_controller.h"
-
-namespace aura {
-class Window;
-}
-
-namespace ash {
-namespace wm {
-class WindowState;
-}
-
-namespace internal {
-
-class WorkspaceEventHandlerTestHelper;
-
-class WorkspaceEventHandler : public ToplevelWindowEventHandler {
- public:
- explicit WorkspaceEventHandler(aura::Window* owner);
- virtual ~WorkspaceEventHandler();
-
- // Overridden from ToplevelWindowEventHandler:
- virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
- virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
-
- private:
- friend class WorkspaceEventHandlerTestHelper;
-
- // Determines if |event| corresponds to a double click on either the top or
- // bottom vertical resize edge, and if so toggles the vertical height of the
- // window between its restored state and the full available height of the
- // workspace.
- void HandleVerticalResizeDoubleClick(wm::WindowState* window_state,
- ui::MouseEvent* event);
-
- MultiWindowResizeController multi_window_resize_controller_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkspaceEventHandler);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_H_
diff --git a/chromium/ash/wm/workspace/workspace_event_handler_test_helper.cc b/chromium/ash/wm/workspace/workspace_event_handler_test_helper.cc
deleted file mode 100644
index 55b707b4402..00000000000
--- a/chromium/ash/wm/workspace/workspace_event_handler_test_helper.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_event_handler_test_helper.h"
-
-namespace ash {
-namespace internal {
-
-WorkspaceEventHandlerTestHelper::WorkspaceEventHandlerTestHelper(
- WorkspaceEventHandler* handler)
- : handler_(handler) {
-}
-
-WorkspaceEventHandlerTestHelper::~WorkspaceEventHandlerTestHelper() {
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_event_handler_test_helper.h b/chromium/ash/wm/workspace/workspace_event_handler_test_helper.h
deleted file mode 100644
index 21e1adb981b..00000000000
--- a/chromium/ash/wm/workspace/workspace_event_handler_test_helper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_TEST_HELPER_H_
-#define ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_TEST_HELPER_H_
-
-#include "ash/wm/workspace/workspace_event_handler.h"
-
-namespace ash {
-namespace internal {
-
-class WorkspaceEventHandlerTestHelper {
- public:
- explicit WorkspaceEventHandlerTestHelper(WorkspaceEventHandler* handler);
- ~WorkspaceEventHandlerTestHelper();
-
- MultiWindowResizeController* resize_controller() {
- return &(handler_->multi_window_resize_controller_);
- }
-
- private:
- WorkspaceEventHandler* handler_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkspaceEventHandlerTestHelper);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_WORKSPACE_EVENT_HANDLER_TEST_HELPER_H_
diff --git a/chromium/ash/wm/workspace/workspace_event_handler_unittest.cc b/chromium/ash/wm/workspace/workspace_event_handler_unittest.cc
deleted file mode 100644
index feec4bdbc6b..00000000000
--- a/chromium/ash/wm/workspace/workspace_event_handler_unittest.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_event_handler.h"
-
-#include "ash/screen_ash.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace_controller.h"
-#include "ash/wm/workspace_controller_test_helper.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/test/event_generator.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window.h"
-#include "ui/base/hit_test.h"
-#include "ui/gfx/screen.h"
-
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
-namespace ash {
-namespace internal {
-
-class WorkspaceEventHandlerTest : public test::AshTestBase {
- public:
- WorkspaceEventHandlerTest() {}
- virtual ~WorkspaceEventHandlerTest() {}
-
- protected:
- aura::Window* CreateTestWindow(aura::WindowDelegate* delegate,
- const gfx::Rect& bounds) {
- aura::Window* window = new aura::Window(delegate);
- window->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window->Init(ui::LAYER_TEXTURED);
- ParentWindowInPrimaryRootWindow(window);
- window->SetBounds(bounds);
- window->Show();
- return window;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WorkspaceEventHandlerTest);
-};
-
-// Keeps track of the properties changed of a particular window.
-class WindowPropertyObserver : public aura::WindowObserver {
- public:
- explicit WindowPropertyObserver(aura::Window* window)
- : window_(window) {
- window->AddObserver(this);
- }
-
- virtual ~WindowPropertyObserver() {
- window_->RemoveObserver(this);
- }
-
- bool DidPropertyChange(const void* property) const {
- return std::find(properties_changed_.begin(),
- properties_changed_.end(),
- property) != properties_changed_.end();
- }
-
- private:
- virtual void OnWindowPropertyChanged(aura::Window* window,
- const void* key,
- intptr_t old) OVERRIDE {
- properties_changed_.push_back(key);
- }
-
- aura::Window* window_;
- std::vector<const void*> properties_changed_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowPropertyObserver);
-};
-
-TEST_F(WorkspaceEventHandlerTest, DoubleClickSingleAxisResizeEdge) {
- // Double clicking the vertical resize edge of a window should maximize it
- // vertically.
- gfx::Rect restored_bounds(10, 10, 50, 50);
- aura::test::TestWindowDelegate wd;
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, restored_bounds));
-
- wm::ActivateWindow(window.get());
-
- gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- window.get());
-
- // Double-click the top resize edge.
- wd.set_window_component(HTTOP);
- // On X a double click actually generates a drag between each press/release.
- // Explicitly trigger this path since we had bugs in dealing with it
- // correctly.
- generator.PressLeftButton();
- generator.ReleaseLeftButton();
- generator.set_flags(ui::EF_IS_DOUBLE_CLICK);
- generator.PressLeftButton();
- generator.MoveMouseTo(generator.current_location(), 1);
- generator.ReleaseLeftButton();
- gfx::Rect bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.x(), bounds_in_screen.x());
- EXPECT_EQ(restored_bounds.width(), bounds_in_screen.width());
- EXPECT_EQ(work_area.y(), bounds_in_screen.y());
- EXPECT_EQ(work_area.height(), bounds_in_screen.height());
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- // Single-axis maximization is not considered real maximization.
- EXPECT_FALSE(window_state->IsMaximized());
-
- // Restore.
- generator.DoubleClickLeftButton();
- bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.ToString(), bounds_in_screen.ToString());
- // Note that it should not even be restored at this point, it should have
- // also cleared the restore rectangle.
- EXPECT_FALSE(window_state->HasRestoreBounds());
-
- // Double-click the top resize edge again to maximize vertically, then double
- // click again to restore.
- generator.DoubleClickLeftButton();
- wd.set_window_component(HTCAPTION);
- generator.DoubleClickLeftButton();
- EXPECT_FALSE(window_state->IsMaximized());
- bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.ToString(), bounds_in_screen.ToString());
-
- // Double clicking the left resize edge should maximize horizontally.
- wd.set_window_component(HTLEFT);
- generator.DoubleClickLeftButton();
- bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.y(), bounds_in_screen.y());
- EXPECT_EQ(restored_bounds.height(), bounds_in_screen.height());
- EXPECT_EQ(work_area.x(), bounds_in_screen.x());
- EXPECT_EQ(work_area.width(), bounds_in_screen.width());
- // Single-axis maximization is not considered real maximization.
- EXPECT_FALSE(window_state->IsMaximized());
-
- // Restore.
- wd.set_window_component(HTCAPTION);
- generator.DoubleClickLeftButton();
- EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
-
-#if defined(OS_WIN)
- // Multi display test does not run on Win8 bot. crbug.com/247427.
- if (base::win::GetVersion() >= base::win::VERSION_WIN8)
- return;
-#endif
-
- // Verify the double clicking the resize edge works on 2nd display too.
- UpdateDisplay("200x200,400x300");
- gfx::Rect work_area2 = ScreenAsh::GetSecondaryDisplay().work_area();
- restored_bounds.SetRect(220,20, 50, 50);
- window->SetBoundsInScreen(restored_bounds, ScreenAsh::GetSecondaryDisplay());
- aura::Window* second_root = Shell::GetAllRootWindows()[1];
- EXPECT_EQ(second_root, window->GetRootWindow());
- aura::test::EventGenerator generator2(second_root, window.get());
-
- // Y-axis maximization.
- wd.set_window_component(HTTOP);
- generator2.PressLeftButton();
- generator2.ReleaseLeftButton();
- generator2.set_flags(ui::EF_IS_DOUBLE_CLICK);
- generator2.PressLeftButton();
- generator2.MoveMouseTo(generator.current_location(), 1);
- generator2.ReleaseLeftButton();
- generator.DoubleClickLeftButton();
- bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.x(), bounds_in_screen.x());
- EXPECT_EQ(restored_bounds.width(), bounds_in_screen.width());
- EXPECT_EQ(work_area2.y(), bounds_in_screen.y());
- EXPECT_EQ(work_area2.height(), bounds_in_screen.height());
- EXPECT_FALSE(window_state->IsMaximized());
-
- // Restore.
- wd.set_window_component(HTCAPTION);
- generator2.DoubleClickLeftButton();
- EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
-
- // X-axis maximization.
- wd.set_window_component(HTLEFT);
- generator2.DoubleClickLeftButton();
- bounds_in_screen = window->GetBoundsInScreen();
- EXPECT_EQ(restored_bounds.y(), bounds_in_screen.y());
- EXPECT_EQ(restored_bounds.height(), bounds_in_screen.height());
- EXPECT_EQ(work_area2.x(), bounds_in_screen.x());
- EXPECT_EQ(work_area2.width(), bounds_in_screen.width());
- EXPECT_FALSE(window_state->IsMaximized());
-
- // Restore.
- wd.set_window_component(HTCAPTION);
- generator2.DoubleClickLeftButton();
- EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-TEST_F(WorkspaceEventHandlerTest,
- DoubleClickSingleAxisDoesntResizeVerticalEdgeIfConstrained) {
- gfx::Rect restored_bounds(10, 10, 50, 50);
- aura::test::TestWindowDelegate wd;
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, restored_bounds));
-
- wm::ActivateWindow(window.get());
-
- gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
-
- wd.set_maximum_size(gfx::Size(0, 100));
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- window.get());
- // Double-click the top resize edge.
- wd.set_window_component(HTTOP);
- generator.DoubleClickLeftButton();
-
- // The size of the window should be unchanged.
- EXPECT_EQ(restored_bounds.y(), window->bounds().y());
- EXPECT_EQ(restored_bounds.height(), window->bounds().height());
-}
-
-TEST_F(WorkspaceEventHandlerTest,
- DoubleClickSingleAxisDoesntResizeHorizontalEdgeIfConstrained) {
- gfx::Rect restored_bounds(10, 10, 50, 50);
- aura::test::TestWindowDelegate wd;
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, restored_bounds));
-
- wm::ActivateWindow(window.get());
-
- gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
-
- wd.set_maximum_size(gfx::Size(100, 0));
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- window.get());
- // Double-click the top resize edge.
- wd.set_window_component(HTRIGHT);
- generator.DoubleClickLeftButton();
-
- // The size of the window should be unchanged.
- EXPECT_EQ(restored_bounds.x(), window->bounds().x());
- EXPECT_EQ(restored_bounds.width(), window->bounds().width());
-}
-
-TEST_F(WorkspaceEventHandlerTest, DoubleClickCaptionTogglesMaximize) {
- aura::test::TestWindowDelegate wd;
- scoped_ptr<aura::Window> window(
- CreateTestWindow(&wd, gfx::Rect(1, 2, 30, 40)));
- window->SetProperty(aura::client::kCanMaximizeKey, true);
- wd.set_window_component(HTCAPTION);
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- EXPECT_FALSE(window_state->IsMaximized());
- aura::Window* root = Shell::GetPrimaryRootWindow();
- aura::test::EventGenerator generator(root, window.get());
- generator.DoubleClickLeftButton();
- EXPECT_NE("1,2 30x40", window->bounds().ToString());
-
- EXPECT_TRUE(window_state->IsMaximized());
- generator.DoubleClickLeftButton();
-
- EXPECT_FALSE(window_state->IsMaximized());
- EXPECT_EQ("1,2 30x40", window->bounds().ToString());
-
- // Double-clicking the middle button shouldn't toggle the maximized state.
- WindowPropertyObserver observer(window.get());
- ui::MouseEvent press(ui::ET_MOUSE_PRESSED, generator.current_location(),
- generator.current_location(),
- ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK);
- aura::WindowEventDispatcher* dispatcher = root->GetDispatcher();
- dispatcher->AsRootWindowHostDelegate()->OnHostMouseEvent(&press);
- ui::MouseEvent release(ui::ET_MOUSE_RELEASED, generator.current_location(),
- generator.current_location(),
- ui::EF_IS_DOUBLE_CLICK);
- dispatcher->AsRootWindowHostDelegate()->OnHostMouseEvent(&release);
-
- EXPECT_FALSE(window_state->IsMaximized());
- EXPECT_EQ("1,2 30x40", window->bounds().ToString());
- EXPECT_FALSE(observer.DidPropertyChange(aura::client::kShowStateKey));
-}
-
-TEST_F(WorkspaceEventHandlerTest, DoubleTapCaptionTogglesMaximize) {
- aura::test::TestWindowDelegate wd;
- gfx::Rect bounds(10, 20, 30, 40);
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, bounds));
- window->SetProperty(aura::client::kCanMaximizeKey, true);
- wd.set_window_component(HTCAPTION);
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- EXPECT_FALSE(window_state->IsMaximized());
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- window.get());
- generator.GestureTapAt(gfx::Point(25, 25));
- generator.GestureTapAt(gfx::Point(25, 25));
- RunAllPendingInMessageLoop();
- EXPECT_NE(bounds.ToString(), window->bounds().ToString());
- EXPECT_TRUE(window_state->IsMaximized());
-
- generator.GestureTapAt(gfx::Point(5, 5));
- generator.GestureTapAt(gfx::Point(10, 10));
-
- EXPECT_FALSE(window_state->IsMaximized());
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
-}
-
-// Verifies deleting the window while dragging doesn't crash.
-TEST_F(WorkspaceEventHandlerTest, DeleteWhenDragging) {
- // Create a large window in the background. This is necessary so that when we
- // delete |window| WorkspaceEventHandler is still the active event handler.
- aura::test::TestWindowDelegate wd2;
- scoped_ptr<aura::Window> window2(
- CreateTestWindow(&wd2, gfx::Rect(0, 0, 500, 500)));
-
- aura::test::TestWindowDelegate wd;
- const gfx::Rect bounds(10, 20, 30, 40);
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, bounds));
- wd.set_window_component(HTCAPTION);
- aura::test::EventGenerator generator(window->GetRootWindow());
- generator.MoveMouseToCenterOf(window.get());
- generator.PressLeftButton();
- generator.MoveMouseTo(generator.current_location() + gfx::Vector2d(50, 50));
- DCHECK_NE(bounds.origin().ToString(), window->bounds().origin().ToString());
- window.reset();
- generator.MoveMouseTo(generator.current_location() + gfx::Vector2d(50, 50));
-}
-
-// Verifies deleting the window while in a run loop doesn't crash.
-TEST_F(WorkspaceEventHandlerTest, DeleteWhileInRunLoop) {
- aura::test::TestWindowDelegate wd;
- const gfx::Rect bounds(10, 20, 30, 40);
- scoped_ptr<aura::Window> window(CreateTestWindow(&wd, bounds));
- wd.set_window_component(HTCAPTION);
-
- ASSERT_TRUE(aura::client::GetWindowMoveClient(window->parent()));
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, window.get());
- aura::client::GetWindowMoveClient(window->parent())
- ->RunMoveLoop(window.release(),
- gfx::Vector2d(),
- aura::client::WINDOW_MOVE_SOURCE_MOUSE);
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_layout_manager.cc b/chromium/ash/wm/workspace/workspace_layout_manager.cc
deleted file mode 100644
index fe7d748d19b..00000000000
--- a/chromium/ash/wm/workspace/workspace_layout_manager.cc
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_layout_manager.h"
-
-#include "ash/display/display_controller.h"
-#include "ash/root_window_controller.h"
-#include "ash/screen_ash.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shell.h"
-#include "ash/wm/always_on_top_controller.h"
-#include "ash/wm/base_layout_manager.h"
-#include "ash/wm/window_animations.h"
-#include "ash/wm/window_positioner.h"
-#include "ash/wm/window_properties.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_observer.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/events/event.h"
-#include "ui/views/corewm/window_util.h"
-
-using aura::Window;
-
-namespace ash {
-
-namespace internal {
-
-namespace {
-
-// This specifies how much percent 30% of a window rect (width / height)
-// must be visible when the window is added to the workspace.
-const float kMinimumPercentOnScreenArea = 0.3f;
-
-void MoveToDisplayForRestore(wm::WindowState* window_state) {
- if (!window_state->HasRestoreBounds())
- return;
- const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen();
-
- // Move only if the restore bounds is outside of
- // the display. There is no information about in which
- // display it should be restored, so this is best guess.
- // TODO(oshima): Restore information should contain the
- // work area information like WindowResizer does for the
- // last window location.
- gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window_state->window()).bounds();
-
- if (!display_area.Intersects(restore_bounds)) {
- DisplayController* display_controller =
- Shell::GetInstance()->display_controller();
- const gfx::Display& display =
- display_controller->GetDisplayMatching(restore_bounds);
- aura::Window* new_root =
- display_controller->GetRootWindowForDisplayId(display.id());
- if (new_root != window_state->window()->GetRootWindow()) {
- aura::Window* new_container =
- Shell::GetContainer(new_root, window_state->window()->parent()->id());
- new_container->AddChild(window_state->window());
- }
- }
-}
-
-} // namespace
-
-WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window)
- : BaseLayoutManager(window->GetRootWindow()),
- shelf_(NULL),
- window_(window),
- work_area_in_parent_(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window->parent())),
- is_fullscreen_(GetRootWindowController(
- window->GetRootWindow())->GetWindowForFullscreenMode() != NULL) {
-}
-
-WorkspaceLayoutManager::~WorkspaceLayoutManager() {
-}
-
-void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) {
- shelf_ = shelf;
-}
-
-void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) {
- AdjustWindowBoundsWhenAdded(wm::GetWindowState(child));
- BaseLayoutManager::OnWindowAddedToLayout(child);
- UpdateShelfVisibility();
- UpdateFullscreenState();
- WindowPositioner::RearrangeVisibleWindowOnShow(child);
-}
-
-void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) {
- BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
- if (child->TargetVisibility())
- WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child);
-}
-
-void WorkspaceLayoutManager::OnWindowRemovedFromLayout(Window* child) {
- BaseLayoutManager::OnWindowRemovedFromLayout(child);
- UpdateShelfVisibility();
- UpdateFullscreenState();
-}
-
-void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child,
- bool visible) {
- BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible);
- if (child->TargetVisibility()) {
- WindowPositioner::RearrangeVisibleWindowOnShow(child);
- } else {
- if (wm::GetWindowState(child)->IsFullscreen())
- UpdateFullscreenState();
- WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child);
- }
- UpdateShelfVisibility();
-}
-
-void WorkspaceLayoutManager::SetChildBounds(
- Window* child,
- const gfx::Rect& requested_bounds) {
- wm::WindowState* window_state = wm::GetWindowState(child);
- if (window_state->is_dragged()) {
- SetChildBoundsDirect(child, requested_bounds);
- } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
- // Some windows rely on this to set their initial bounds.
- // Non-maximized/full-screen windows have their size constrained to the
- // work-area.
- gfx::Rect child_bounds(requested_bounds);
- child_bounds.set_width(std::min(work_area_in_parent_.width(),
- child_bounds.width()));
- child_bounds.set_height(std::min(work_area_in_parent_.height(),
- child_bounds.height()));
- AdjustSnappedBounds(window_state, &child_bounds);
- SetChildBoundsDirect(child, child_bounds);
- }
- UpdateShelfVisibility();
-}
-
-void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
- const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_->parent()));
- if (work_area != work_area_in_parent_) {
- AdjustAllWindowsBoundsForWorkAreaChange(
- ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
- }
-}
-
-void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
- const void* key,
- intptr_t old) {
- if (key == aura::client::kAlwaysOnTopKey &&
- window->GetProperty(aura::client::kAlwaysOnTopKey)) {
- GetRootWindowController(window->GetRootWindow())->
- always_on_top_controller()->GetContainer(window)->AddChild(window);
- }
-}
-
-void WorkspaceLayoutManager::OnWindowStackingChanged(aura::Window* window) {
- BaseLayoutManager::OnWindowStackingChanged(window);
- UpdateShelfVisibility();
- UpdateFullscreenState();
-}
-
-void WorkspaceLayoutManager::OnWindowShowTypeChanged(
- wm::WindowState* window_state,
- wm::WindowShowType old_type) {
- ui::WindowShowState old_state = ToWindowShowState(old_type);
- ui::WindowShowState new_state = window_state->GetShowState();
- if (old_state != ui::SHOW_STATE_MINIMIZED &&
- !window_state->HasRestoreBounds() &&
- window_state->IsMaximizedOrFullscreen() &&
- !wm::WindowState::IsMaximizedOrFullscreenState(old_state)) {
- window_state->SaveCurrentBoundsForRestore();
- }
- // When restoring from a minimized state, we want to restore to the
- // previous (maybe L/R maximized) state. Since we do also want to keep the
- // restore rectangle, we set the restore rectangle to the rectangle we want
- // to restore to and restore it after we switched so that it is preserved.
- gfx::Rect restore;
- if (old_state == ui::SHOW_STATE_MINIMIZED &&
- (new_state == ui::SHOW_STATE_NORMAL ||
- new_state == ui::SHOW_STATE_DEFAULT) &&
- window_state->HasRestoreBounds() &&
- !window_state->always_restores_to_restore_bounds()) {
- restore = window_state->GetRestoreBoundsInScreen();
- window_state->SaveCurrentBoundsForRestore();
- }
- // Notify observers that fullscreen state may be changing.
- if (old_state != new_state &&
- (new_state == ui::SHOW_STATE_FULLSCREEN ||
- old_state == ui::SHOW_STATE_FULLSCREEN)) {
- UpdateFullscreenState();
- }
-
- UpdateBoundsFromShowState(window_state, old_state);
- ShowStateChanged(window_state, old_state);
-
- // Set the restore rectangle to the previously set restore rectangle.
- if (!restore.IsEmpty())
- window_state->SetRestoreBoundsInScreen(restore);
-}
-
-void WorkspaceLayoutManager::ShowStateChanged(
- wm::WindowState* state,
- ui::WindowShowState last_show_state) {
- BaseLayoutManager::ShowStateChanged(state, last_show_state);
- UpdateShelfVisibility();
-}
-
-void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
- AdjustWindowReason reason) {
- work_area_in_parent_ =
- ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent());
- BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason);
-}
-
-void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange(
- wm::WindowState* window_state,
- AdjustWindowReason reason) {
- if (window_state->is_dragged())
- return;
-
- // Do not cross fade here: the window's layer hierarchy may be messed up for
- // the transition between mirroring and extended. See also: crbug.com/267698
- // TODO(oshima): Differentiate display change and shelf visibility change, and
- // bring back CrossFade animation.
- if (window_state->IsMaximized() &&
- reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) {
- SetChildBoundsDirect(window_state->window(),
- ScreenAsh::GetMaximizedWindowBoundsInParent(
- window_state->window()->parent()->parent()));
- return;
- }
-
- if (SetMaximizedOrFullscreenBounds(window_state))
- return;
-
- gfx::Rect bounds = window_state->window()->bounds();
- switch (reason) {
- case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
- // The work area may be smaller than the full screen. Put as much of the
- // window as possible within the display area.
- bounds.AdjustToFit(work_area_in_parent_);
- break;
- case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
- ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
- work_area_in_parent_, &bounds);
- break;
- }
- AdjustSnappedBounds(window_state, &bounds);
- if (window_state->window()->bounds() != bounds)
- SetChildBoundsAnimated(window_state->window(), bounds);
-}
-
-void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
- wm::WindowState* window_state) {
- // Don't adjust window bounds if the bounds are empty as this
- // happens when a new views::Widget is created.
- // When a window is dragged and dropped onto a different
- // root window, the bounds will be updated after they are added
- // to the root window.
- if (window_state->window()->bounds().IsEmpty())
- return;
-
- if (window_state->is_dragged())
- return;
-
- if (SetMaximizedOrFullscreenBounds(window_state))
- return;
-
- Window* window = window_state->window();
- gfx::Rect bounds = window->bounds();
- int min_width = bounds.width() * kMinimumPercentOnScreenArea;
- int min_height = bounds.height() * kMinimumPercentOnScreenArea;
- // Use entire display instead of workarea because the workarea can
- // be further shrunk by the docked area. The logic ensures 30%
- // visibility which should be enough to see where the window gets
- // moved.
- gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window);
-
- ash::wm::AdjustBoundsToEnsureWindowVisibility(
- display_area, min_width, min_height, &bounds);
- AdjustSnappedBounds(window_state, &bounds);
- if (window->bounds() != bounds)
- window->SetBounds(bounds);
-}
-
-void WorkspaceLayoutManager::UpdateShelfVisibility() {
- if (shelf_)
- shelf_->UpdateVisibilityState();
-}
-
-void WorkspaceLayoutManager::UpdateFullscreenState() {
- bool is_fullscreen = GetRootWindowController(
- window_->GetRootWindow())->GetWindowForFullscreenMode() != NULL;
- if (is_fullscreen != is_fullscreen_) {
- ash::Shell::GetInstance()->NotifyFullscreenStateChange(
- is_fullscreen, window_->GetRootWindow());
- is_fullscreen_ = is_fullscreen;
- }
-}
-
-void WorkspaceLayoutManager::UpdateBoundsFromShowState(
- wm::WindowState* window_state,
- ui::WindowShowState last_show_state) {
- aura::Window* window = window_state->window();
- // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in
- // these calculation.
- // TODO(varkha): Change the switch statement below to use wm::WindowShowType.
- switch (window_state->GetShowState()) {
- case ui::SHOW_STATE_DEFAULT:
- case ui::SHOW_STATE_NORMAL: {
- // Make sure that the part of the window is always visible
- // when restored.
- gfx::Rect bounds_in_parent;
- if (window_state->HasRestoreBounds()) {
- bounds_in_parent = window_state->GetRestoreBoundsInParent();
- ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
- work_area_in_parent_, &bounds_in_parent);
- } else {
- // Minimized windows have no restore bounds.
- // Use the current bounds instead.
- bounds_in_parent = window->bounds();
- ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
- work_area_in_parent_, &bounds_in_parent);
- // Don't start animation if the bounds didn't change.
- if (bounds_in_parent == window->bounds())
- bounds_in_parent.SetRect(0, 0, 0, 0);
- }
- if (!bounds_in_parent.IsEmpty()) {
- if ((last_show_state == ui::SHOW_STATE_DEFAULT ||
- last_show_state == ui::SHOW_STATE_NORMAL) &&
- window_state->IsSnapped()) {
- AdjustSnappedBounds(window_state, &bounds_in_parent);
- SetChildBoundsAnimated(window, bounds_in_parent);
- } else {
- gfx::Rect new_bounds = BaseLayoutManager::BoundsWithScreenEdgeVisible(
- window->parent()->parent(),
- bounds_in_parent);
- if (last_show_state == ui::SHOW_STATE_MINIMIZED)
- SetChildBoundsDirect(window, new_bounds);
- else
- CrossFadeToBounds(window, new_bounds);
- }
- }
- window_state->ClearRestoreBounds();
- break;
- }
-
- case ui::SHOW_STATE_MAXIMIZED: {
- MoveToDisplayForRestore(window_state);
- gfx::Rect new_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent(
- window->parent()->parent());
- // If the window is restored from minimized state, do not make the cross
- // fade animation and set the child bounds directly. The restoring
- // animation will be done by ash/wm/window_animations.cc.
- if (last_show_state == ui::SHOW_STATE_MINIMIZED)
- SetChildBoundsDirect(window, new_bounds);
- else
- CrossFadeToBounds(window, new_bounds);
- break;
- }
-
- case ui::SHOW_STATE_FULLSCREEN: {
- MoveToDisplayForRestore(window_state);
- gfx::Rect new_bounds = ScreenAsh::GetDisplayBoundsInParent(
- window->parent()->parent());
- if (window_state->animate_to_fullscreen() &&
- last_show_state != ui::SHOW_STATE_MINIMIZED) {
- CrossFadeToBounds(window, new_bounds);
- } else {
- SetChildBoundsDirect(window, new_bounds);
- }
- break;
- }
-
- default:
- break;
- }
-}
-
-bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds(
- wm::WindowState* window_state) {
- DCHECK(!window_state->is_dragged());
-
- // During animations there is a transform installed on the workspace
- // windows. For this reason this code uses the parent so that the transform is
- // ignored.
- if (window_state->IsMaximized()) {
- SetChildBoundsDirect(
- window_state->window(), ScreenAsh::GetMaximizedWindowBoundsInParent(
- window_state->window()->parent()->parent()));
- return true;
- }
- if (window_state->IsFullscreen()) {
- SetChildBoundsDirect(
- window_state->window(),
- ScreenAsh::GetDisplayBoundsInParent(
- window_state->window()->parent()->parent()));
- return true;
- }
- return false;
-}
-
-void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state,
- gfx::Rect* bounds) {
- if (window_state->is_dragged() || !window_state->IsSnapped())
- return;
- gfx::Rect maximized_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent(
- window_state->window()->parent()->parent());
- if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED)
- bounds->set_x(maximized_bounds.x());
- else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED)
- bounds->set_x(maximized_bounds.right() - bounds->width());
- bounds->set_y(maximized_bounds.y());
- // TODO(varkha): Set width to 50% here for snapped windows.
- bounds->set_height(maximized_bounds.height());
-}
-
-void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child,
- const gfx::Rect& bounds) {
- const int kBoundsChangeSlideDurationMs = 120;
-
- ui::Layer* layer = child->layer();
- ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
- slide_settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- slide_settings.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs));
- SetChildBoundsDirect(child, bounds);
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_layout_manager.h b/chromium/ash/wm/workspace/workspace_layout_manager.h
deleted file mode 100644
index ab4876c5b2e..00000000000
--- a/chromium/ash/wm/workspace/workspace_layout_manager.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_WORKSPACE_LAYOUT_MANAGER_H_
-#define ASH_WM_WORKSPACE_WORKSPACE_LAYOUT_MANAGER_H_
-
-#include <set>
-
-#include "ash/shell_observer.h"
-#include "ash/wm/base_layout_manager.h"
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/aura/window_observer.h"
-#include "ui/gfx/rect.h"
-
-namespace aura {
-class RootWindow;
-class Window;
-}
-
-namespace ui {
-class Layer;
-}
-
-namespace ash {
-
-namespace internal {
-
-class ShelfLayoutManager;
-
-// LayoutManager used on the window created for a workspace.
-class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager {
- public:
- explicit WorkspaceLayoutManager(aura::Window* window);
- virtual ~WorkspaceLayoutManager();
-
- void SetShelf(internal::ShelfLayoutManager* shelf);
-
- // Overridden from aura::LayoutManager:
- virtual void OnWindowResized() OVERRIDE {}
- virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
- virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
- virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE;
- virtual void OnChildWindowVisibilityChanged(aura::Window* child,
- bool visibile) OVERRIDE;
- virtual void SetChildBounds(aura::Window* child,
- const gfx::Rect& requested_bounds) OVERRIDE;
-
- // ash::ShellObserver overrides:
- virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE;
-
- // Overriden from WindowObserver:
- virtual void OnWindowPropertyChanged(aura::Window* window,
- const void* key,
- intptr_t old) OVERRIDE;
- virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE;
-
- // WindowStateObserver overrides:
- virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
- wm::WindowShowType old_type) OVERRIDE;
-
- private:
- // Overridden from BaseLayoutManager:
- virtual void ShowStateChanged(wm::WindowState* window_state,
- ui::WindowShowState last_show_state) OVERRIDE;
- virtual void AdjustAllWindowsBoundsForWorkAreaChange(
- AdjustWindowReason reason) OVERRIDE;
- virtual void AdjustWindowBoundsForWorkAreaChange(
- wm::WindowState* window_state,
- AdjustWindowReason reason) OVERRIDE;
-
- void AdjustWindowBoundsWhenAdded(wm::WindowState* window_state);
-
- // Updates the visibility state of the shelf.
- void UpdateShelfVisibility();
-
- // Updates the fullscreen state of the workspace and notifies Shell if it
- // has changed.
- void UpdateFullscreenState();
-
- // Updates the bounds of the window for a show state change from
- // |last_show_state|.
- void UpdateBoundsFromShowState(wm::WindowState* window_state,
- ui::WindowShowState last_show_state);
-
- // If |window_state| is maximized or fullscreen the bounds of the
- // window are set and true is returned. Does nothing otherwise.
- bool SetMaximizedOrFullscreenBounds(wm::WindowState* window_state);
-
- // Adjusts the |bounds| so that they are flush with the edge of the
- // workspace if the window represented by |window_state| is side snapped.
- void AdjustSnappedBounds(wm::WindowState* window_state, gfx::Rect* bounds);
-
- // Animates the window bounds to |bounds|.
- void SetChildBoundsAnimated(aura::Window* child, const gfx::Rect& bounds);
-
- internal::ShelfLayoutManager* shelf_;
- aura::Window* window_;
-
- // The work area. Cached to avoid unnecessarily moving windows during a
- // workspace switch.
- gfx::Rect work_area_in_parent_;
-
- // True if this workspace is currently in fullscreen mode.
- bool is_fullscreen_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManager);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_WORKSPACE_LAYOUT_MANAGER_H_
diff --git a/chromium/ash/wm/workspace/workspace_layout_manager_unittest.cc b/chromium/ash/wm/workspace/workspace_layout_manager_unittest.cc
deleted file mode 100644
index d12fb15bb79..00000000000
--- a/chromium/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ /dev/null
@@ -1,481 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_layout_manager.h"
-
-#include "ash/display/display_layout.h"
-#include "ash/display/display_manager.h"
-#include "ash/root_window_controller.h"
-#include "ash/screen_ash.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shelf/shelf_widget.h"
-#include "ash/shell.h"
-#include "ash/shell_observer.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/test/test_windows.h"
-#include "ui/aura/window.h"
-#include "ui/gfx/insets.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-
-namespace ash {
-namespace {
-
-class MaximizeDelegateView : public views::WidgetDelegateView {
- public:
- MaximizeDelegateView(const gfx::Rect& initial_bounds)
- : initial_bounds_(initial_bounds) {
- }
- virtual ~MaximizeDelegateView() {}
-
- virtual bool GetSavedWindowPlacement(
- const views::Widget* widget,
- gfx::Rect* bounds,
- ui::WindowShowState* show_state) const OVERRIDE {
- *bounds = initial_bounds_;
- *show_state = ui::SHOW_STATE_MAXIMIZED;
- return true;
- }
-
- private:
- const gfx::Rect initial_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(MaximizeDelegateView);
-};
-
-class TestShellObserver : public ShellObserver {
- public:
- TestShellObserver() : call_count_(0),
- is_fullscreen_(false) {
- Shell::GetInstance()->AddShellObserver(this);
- }
-
- virtual ~TestShellObserver() {
- Shell::GetInstance()->RemoveShellObserver(this);
- }
-
- virtual void OnFullscreenStateChanged(bool is_fullscreen,
- aura::Window* root_window) OVERRIDE {
- call_count_++;
- is_fullscreen_ = is_fullscreen;
- }
-
- int call_count() const {
- return call_count_;
- }
-
- bool is_fullscreen() const {
- return is_fullscreen_;
- }
-
- private:
- int call_count_;
- bool is_fullscreen_;
-
- DISALLOW_COPY_AND_ASSIGN(TestShellObserver);
-};
-
-} // namespace
-
-typedef test::AshTestBase WorkspaceLayoutManagerTest;
-
-// Verifies that a window containing a restore coordinate will be restored to
-// to the size prior to minimize, keeping the restore rectangle in tact (if
-// there is one).
-TEST_F(WorkspaceLayoutManagerTest, RestoreFromMinimizeKeepsRestore) {
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 3, 4)));
- gfx::Rect bounds(10, 15, 25, 35);
- window->SetBounds(bounds);
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- // This will not be used for un-minimizing window.
- window_state->SetRestoreBoundsInScreen(gfx::Rect(0, 0, 100, 100));
- window_state->Minimize();
- window_state->Restore();
- EXPECT_EQ("0,0 100x100", window_state->GetRestoreBoundsInScreen().ToString());
- EXPECT_EQ("10,15 25x35", window.get()->bounds().ToString());
-
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("400x300,500x400");
- window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
- ScreenAsh::GetSecondaryDisplay());
- EXPECT_EQ(Shell::GetAllRootWindows()[1], window->GetRootWindow());
- window_state->Minimize();
- // This will not be used for un-minimizing window.
- window_state->SetRestoreBoundsInScreen(gfx::Rect(0, 0, 100, 100));
- window_state->Restore();
- EXPECT_EQ("600,0 100x100", window->GetBoundsInScreen().ToString());
-
- // Make sure the unminimized window moves inside the display when
- // 2nd display is disconnected.
- window_state->Minimize();
- UpdateDisplay("400x300");
- window_state->Restore();
- EXPECT_EQ(Shell::GetPrimaryRootWindow(), window->GetRootWindow());
- EXPECT_TRUE(
- Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
-}
-
-TEST_F(WorkspaceLayoutManagerTest, KeepMinimumVisibilityInDisplays) {
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("300x400,400x500");
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-
- DisplayLayout layout(DisplayLayout::TOP, 0);
- Shell::GetInstance()->display_manager()->
- SetLayoutForCurrentDisplays(layout);
- EXPECT_EQ("0,-500 400x500", root_windows[1]->GetBoundsInScreen().ToString());
-
- scoped_ptr<aura::Window> window1(
- CreateTestWindowInShellWithBounds(gfx::Rect(10, -400, 200, 200)));
- EXPECT_EQ("10,-400 200x200", window1->GetBoundsInScreen().ToString());
-
- // Make sure the caption is visible.
- scoped_ptr<aura::Window> window2(
- CreateTestWindowInShellWithBounds(gfx::Rect(10, -600, 200, 200)));
- EXPECT_EQ("10,-500 200x200", window2->GetBoundsInScreen().ToString());
-}
-
-TEST_F(WorkspaceLayoutManagerTest, KeepRestoredWindowInDisplay) {
- if (!SupportsHostWindowResize())
- return;
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- // Maximized -> Normal transition.
- window_state->Maximize();
- window_state->SetRestoreBoundsInScreen(gfx::Rect(-100, -100, 30, 40));
- window_state->Restore();
- EXPECT_TRUE(
- Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
- // Y bounds should not be negative.
- EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
-
- // Minimized -> Normal transition.
- window->SetBounds(gfx::Rect(-100, -100, 30, 40));
- window_state->Minimize();
- EXPECT_FALSE(
- Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
- EXPECT_EQ("-100,-100 30x40", window->bounds().ToString());
- window->Show();
- EXPECT_TRUE(
- Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
- // Y bounds should not be negative.
- EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
-
- // Fullscreen -> Normal transition.
- window->SetBounds(gfx::Rect(0, 0, 30, 40)); // reset bounds.
- ASSERT_EQ("0,0 30x40", window->bounds().ToString());
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
- EXPECT_EQ(window->bounds(), window->GetRootWindow()->bounds());
- window_state->SetRestoreBoundsInScreen(gfx::Rect(-100, -100, 30, 40));
- window_state->Restore();
- EXPECT_TRUE(
- Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
- // Y bounds should not be negative.
- EXPECT_EQ("-20,0 30x40", window->bounds().ToString());
-}
-
-TEST_F(WorkspaceLayoutManagerTest, MaximizeInDisplayToBeRestored) {
- if (!SupportsMultipleDisplays())
- return;
- UpdateDisplay("300x400,400x500");
-
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
- EXPECT_EQ(root_windows[0], window->GetRootWindow());
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));
- // Maximize the window in 2nd display as the restore bounds
- // is inside 2nd display.
- window_state->Maximize();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("300,0 400x453", window->GetBoundsInScreen().ToString());
-
- window_state->Restore();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("400,0 30x40", window->GetBoundsInScreen().ToString());
-
- // If the restore bounds intersects with the current display,
- // don't move.
- window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
- window_state->Maximize();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("300,0 400x453", window->GetBoundsInScreen().ToString());
-
- window_state->Restore();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("280,0 30x40", window->GetBoundsInScreen().ToString());
-
- // Restoring widget state.
- scoped_ptr<views::Widget> w1(new views::Widget);
- views::Widget::InitParams params;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.delegate = new MaximizeDelegateView(gfx::Rect(400, 0, 30, 40));
- params.context = root_windows[0];
- w1->Init(params);
- w1->Show();
- EXPECT_TRUE(w1->IsMaximized());
- EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
- EXPECT_EQ("300,0 400x453", w1->GetWindowBoundsInScreen().ToString());
- w1->Restore();
- EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
- EXPECT_EQ("400,0 30x40", w1->GetWindowBoundsInScreen().ToString());
-}
-
-TEST_F(WorkspaceLayoutManagerTest, FullscreenInDisplayToBeRestored) {
- if (!SupportsMultipleDisplays())
- return;
- UpdateDisplay("300x400,400x500");
-
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
- EXPECT_EQ(root_windows[0], window->GetRootWindow());
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));
- // Maximize the window in 2nd display as the restore bounds
- // is inside 2nd display.
- window->SetProperty(aura::client::kShowStateKey,
- ui::SHOW_STATE_FULLSCREEN);
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("300,0 400x500", window->GetBoundsInScreen().ToString());
-
- window_state->Restore();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("400,0 30x40", window->GetBoundsInScreen().ToString());
-
- // If the restore bounds intersects with the current display,
- // don't move.
- window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
- window->SetProperty(aura::client::kShowStateKey,
- ui::SHOW_STATE_FULLSCREEN);
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("300,0 400x500", window->GetBoundsInScreen().ToString());
-
- window_state->Restore();
- EXPECT_EQ(root_windows[1], window->GetRootWindow());
- EXPECT_EQ("280,0 30x40", window->GetBoundsInScreen().ToString());
-}
-
-// WindowObserver implementation used by DontClobberRestoreBoundsWindowObserver.
-// This code mirrors what BrowserFrameAsh does. In particular when this code
-// sees the window was maximized it changes the bounds of a secondary
-// window. The secondary window mirrors the status window.
-class DontClobberRestoreBoundsWindowObserver : public aura::WindowObserver {
- public:
- DontClobberRestoreBoundsWindowObserver() : window_(NULL) {}
-
- void set_window(aura::Window* window) { window_ = window; }
-
- virtual void OnWindowPropertyChanged(aura::Window* window,
- const void* key,
- intptr_t old) OVERRIDE {
- if (!window_)
- return;
-
- if (wm::GetWindowState(window)->IsMaximized()) {
- aura::Window* w = window_;
- window_ = NULL;
-
- gfx::Rect shelf_bounds(Shell::GetPrimaryRootWindowController()->
- GetShelfLayoutManager()->GetIdealBounds());
- const gfx::Rect& window_bounds(w->bounds());
- w->SetBounds(gfx::Rect(window_bounds.x(), shelf_bounds.y() - 1,
- window_bounds.width(), window_bounds.height()));
- }
- }
-
- private:
- aura::Window* window_;
-
- DISALLOW_COPY_AND_ASSIGN(DontClobberRestoreBoundsWindowObserver);
-};
-
-// Creates a window, maximized the window and from within the maximized
-// notification sets the bounds of a window to overlap the shelf. Verifies this
-// doesn't effect the restore bounds.
-TEST_F(WorkspaceLayoutManagerTest, DontClobberRestoreBounds) {
- DontClobberRestoreBoundsWindowObserver window_observer;
- scoped_ptr<aura::Window> window(new aura::Window(NULL));
- window->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window->Init(ui::LAYER_TEXTURED);
- window->SetBounds(gfx::Rect(10, 20, 30, 40));
- // NOTE: for this test to exercise the failure the observer needs to be added
- // before the parent set. This mimics what BrowserFrameAsh does.
- window->AddObserver(&window_observer);
- ParentWindowInPrimaryRootWindow(window.get());
- window->Show();
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->Activate();
-
- scoped_ptr<aura::Window> window2(
- CreateTestWindowInShellWithBounds(gfx::Rect(12, 20, 30, 40)));
- window->AddTransientChild(window2.get());
- window2->Show();
-
- window_observer.set_window(window2.get());
- window_state->Maximize();
- EXPECT_EQ("10,20 30x40",
- window_state->GetRestoreBoundsInScreen().ToString());
- window->RemoveObserver(&window_observer);
-}
-
-// Verifies when a window is maximized all descendant windows have a size.
-TEST_F(WorkspaceLayoutManagerTest, ChildBoundsResetOnMaximize) {
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 30, 40)));
- window->Show();
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->Activate();
- scoped_ptr<aura::Window> child_window(
- aura::test::CreateTestWindowWithBounds(gfx::Rect(5, 6, 7, 8),
- window.get()));
- child_window->Show();
- window_state->Maximize();
- EXPECT_EQ("5,6 7x8", child_window->bounds().ToString());
-}
-
-TEST_F(WorkspaceLayoutManagerTest, WindowShouldBeOnScreenWhenAdded) {
- // Normal window bounds shouldn't be changed.
- gfx::Rect window_bounds(100, 100, 200, 200);
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(window_bounds));
- EXPECT_EQ(window_bounds, window->bounds());
-
- // If the window is out of the workspace, it would be moved on screen.
- gfx::Rect root_window_bounds =
- Shell::GetInstance()->GetPrimaryRootWindow()->bounds();
- window_bounds.Offset(root_window_bounds.width(), root_window_bounds.height());
- ASSERT_FALSE(window_bounds.Intersects(root_window_bounds));
- scoped_ptr<aura::Window> out_window(
- CreateTestWindowInShellWithBounds(window_bounds));
- EXPECT_EQ(window_bounds.size(), out_window->bounds().size());
- gfx::Rect bounds = out_window->bounds();
- bounds.Intersect(root_window_bounds);
-
- // 30% of the window edge must be visible.
- EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
- EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
-
- aura::Window* parent = out_window->parent();
- parent->RemoveChild(out_window.get());
- out_window->SetBounds(gfx::Rect(-200, -200, 200, 200));
- // UserHasChangedWindowPositionOrSize flag shouldn't turn off this behavior.
- wm::GetWindowState(window.get())->set_bounds_changed_by_user(true);
- parent->AddChild(out_window.get());
- EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
- EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
-
- // Make sure we always make more than 1/3 of the window edge visible even
- // if the initial bounds intersects with display.
- window_bounds.SetRect(-150, -150, 200, 200);
- bounds = window_bounds;
- bounds.Intersect(root_window_bounds);
-
- // Make sure that the initial bounds' visible area is less than 26%
- // so that the auto adjustment logic kicks in.
- ASSERT_LT(bounds.width(), out_window->bounds().width() * 0.26);
- ASSERT_LT(bounds.height(), out_window->bounds().height() * 0.26);
- ASSERT_TRUE(window_bounds.Intersects(root_window_bounds));
-
- scoped_ptr<aura::Window> partially_out_window(
- CreateTestWindowInShellWithBounds(window_bounds));
- EXPECT_EQ(window_bounds.size(), partially_out_window->bounds().size());
- bounds = partially_out_window->bounds();
- bounds.Intersect(root_window_bounds);
- EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
- EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
-
- // Make sure the window whose 30% width/height is bigger than display
- // will be placed correctly.
- window_bounds.SetRect(-1900, -1900, 3000, 3000);
- scoped_ptr<aura::Window> window_bigger_than_display(
- CreateTestWindowInShellWithBounds(window_bounds));
- EXPECT_GE(root_window_bounds.width(),
- window_bigger_than_display->bounds().width());
- EXPECT_GE(root_window_bounds.height(),
- window_bigger_than_display->bounds().height());
-
- bounds = window_bigger_than_display->bounds();
- bounds.Intersect(root_window_bounds);
- EXPECT_GT(bounds.width(), out_window->bounds().width() * 0.29);
- EXPECT_GT(bounds.height(), out_window->bounds().height() * 0.29);
-}
-
-// Verifies the size of a window is enforced to be smaller than the work area.
-TEST_F(WorkspaceLayoutManagerTest, SizeToWorkArea) {
- // Normal window bounds shouldn't be changed.
- gfx::Size work_area(
- Shell::GetScreen()->GetPrimaryDisplay().work_area().size());
- const gfx::Rect window_bounds(
- 100, 101, work_area.width() + 1, work_area.height() + 2);
- scoped_ptr<aura::Window> window(
- CreateTestWindowInShellWithBounds(window_bounds));
- EXPECT_EQ(gfx::Rect(gfx::Point(100, 101), work_area).ToString(),
- window->bounds().ToString());
-
- // Directly setting the bounds triggers a slightly different code path. Verify
- // that too.
- window->SetBounds(window_bounds);
- EXPECT_EQ(gfx::Rect(gfx::Point(100, 101), work_area).ToString(),
- window->bounds().ToString());
-}
-
-TEST_F(WorkspaceLayoutManagerTest, NotifyFullscreenChanges) {
- TestShellObserver observer;
- scoped_ptr<aura::Window> window1(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
- scoped_ptr<aura::Window> window2(
- CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 30, 40)));
- wm::WindowState* window_state1 = wm::GetWindowState(window1.get());
- wm::WindowState* window_state2 = wm::GetWindowState(window2.get());
- window_state2->Activate();
-
- window_state2->ToggleFullscreen();
- EXPECT_EQ(1, observer.call_count());
- EXPECT_TRUE(observer.is_fullscreen());
-
- // When window1 moves to the front the fullscreen state should change.
- window_state1->Activate();
- EXPECT_EQ(2, observer.call_count());
- EXPECT_FALSE(observer.is_fullscreen());
-
- // It should change back if window2 becomes active again.
- window_state2->Activate();
- EXPECT_EQ(3, observer.call_count());
- EXPECT_TRUE(observer.is_fullscreen());
-
- window_state2->ToggleFullscreen();
- EXPECT_EQ(4, observer.call_count());
- EXPECT_FALSE(observer.is_fullscreen());
-
- window_state2->ToggleFullscreen();
- EXPECT_EQ(5, observer.call_count());
- EXPECT_TRUE(observer.is_fullscreen());
-
- // Closing the window should change the fullscreen state.
- window2.reset();
- EXPECT_EQ(6, observer.call_count());
- EXPECT_FALSE(observer.is_fullscreen());
-}
-
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_types.h b/chromium/ash/wm/workspace/workspace_types.h
deleted file mode 100644
index 9572a328d8b..00000000000
--- a/chromium/ash/wm/workspace/workspace_types.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_WORKSPACE_TYPES_H_
-#define ASH_WM_WORKSPACE_WORKSPACE_TYPES_H_
-
-namespace ash {
-
-// Enumeration of the possible window states.
-enum WorkspaceWindowState {
- // There's a full screen window.
- WORKSPACE_WINDOW_STATE_FULL_SCREEN,
-
- // There's a maximized window.
- WORKSPACE_WINDOW_STATE_MAXIMIZED,
-
- // At least one window overlaps the shelf.
- WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF,
-
- // None of the windows are fullscreen, maximized or touch the shelf.
- WORKSPACE_WINDOW_STATE_DEFAULT,
-};
-
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_WORKSPACE_TYPES_H_
diff --git a/chromium/ash/wm/workspace/workspace_window_resizer.cc b/chromium/ash/wm/workspace/workspace_window_resizer.cc
deleted file mode 100644
index b8cd5049448..00000000000
--- a/chromium/ash/wm/workspace/workspace_window_resizer.cc
+++ /dev/null
@@ -1,1051 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_window_resizer.h"
-
-#include <algorithm>
-#include <cmath>
-#include <utility>
-#include <vector>
-
-#include "ash/ash_switches.h"
-#include "ash/display/display_controller.h"
-#include "ash/root_window_controller.h"
-#include "ash/screen_ash.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/coordinate_conversion.h"
-#include "ash/wm/default_window_resizer.h"
-#include "ash/wm/dock/docked_window_layout_manager.h"
-#include "ash/wm/dock/docked_window_resizer.h"
-#include "ash/wm/drag_window_resizer.h"
-#include "ash/wm/panels/panel_window_resizer.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace/phantom_window_controller.h"
-#include "ash/wm/workspace/snap_sizer.h"
-#include "base/command_line.h"
-#include "base/memory/weak_ptr.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/client/window_types.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/base/hit_test.h"
-#include "ui/compositor/layer.h"
-#include "ui/gfx/screen.h"
-#include "ui/gfx/transform.h"
-
-namespace ash {
-
-scoped_ptr<WindowResizer> CreateWindowResizer(
- aura::Window* window,
- const gfx::Point& point_in_parent,
- int window_component,
- aura::client::WindowMoveSource source) {
- DCHECK(window);
- wm::WindowState* window_state = wm::GetWindowState(window);
- // No need to return a resizer when the window cannot get resized or when a
- // resizer already exists for this window.
- if ((!window_state->CanResize() && window_component != HTCAPTION) ||
- window_state->window_resizer()) {
- return scoped_ptr<WindowResizer>();
- }
-
- // TODO(varkha): The chaining of window resizers causes some of the logic
- // to be repeated and the logic flow difficult to control. With some windows
- // classes using reparenting during drag operations it becomes challenging to
- // implement proper transition from one resizer to another during or at the
- // end of the drag. This also causes http://crbug.com/247085.
- // It seems the only thing the panel or dock resizer needs to do is notify the
- // layout manager when a docked window is being dragged. We should have a
- // better way of doing this, perhaps by having a way of observing drags or
- // having a generic drag window wrapper which informs a layout manager that a
- // drag has started or stopped.
- // It may be possible to refactor and eliminate chaining.
- WindowResizer* window_resizer = NULL;
- if (window->parent() &&
- (window->parent()->id() == internal::kShellWindowId_DefaultContainer ||
- window->parent()->id() == internal::kShellWindowId_DockedContainer ||
- window->parent()->id() == internal::kShellWindowId_PanelContainer)) {
- // Allow dragging maximized windows if it's not tracked by workspace. This
- // is set by tab dragging code.
- if (!window_state->IsNormalShowState() &&
- (window_component != HTCAPTION ||
- !window_state->is_dragged())) {
- return scoped_ptr<WindowResizer>();
- }
- window_resizer = internal::WorkspaceWindowResizer::Create(
- window,
- point_in_parent,
- window_component,
- source,
- std::vector<aura::Window*>());
- } else if (window_state->IsNormalShowState()) {
- window_resizer = DefaultWindowResizer::Create(
- window, point_in_parent, window_component, source);
- }
- if (window_resizer) {
- window_resizer = internal::DragWindowResizer::Create(
- window_resizer, window, point_in_parent, window_component, source);
- }
- if (window_resizer && window->type() == aura::client::WINDOW_TYPE_PANEL) {
- window_resizer = PanelWindowResizer::Create(
- window_resizer, window, point_in_parent, window_component, source);
- }
- if (switches::UseDockedWindows() &&
- window_resizer && window->parent() &&
- !window->transient_parent() &&
- (window->parent()->id() == internal::kShellWindowId_DefaultContainer ||
- window->parent()->id() == internal::kShellWindowId_DockedContainer ||
- window->parent()->id() == internal::kShellWindowId_PanelContainer)) {
- window_resizer = internal::DockedWindowResizer::Create(
- window_resizer, window, point_in_parent, window_component, source);
- }
- window_state->set_window_resizer_(window_resizer);
- return make_scoped_ptr<WindowResizer>(window_resizer);
-}
-
-namespace internal {
-
-namespace {
-
-// Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset
-// when resizing a window using touchscreen.
-const int kScreenEdgeInsetForTouchResize = 32;
-
-// Returns true if the window should stick to the edge.
-bool ShouldStickToEdge(int distance_from_edge, int sticky_size) {
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshEnableStickyEdges)) {
- // TODO(varkha): Consider keeping snapping behavior for touch drag.
- return distance_from_edge < 0 &&
- distance_from_edge > -sticky_size;
- }
- return distance_from_edge < sticky_size &&
- distance_from_edge > -sticky_size * 2;
-}
-
-// Returns the coordinate along the secondary axis to snap to.
-int CoordinateAlongSecondaryAxis(SecondaryMagnetismEdge edge,
- int leading,
- int trailing,
- int none) {
- switch (edge) {
- case SECONDARY_MAGNETISM_EDGE_LEADING:
- return leading;
- case SECONDARY_MAGNETISM_EDGE_TRAILING:
- return trailing;
- case SECONDARY_MAGNETISM_EDGE_NONE:
- return none;
- }
- NOTREACHED();
- return none;
-}
-
-// Returns the origin for |src| when magnetically attaching to |attach_to| along
-// the edges |edges|. |edges| is a bitmask of the MagnetismEdges.
-gfx::Point OriginForMagneticAttach(const gfx::Rect& src,
- const gfx::Rect& attach_to,
- const MatchedEdge& edge) {
- int x = 0, y = 0;
- switch (edge.primary_edge) {
- case MAGNETISM_EDGE_TOP:
- y = attach_to.bottom();
- break;
- case MAGNETISM_EDGE_LEFT:
- x = attach_to.right();
- break;
- case MAGNETISM_EDGE_BOTTOM:
- y = attach_to.y() - src.height();
- break;
- case MAGNETISM_EDGE_RIGHT:
- x = attach_to.x() - src.width();
- break;
- }
- switch (edge.primary_edge) {
- case MAGNETISM_EDGE_TOP:
- case MAGNETISM_EDGE_BOTTOM:
- x = CoordinateAlongSecondaryAxis(
- edge.secondary_edge, attach_to.x(), attach_to.right() - src.width(),
- src.x());
- break;
- case MAGNETISM_EDGE_LEFT:
- case MAGNETISM_EDGE_RIGHT:
- y = CoordinateAlongSecondaryAxis(
- edge.secondary_edge, attach_to.y(), attach_to.bottom() - src.height(),
- src.y());
- break;
- }
- return gfx::Point(x, y);
-}
-
-// Returns the bounds for a magnetic attach when resizing. |src| is the bounds
-// of window being resized, |attach_to| the bounds of the window to attach to
-// and |edge| identifies the edge to attach to.
-gfx::Rect BoundsForMagneticResizeAttach(const gfx::Rect& src,
- const gfx::Rect& attach_to,
- const MatchedEdge& edge) {
- int x = src.x();
- int y = src.y();
- int w = src.width();
- int h = src.height();
- gfx::Point attach_origin(OriginForMagneticAttach(src, attach_to, edge));
- switch (edge.primary_edge) {
- case MAGNETISM_EDGE_LEFT:
- x = attach_origin.x();
- w = src.right() - x;
- break;
- case MAGNETISM_EDGE_RIGHT:
- w += attach_origin.x() - src.x();
- break;
- case MAGNETISM_EDGE_TOP:
- y = attach_origin.y();
- h = src.bottom() - y;
- break;
- case MAGNETISM_EDGE_BOTTOM:
- h += attach_origin.y() - src.y();
- break;
- }
- switch (edge.primary_edge) {
- case MAGNETISM_EDGE_LEFT:
- case MAGNETISM_EDGE_RIGHT:
- if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_LEADING) {
- y = attach_origin.y();
- h = src.bottom() - y;
- } else if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_TRAILING) {
- h += attach_origin.y() - src.y();
- }
- break;
- case MAGNETISM_EDGE_TOP:
- case MAGNETISM_EDGE_BOTTOM:
- if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_LEADING) {
- x = attach_origin.x();
- w = src.right() - x;
- } else if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_TRAILING) {
- w += attach_origin.x() - src.x();
- }
- break;
- }
- return gfx::Rect(x, y, w, h);
-}
-
-// Converts a window component edge to the magnetic edge to snap to.
-uint32 WindowComponentToMagneticEdge(int window_component) {
- switch (window_component) {
- case HTTOPLEFT:
- return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_TOP;
- case HTTOPRIGHT:
- return MAGNETISM_EDGE_TOP | MAGNETISM_EDGE_RIGHT;
- case HTBOTTOMLEFT:
- return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_BOTTOM;
- case HTBOTTOMRIGHT:
- return MAGNETISM_EDGE_RIGHT | MAGNETISM_EDGE_BOTTOM;
- case HTTOP:
- return MAGNETISM_EDGE_TOP;
- case HTBOTTOM:
- return MAGNETISM_EDGE_BOTTOM;
- case HTRIGHT:
- return MAGNETISM_EDGE_RIGHT;
- case HTLEFT:
- return MAGNETISM_EDGE_LEFT;
- default:
- break;
- }
- return 0;
-}
-
-} // namespace
-
-// static
-const int WorkspaceWindowResizer::kMinOnscreenSize = 20;
-
-// static
-const int WorkspaceWindowResizer::kMinOnscreenHeight = 32;
-
-// static
-const int WorkspaceWindowResizer::kScreenEdgeInset = 8;
-
-// static
-const int WorkspaceWindowResizer::kStickyDistancePixels = 64;
-
-// static
-WorkspaceWindowResizer* WorkspaceWindowResizer::instance_ = NULL;
-
-// Represents the width or height of a window with constraints on its minimum
-// and maximum size. 0 represents a lack of a constraint.
-class WindowSize {
- public:
- WindowSize(int size, int min, int max)
- : size_(size),
- min_(min),
- max_(max) {
- // Grow the min/max bounds to include the starting size.
- if (is_underflowing())
- min_ = size_;
- if (is_overflowing())
- max_ = size_;
- }
-
- bool is_at_capacity(bool shrinking) {
- return size_ == (shrinking ? min_ : max_);
- }
-
- int size() const {
- return size_;
- }
-
- bool has_min() const {
- return min_ != 0;
- }
-
- bool has_max() const {
- return max_ != 0;
- }
-
- bool is_valid() const {
- return !is_overflowing() && !is_underflowing();
- }
-
- bool is_overflowing() const {
- return has_max() && size_ > max_;
- }
-
- bool is_underflowing() const {
- return has_min() && size_ < min_;
- }
-
- // Add |amount| to this WindowSize not exceeding min or max size constraints.
- // Returns by how much |size_| + |amount| exceeds the min/max constraints.
- int Add(int amount) {
- DCHECK(is_valid());
- int new_value = size_ + amount;
-
- if (has_min() && new_value < min_) {
- size_ = min_;
- return new_value - min_;
- }
-
- if (has_max() && new_value > max_) {
- size_ = max_;
- return new_value - max_;
- }
-
- size_ = new_value;
- return 0;
- }
-
- private:
- int size_;
- int min_;
- int max_;
-};
-
-WorkspaceWindowResizer::~WorkspaceWindowResizer() {
- if (did_lock_cursor_) {
- Shell* shell = Shell::GetInstance();
- shell->cursor_manager()->UnlockCursor();
- }
- if (instance_ == this)
- instance_ = NULL;
-}
-
-// static
-WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
- aura::Window* window,
- const gfx::Point& location_in_parent,
- int window_component,
- aura::client::WindowMoveSource source,
- const std::vector<aura::Window*>& attached_windows) {
- Details details(window, location_in_parent, window_component, source);
- return details.is_resizable ?
- new WorkspaceWindowResizer(details, attached_windows) : NULL;
-}
-
-void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent,
- int event_flags) {
- last_mouse_location_ = location_in_parent;
-
- int sticky_size;
- if (event_flags & ui::EF_CONTROL_DOWN) {
- sticky_size = 0;
- } else if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshEnableStickyEdges)) {
- sticky_size = kStickyDistancePixels;
- } else if ((details_.bounds_change & kBoundsChange_Resizes) &&
- details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
- sticky_size = kScreenEdgeInsetForTouchResize;
- } else {
- sticky_size = kScreenEdgeInset;
- }
- // |bounds| is in |window()->parent()|'s coordinates.
- gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent);
- if (window_state()->IsNormalShowState())
- AdjustBoundsForMainWindow(sticky_size, &bounds);
-
- if (bounds != window()->bounds()) {
- if (!did_move_or_resize_) {
- if (!details_.restore_bounds.IsEmpty())
- window_state()->ClearRestoreBounds();
- RestackWindows();
- }
- did_move_or_resize_ = true;
- }
-
- gfx::Point location_in_screen = location_in_parent;
- wm::ConvertPointToScreen(window()->parent(), &location_in_screen);
-
- aura::Window* root = NULL;
- gfx::Display display =
- ScreenAsh::FindDisplayContainingPoint(location_in_screen);
- // Track the last screen that the pointer was on to keep the snap phantom
- // window there.
- if (display.is_valid()) {
- root = Shell::GetInstance()->display_controller()->
- GetRootWindowForDisplayId(display.id());
- }
- if (!attached_windows_.empty())
- LayoutAttachedWindows(&bounds);
- if (bounds != window()->bounds()) {
- // SetBounds needs to be called to update the layout which affects where the
- // phantom window is drawn. Keep track if the window was destroyed during
- // the drag and quit early if so.
- base::WeakPtr<WorkspaceWindowResizer> resizer(
- weak_ptr_factory_.GetWeakPtr());
- window()->SetBounds(bounds);
- if (!resizer)
- return;
- }
- const bool in_original_root = !root || root == window()->GetRootWindow();
- // Hide a phantom window for snapping if the cursor is in another root window.
- if (in_original_root) {
- UpdateSnapPhantomWindow(location_in_parent, bounds);
- } else {
- snap_type_ = SNAP_NONE;
- snap_phantom_window_controller_.reset();
- snap_sizer_.reset();
- SetDraggedWindowDocked(false);
- }
-}
-
-void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
- window_state()->set_bounds_changed_by_user(true);
- snap_phantom_window_controller_.reset();
- if (!did_move_or_resize_ || details_.window_component != HTCAPTION)
- return;
-
- bool snapped = false;
- // When the window is not in the normal show state, we do not snap the window.
- // This happens when the user minimizes or maximizes the window by keyboard
- // shortcut while dragging it. If the window is the result of dragging a tab
- // out of a maximized window, it's already in the normal show state when this
- // is called, so it does not matter.
- if (window_state()->IsNormalShowState() &&
- (window()->type() != aura::client::WINDOW_TYPE_PANEL ||
- !window_state()->panel_attached() ||
- dock_layout_->is_dragged_window_docked()) &&
- (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
- if (!window_state()->HasRestoreBounds()) {
- gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen(
- window()->parent(), details_.initial_bounds_in_parent);
- window_state()->SetRestoreBoundsInScreen(
- details_.restore_bounds.IsEmpty() ?
- initial_bounds :
- details_.restore_bounds);
- }
- DCHECK(snap_sizer_);
- if (window_state()->CanResize() &&
- !dock_layout_->is_dragged_window_docked()) {
- snap_sizer_->SnapWindowToTargetBounds();
- snapped = true;
- }
- }
- if (window_state()->IsSnapped() && !snapped)
- window_state()->Restore();
-}
-
-void WorkspaceWindowResizer::RevertDrag() {
- window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_);
- snap_phantom_window_controller_.reset();
-
- if (!did_move_or_resize_)
- return;
-
- window()->SetBounds(details_.initial_bounds_in_parent);
- if (!details_.restore_bounds.IsEmpty()) {
- window_state()->SetRestoreBoundsInScreen(details_.restore_bounds);
- }
-
- if (details_.window_component == HTRIGHT) {
- int last_x = details_.initial_bounds_in_parent.right();
- for (size_t i = 0; i < attached_windows_.size(); ++i) {
- gfx::Rect bounds(attached_windows_[i]->bounds());
- bounds.set_x(last_x);
- bounds.set_width(initial_size_[i]);
- attached_windows_[i]->SetBounds(bounds);
- last_x = attached_windows_[i]->bounds().right();
- }
- } else {
- int last_y = details_.initial_bounds_in_parent.bottom();
- for (size_t i = 0; i < attached_windows_.size(); ++i) {
- gfx::Rect bounds(attached_windows_[i]->bounds());
- bounds.set_y(last_y);
- bounds.set_height(initial_size_[i]);
- attached_windows_[i]->SetBounds(bounds);
- last_y = attached_windows_[i]->bounds().bottom();
- }
- }
-}
-
-aura::Window* WorkspaceWindowResizer::GetTarget() {
- return details_.window;
-}
-
-const gfx::Point& WorkspaceWindowResizer::GetInitialLocation() const {
- return details_.initial_location_in_parent;
-}
-
-WorkspaceWindowResizer::WorkspaceWindowResizer(
- const Details& details,
- const std::vector<aura::Window*>& attached_windows)
- : details_(details),
- attached_windows_(attached_windows),
- did_lock_cursor_(false),
- did_move_or_resize_(false),
- initial_bounds_changed_by_user_(
- details.window_state->bounds_changed_by_user()),
- total_min_(0),
- total_initial_size_(0),
- snap_type_(SNAP_NONE),
- num_mouse_moves_since_bounds_change_(0),
- magnetism_window_(NULL),
- weak_ptr_factory_(this) {
- DCHECK(details_.is_resizable);
-
- // A mousemove should still show the cursor even if the window is
- // being moved or resized with touch, so do not lock the cursor.
- if (details.source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
- Shell* shell = Shell::GetInstance();
- shell->cursor_manager()->LockCursor();
- did_lock_cursor_ = true;
- }
-
- aura::Window* dock_container = Shell::GetContainer(
- window()->GetRootWindow(), kShellWindowId_DockedContainer);
- dock_layout_ = static_cast<DockedWindowLayoutManager*>(
- dock_container->layout_manager());
-
- // Only support attaching to the right/bottom.
- DCHECK(attached_windows_.empty() ||
- (details.window_component == HTRIGHT ||
- details.window_component == HTBOTTOM));
-
- // TODO: figure out how to deal with window going off the edge.
-
- // Calculate sizes so that we can maintain the ratios if we need to resize.
- int total_available = 0;
- for (size_t i = 0; i < attached_windows_.size(); ++i) {
- gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize());
- int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size());
- initial_size_.push_back(initial_size);
- // If current size is smaller than the min, use the current size as the min.
- // This way we don't snap on resize.
- int min_size = std::min(initial_size,
- std::max(PrimaryAxisSize(min), kMinOnscreenSize));
- total_min_ += min_size;
- total_initial_size_ += initial_size;
- total_available += std::max(min_size, initial_size) - min_size;
- }
- instance_ = this;
-}
-
-gfx::Rect WorkspaceWindowResizer::GetFinalBounds(
- const gfx::Rect& bounds) const {
- if (snap_phantom_window_controller_.get() &&
- snap_phantom_window_controller_->IsShowing()) {
- return snap_phantom_window_controller_->bounds_in_screen();
- }
- return bounds;
-}
-
-void WorkspaceWindowResizer::LayoutAttachedWindows(
- gfx::Rect* bounds) {
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window()));
- int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size());
- int current_size = PrimaryAxisSize(bounds->size());
- int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom());
- int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom());
-
- int delta = current_size - initial_size;
- int available_size = end - start;
- std::vector<int> sizes;
- int leftovers = CalculateAttachedSizes(delta, available_size, &sizes);
-
- // leftovers > 0 means that the attached windows can't grow to compensate for
- // the shrinkage of the main window. This line causes the attached windows to
- // be moved so they are still flush against the main window, rather than the
- // main window being prevented from shrinking.
- leftovers = std::min(0, leftovers);
- // Reallocate any leftover pixels back into the main window. This is
- // necessary when, for example, the main window shrinks, but none of the
- // attached windows can grow without exceeding their max size constraints.
- // Adding the pixels back to the main window effectively prevents the main
- // window from resizing too far.
- if (details_.window_component == HTRIGHT)
- bounds->set_width(bounds->width() + leftovers);
- else
- bounds->set_height(bounds->height() + leftovers);
-
- DCHECK_EQ(attached_windows_.size(), sizes.size());
- int last = PrimaryAxisCoordinate(bounds->right(), bounds->bottom());
- for (size_t i = 0; i < attached_windows_.size(); ++i) {
- gfx::Rect attached_bounds(attached_windows_[i]->bounds());
- if (details_.window_component == HTRIGHT) {
- attached_bounds.set_x(last);
- attached_bounds.set_width(sizes[i]);
- } else {
- attached_bounds.set_y(last);
- attached_bounds.set_height(sizes[i]);
- }
- attached_windows_[i]->SetBounds(attached_bounds);
- last += sizes[i];
- }
-}
-
-int WorkspaceWindowResizer::CalculateAttachedSizes(
- int delta,
- int available_size,
- std::vector<int>* sizes) const {
- std::vector<WindowSize> window_sizes;
- CreateBucketsForAttached(&window_sizes);
-
- // How much we need to grow the attached by (collectively).
- int grow_attached_by = 0;
- if (delta > 0) {
- // If the attached windows don't fit when at their initial size, we will
- // have to shrink them by how much they overflow.
- if (total_initial_size_ >= available_size)
- grow_attached_by = available_size - total_initial_size_;
- } else {
- // If we're shrinking, we grow the attached so the total size remains
- // constant.
- grow_attached_by = -delta;
- }
-
- int leftover_pixels = 0;
- while (grow_attached_by != 0) {
- int leftovers = GrowFairly(grow_attached_by, window_sizes);
- if (leftovers == grow_attached_by) {
- leftover_pixels = leftovers;
- break;
- }
- grow_attached_by = leftovers;
- }
-
- for (size_t i = 0; i < window_sizes.size(); ++i)
- sizes->push_back(window_sizes[i].size());
-
- return leftover_pixels;
-}
-
-int WorkspaceWindowResizer::GrowFairly(
- int pixels,
- std::vector<WindowSize>& sizes) const {
- bool shrinking = pixels < 0;
- std::vector<WindowSize*> nonfull_windows;
- for (size_t i = 0; i < sizes.size(); ++i) {
- if (!sizes[i].is_at_capacity(shrinking))
- nonfull_windows.push_back(&sizes[i]);
- }
- std::vector<float> ratios;
- CalculateGrowthRatios(nonfull_windows, &ratios);
-
- int remaining_pixels = pixels;
- bool add_leftover_pixels_to_last = true;
- for (size_t i = 0; i < nonfull_windows.size(); ++i) {
- int grow_by = pixels * ratios[i];
- // Put any leftover pixels into the last window.
- if (i == nonfull_windows.size() - 1 && add_leftover_pixels_to_last)
- grow_by = remaining_pixels;
- int remainder = nonfull_windows[i]->Add(grow_by);
- int consumed = grow_by - remainder;
- remaining_pixels -= consumed;
- if (nonfull_windows[i]->is_at_capacity(shrinking) && remainder > 0) {
- // Because this window overflowed, some of the pixels in
- // |remaining_pixels| aren't there due to rounding errors. Rather than
- // unfairly giving all those pixels to the last window, we refrain from
- // allocating them so that this function can be called again to distribute
- // the pixels fairly.
- add_leftover_pixels_to_last = false;
- }
- }
- return remaining_pixels;
-}
-
-void WorkspaceWindowResizer::CalculateGrowthRatios(
- const std::vector<WindowSize*>& sizes,
- std::vector<float>* out_ratios) const {
- DCHECK(out_ratios->empty());
- int total_value = 0;
- for (size_t i = 0; i < sizes.size(); ++i)
- total_value += sizes[i]->size();
-
- for (size_t i = 0; i < sizes.size(); ++i)
- out_ratios->push_back(
- (static_cast<float>(sizes[i]->size())) / total_value);
-}
-
-void WorkspaceWindowResizer::CreateBucketsForAttached(
- std::vector<WindowSize>* sizes) const {
- for (size_t i = 0; i < attached_windows_.size(); i++) {
- int initial_size = initial_size_[i];
- aura::WindowDelegate* delegate = attached_windows_[i]->delegate();
- int min = PrimaryAxisSize(delegate->GetMinimumSize());
- int max = PrimaryAxisSize(delegate->GetMaximumSize());
-
- sizes->push_back(WindowSize(initial_size, min, max));
- }
-}
-
-void WorkspaceWindowResizer::MagneticallySnapToOtherWindows(gfx::Rect* bounds) {
- if (UpdateMagnetismWindow(*bounds, kAllMagnetismEdges)) {
- gfx::Point point = OriginForMagneticAttach(
- ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds),
- magnetism_window_->GetBoundsInScreen(),
- magnetism_edge_);
- aura::client::GetScreenPositionClient(window()->GetRootWindow())->
- ConvertPointFromScreen(window()->parent(), &point);
- bounds->set_origin(point);
- }
-}
-
-void WorkspaceWindowResizer::MagneticallySnapResizeToOtherWindows(
- gfx::Rect* bounds) {
- const uint32 edges = WindowComponentToMagneticEdge(details_.window_component);
- if (UpdateMagnetismWindow(*bounds, edges)) {
- *bounds = ScreenAsh::ConvertRectFromScreen(
- window()->parent(),
- BoundsForMagneticResizeAttach(
- ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds),
- magnetism_window_->GetBoundsInScreen(),
- magnetism_edge_));
- }
-}
-
-bool WorkspaceWindowResizer::UpdateMagnetismWindow(const gfx::Rect& bounds,
- uint32 edges) {
- // |bounds| are in coordinates of original window's parent.
- gfx::Rect bounds_in_screen =
- ScreenAsh::ConvertRectToScreen(window()->parent(), bounds);
- MagnetismMatcher matcher(bounds_in_screen, edges);
-
- // If we snapped to a window then check it first. That way we don't bounce
- // around when close to multiple edges.
- if (magnetism_window_) {
- if (window_tracker_.Contains(magnetism_window_) &&
- matcher.ShouldAttach(magnetism_window_->GetBoundsInScreen(),
- &magnetism_edge_)) {
- return true;
- }
- window_tracker_.Remove(magnetism_window_);
- magnetism_window_ = NULL;
- }
-
- // Avoid magnetically snapping windows that are not resizable.
- // TODO(oshima): change this to window.type() == TYPE_NORMAL.
- if (!window_state()->CanResize())
- return false;
-
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- for (aura::Window::Windows::iterator iter = root_windows.begin();
- iter != root_windows.end(); ++iter) {
- const aura::Window* root_window = *iter;
- // Test all children from the desktop in each root window.
- const aura::Window::Windows& children = Shell::GetContainer(
- root_window, kShellWindowId_DefaultContainer)->children();
- for (aura::Window::Windows::const_reverse_iterator i = children.rbegin();
- i != children.rend() && !matcher.AreEdgesObscured(); ++i) {
- wm::WindowState* other_state = wm::GetWindowState(*i);
- if (other_state->window() == window() ||
- !other_state->window()->IsVisible() ||
- !other_state->IsNormalShowState() ||
- !other_state->CanResize()) {
- continue;
- }
- if (matcher.ShouldAttach(
- other_state->window()->GetBoundsInScreen(), &magnetism_edge_)) {
- magnetism_window_ = other_state->window();
- window_tracker_.Add(magnetism_window_);
- return true;
- }
- }
- }
- return false;
-}
-
-void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
- int sticky_size,
- gfx::Rect* bounds) {
- gfx::Point last_mouse_location_in_screen = last_mouse_location_;
- wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen);
- gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(
- last_mouse_location_in_screen);
- gfx::Rect work_area =
- ScreenAsh::ConvertRectFromScreen(window()->parent(), display.work_area());
- if (details_.window_component == HTCAPTION) {
- // Adjust the bounds to the work area where the mouse cursor is located.
- // Always keep kMinOnscreenHeight or the window height (whichever is less)
- // on the bottom.
- int max_y = work_area.bottom() - std::min(kMinOnscreenHeight,
- bounds->height());
- if (bounds->y() > max_y) {
- bounds->set_y(max_y);
- } else if (bounds->y() <= work_area.y()) {
- // Don't allow dragging above the top of the display until the mouse
- // cursor reaches the work area above if any.
- bounds->set_y(work_area.y());
- }
-
- if (sticky_size > 0) {
- // Possibly stick to edge except when a mouse pointer is outside the
- // work area.
- if (!(display.work_area().Contains(last_mouse_location_in_screen) &&
- StickToWorkAreaOnMove(work_area, sticky_size, bounds))) {
- MagneticallySnapToOtherWindows(bounds);
- }
- }
- } else if (sticky_size > 0) {
- MagneticallySnapResizeToOtherWindows(bounds);
- if (!magnetism_window_ && sticky_size > 0)
- StickToWorkAreaOnResize(work_area, sticky_size, bounds);
- }
-
- if (attached_windows_.empty())
- return;
-
- if (details_.window_component == HTRIGHT) {
- bounds->set_width(std::min(bounds->width(),
- work_area.right() - total_min_ - bounds->x()));
- } else {
- DCHECK_EQ(HTBOTTOM, details_.window_component);
- bounds->set_height(std::min(bounds->height(),
- work_area.bottom() - total_min_ - bounds->y()));
- }
-}
-
-bool WorkspaceWindowResizer::StickToWorkAreaOnMove(
- const gfx::Rect& work_area,
- int sticky_size,
- gfx::Rect* bounds) const {
- const int left_edge = work_area.x();
- const int right_edge = work_area.right();
- const int top_edge = work_area.y();
- const int bottom_edge = work_area.bottom();
- bool updated = false;
- if (ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) {
- bounds->set_x(left_edge);
- updated = true;
- } else if (ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) {
- bounds->set_x(right_edge - bounds->width());
- updated = true;
- }
- if (ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) {
- bounds->set_y(top_edge);
- updated = true;
- } else if (ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size) &&
- bounds->height() < (bottom_edge - top_edge)) {
- // Only snap to the bottom if the window is smaller than the work area.
- // Doing otherwise can lead to window snapping in weird ways as it bounces
- // between snapping to top then bottom.
- bounds->set_y(bottom_edge - bounds->height());
- updated = true;
- }
- return updated;
-}
-
-void WorkspaceWindowResizer::StickToWorkAreaOnResize(
- const gfx::Rect& work_area,
- int sticky_size,
- gfx::Rect* bounds) const {
- const uint32 edges = WindowComponentToMagneticEdge(details_.window_component);
- const int left_edge = work_area.x();
- const int right_edge = work_area.right();
- const int top_edge = work_area.y();
- const int bottom_edge = work_area.bottom();
- if (edges & MAGNETISM_EDGE_TOP &&
- ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) {
- bounds->set_height(bounds->bottom() - top_edge);
- bounds->set_y(top_edge);
- }
- if (edges & MAGNETISM_EDGE_LEFT &&
- ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) {
- bounds->set_width(bounds->right() - left_edge);
- bounds->set_x(left_edge);
- }
- if (edges & MAGNETISM_EDGE_BOTTOM &&
- ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) {
- bounds->set_height(bottom_edge - bounds->y());
- }
- if (edges & MAGNETISM_EDGE_RIGHT &&
- ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) {
- bounds->set_width(right_edge - bounds->x());
- }
-}
-
-int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const {
- return PrimaryAxisCoordinate(size.width(), size.height());
-}
-
-int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const {
- switch (details_.window_component) {
- case HTRIGHT:
- return x;
- case HTBOTTOM:
- return y;
- default:
- NOTREACHED();
- }
- return 0;
-}
-
-void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location,
- const gfx::Rect& bounds) {
- if (!did_move_or_resize_ || details_.window_component != HTCAPTION)
- return;
-
- SnapType last_type = snap_type_;
- snap_type_ = GetSnapType(location);
- if (snap_type_ == SNAP_NONE || snap_type_ != last_type) {
- snap_phantom_window_controller_.reset();
- snap_sizer_.reset();
- if (snap_type_ == SNAP_NONE) {
- SetDraggedWindowDocked(false);
- return;
- }
- }
- const bool can_dock = dock_layout_->CanDockWindow(window(), snap_type_);
- const bool can_snap = window_state()->CanSnap();
- if (!can_snap && !can_dock) {
- snap_type_ = SNAP_NONE;
- snap_phantom_window_controller_.reset();
- snap_sizer_.reset();
- SetDraggedWindowDocked(false);
- return;
- }
- SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT) ?
- SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE;
- if (!snap_sizer_) {
- snap_sizer_.reset(new SnapSizer(window_state(),
- location,
- edge,
- internal::SnapSizer::OTHER_INPUT));
- } else {
- snap_sizer_->Update(location);
- }
-
- // Update phantom window with snapped or docked guide bounds.
- // Windows that cannot be snapped or are less wide than kMaxDockWidth can get
- // docked without going through a snapping sequence.
- gfx::Rect phantom_bounds;
- if (can_snap &&
- (!can_dock ||
- window()->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth))
- phantom_bounds = snap_sizer_->target_bounds();
- const bool should_dock = can_dock &&
- (phantom_bounds.IsEmpty() ||
- snap_sizer_->end_of_sequence() ||
- dock_layout_->is_dragged_window_docked());
- SetDraggedWindowDocked(should_dock);
- snap_type_ = GetSnapType(location);
- if (dock_layout_->is_dragged_window_docked()) {
- phantom_bounds = ScreenAsh::ConvertRectFromScreen(
- window()->parent(), dock_layout_->dragged_bounds());
- }
-
- if (phantom_bounds.IsEmpty()) {
- snap_phantom_window_controller_.reset();
- return;
- }
-
- if (!snap_phantom_window_controller_) {
- snap_phantom_window_controller_.reset(
- new PhantomWindowController(window()));
- }
- snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen(
- window()->parent(), phantom_bounds));
-}
-
-void WorkspaceWindowResizer::RestackWindows() {
- if (attached_windows_.empty())
- return;
- // Build a map from index in children to window, returning if there is a
- // window with a different parent.
- typedef std::map<size_t, aura::Window*> IndexToWindowMap;
- IndexToWindowMap map;
- aura::Window* parent = window()->parent();
- const aura::Window::Windows& windows(parent->children());
- map[std::find(windows.begin(), windows.end(), window()) -
- windows.begin()] = window();
- for (std::vector<aura::Window*>::const_iterator i =
- attached_windows_.begin(); i != attached_windows_.end(); ++i) {
- if ((*i)->parent() != parent)
- return;
- size_t index =
- std::find(windows.begin(), windows.end(), *i) - windows.begin();
- map[index] = *i;
- }
-
- // Reorder the windows starting at the topmost.
- parent->StackChildAtTop(map.rbegin()->second);
- for (IndexToWindowMap::const_reverse_iterator i = map.rbegin();
- i != map.rend(); ) {
- aura::Window* window = i->second;
- ++i;
- if (i != map.rend())
- parent->StackChildBelow(i->second, window);
- }
-}
-
-SnapType WorkspaceWindowResizer::GetSnapType(
- const gfx::Point& location) const {
- // TODO: this likely only wants total display area, not the area of a single
- // display.
- gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window()));
- if (details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
- // Increase tolerance for touch-snapping near the screen edges. This is only
- // necessary when the work area left or right edge is same as screen edge.
- gfx::Rect display_bounds(ScreenAsh::GetDisplayBoundsInParent(window()));
- int inset_left = 0;
- if (area.x() == display_bounds.x())
- inset_left = kScreenEdgeInsetForTouchResize;
- int inset_right = 0;
- if (area.right() == display_bounds.right())
- inset_right = kScreenEdgeInsetForTouchResize;
- area.Inset(inset_left, 0, inset_right, 0);
- }
- if (location.x() <= area.x())
- return SNAP_LEFT;
- if (location.x() >= area.right() - 1)
- return SNAP_RIGHT;
- return SNAP_NONE;
-}
-
-void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) {
- if (should_dock &&
- dock_layout_->GetAlignmentOfWindow(window()) != DOCKED_ALIGNMENT_NONE) {
- if (!dock_layout_->is_dragged_window_docked()) {
- window_state()->set_bounds_changed_by_user(false);
- dock_layout_->DockDraggedWindow(window());
- }
- } else {
- if (dock_layout_->is_dragged_window_docked()) {
- dock_layout_->UndockDraggedWindow();
- window_state()->set_bounds_changed_by_user(true);
- }
- }
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/chromium/ash/wm/workspace/workspace_window_resizer.h b/chromium/ash/wm/workspace/workspace_window_resizer.h
deleted file mode 100644
index 015e96ddb36..00000000000
--- a/chromium/ash/wm/workspace/workspace_window_resizer.h
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_WINDOW_RESIZER_H_
-#define ASH_WM_WORKSPACE_WINDOW_RESIZER_H_
-
-#include <vector>
-
-#include "ash/wm/window_resizer.h"
-#include "ash/wm/workspace/magnetism_matcher.h"
-#include "ash/wm/workspace/snap_types.h"
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "ui/aura/window_tracker.h"
-
-namespace ash {
-namespace wm {
-class WindowState;
-}
-
-namespace internal {
-
-class DockedWindowLayoutManager;
-class PhantomWindowController;
-class SnapSizer;
-class WindowSize;
-
-// WindowResizer implementation for workspaces. This enforces that windows are
-// not allowed to vertically move or resize outside of the work area. As windows
-// are moved outside the work area they are shrunk. We remember the height of
-// the window before it was moved so that if the window is again moved up we
-// attempt to restore the old height.
-class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
- public:
- // When dragging an attached window this is the min size we'll make sure is
- // visible. In the vertical direction we take the max of this and that from
- // the delegate.
- static const int kMinOnscreenSize;
-
- // Min height we'll force on screen when dragging the caption.
- // TODO: this should come from a property on the window.
- static const int kMinOnscreenHeight;
-
- // Snap region when dragging close to the edges. That is, as the window gets
- // this close to an edge of the screen it snaps to the edge.
- static const int kScreenEdgeInset;
-
- // Distance in pixels that the cursor must move past an edge for a window
- // to move or resize beyond that edge.
- static const int kStickyDistancePixels;
-
- virtual ~WorkspaceWindowResizer();
-
- static WorkspaceWindowResizer* Create(
- aura::Window* window,
- const gfx::Point& location_in_parent,
- int window_component,
- aura::client::WindowMoveSource source,
- const std::vector<aura::Window*>& attached_windows);
-
- // WindowResizer:
- virtual void Drag(const gfx::Point& location_in_parent,
- int event_flags) OVERRIDE;
- virtual void CompleteDrag(int event_flags) OVERRIDE;
- virtual void RevertDrag() OVERRIDE;
- virtual aura::Window* GetTarget() OVERRIDE;
- virtual const gfx::Point& GetInitialLocation() const OVERRIDE;
-
- private:
- WorkspaceWindowResizer(const Details& details,
- const std::vector<aura::Window*>& attached_windows);
-
- private:
- friend class WorkspaceWindowResizerTest;
-
- // Returns the final bounds to place the window at. This differs from
- // the current when snapping.
- gfx::Rect GetFinalBounds(const gfx::Rect& bounds) const;
-
- // Lays out the attached windows. |bounds| is the bounds of the main window.
- void LayoutAttachedWindows(gfx::Rect* bounds);
-
- // Calculates the new sizes of the attached windows, given that the main
- // window has been resized (along the primary axis) by |delta|.
- // |available_size| is the maximum length of the space that the attached
- // windows are allowed to occupy (ie: the distance between the right/bottom
- // edge of the primary window and the right/bottom of the desktop area).
- // Populates |sizes| with the desired sizes of the attached windows, and
- // returns the number of pixels that couldn't be allocated to the attached
- // windows (due to min/max size constraints).
- // Note the return value can be positive or negative, a negative value
- // indicating that that many pixels couldn't be removed from the attached
- // windows.
- int CalculateAttachedSizes(
- int delta,
- int available_size,
- std::vector<int>* sizes) const;
-
- // Divides |amount| evenly between |sizes|. If |amount| is negative it
- // indicates how many pixels |sizes| should be shrunk by.
- // Returns how many pixels failed to be allocated/removed from |sizes|.
- int GrowFairly(int amount, std::vector<WindowSize>& sizes) const;
-
- // Calculate the ratio of pixels that each WindowSize in |sizes| should
- // receive when growing or shrinking.
- void CalculateGrowthRatios(const std::vector<WindowSize*>& sizes,
- std::vector<float>* out_ratios) const;
-
- // Adds a WindowSize to |sizes| for each attached window.
- void CreateBucketsForAttached(std::vector<WindowSize>* sizes) const;
-
- // If possible snaps the window to a neary window. Updates |bounds| if there
- // was a close enough window.
- void MagneticallySnapToOtherWindows(gfx::Rect* bounds);
-
- // If possible snaps the resize to a neary window. Updates |bounds| if there
- // was a close enough window.
- void MagneticallySnapResizeToOtherWindows(gfx::Rect* bounds);
-
- // Finds the neareset window to magentically snap to. Updates
- // |magnetism_window_| and |magnetism_edge_| appropriately. |edges| is a
- // bitmask of the MagnetismEdges to match again. Returns true if a match is
- // found.
- bool UpdateMagnetismWindow(const gfx::Rect& bounds, uint32 edges);
-
- // Adjusts the bounds of the window: magnetically snapping, ensuring the
- // window has enough on screen... |snap_size| is the distance from an edge of
- // the work area before the window is snapped. A value of 0 results in no
- // snapping.
- void AdjustBoundsForMainWindow(int snap_size, gfx::Rect* bounds);
-
- // Stick the window bounds to the work area during a move.
- bool StickToWorkAreaOnMove(const gfx::Rect& work_area,
- int sticky_size,
- gfx::Rect* bounds) const;
-
- // Stick the window bounds to the work area during a resize.
- void StickToWorkAreaOnResize(const gfx::Rect& work_area,
- int sticky_size,
- gfx::Rect* bounds) const;
-
- // Returns a coordinate along the primary axis. Used to share code for
- // left/right multi window resize and top/bottom resize.
- int PrimaryAxisSize(const gfx::Size& size) const;
- int PrimaryAxisCoordinate(int x, int y) const;
-
- // Updates the bounds of the phantom window for window snapping.
- void UpdateSnapPhantomWindow(const gfx::Point& location,
- const gfx::Rect& bounds);
-
- // Restacks the windows z-order position so that one of the windows is at the
- // top of the z-order, and the rest directly underneath it.
- void RestackWindows();
-
- // Returns the SnapType for the specified point. SNAP_NONE is used if no
- // snapping should be used.
- SnapType GetSnapType(const gfx::Point& location) const;
-
- // Docks the dragged window if |should_dock| and the window can be docked.
- // Undocks the window if |should_dock| is false.
- void SetDraggedWindowDocked(bool should_dock);
-
- aura::Window* window() const { return details_.window; }
-
- wm::WindowState* window_state() { return details_.window_state; }
-
- const Details details_;
-
- const std::vector<aura::Window*> attached_windows_;
-
- bool did_lock_cursor_;
-
- // Set to true once Drag() is invoked and the bounds of the window change.
- bool did_move_or_resize_;
-
- // True if the window initially had |bounds_changed_by_user_| set in state.
- bool initial_bounds_changed_by_user_;
-
- // The initial size of each of the windows in |attached_windows_| along the
- // primary axis.
- std::vector<int> initial_size_;
-
- // Sum of the minimum sizes of the attached windows.
- int total_min_;
-
- // Sum of the sizes in |initial_size_|.
- int total_initial_size_;
-
- // Gives a previews of where the the window will end up. Only used if there
- // is a grid and the caption is being dragged.
- scoped_ptr<PhantomWindowController> snap_phantom_window_controller_;
-
- // Used to determine the target position of a snap.
- scoped_ptr<SnapSizer> snap_sizer_;
-
- // Last SnapType.
- SnapType snap_type_;
-
- // Number of mouse moves since the last bounds change. Only used for phantom
- // placement to track when the mouse is moved while pushed against the edge of
- // the screen.
- int num_mouse_moves_since_bounds_change_;
-
- // The mouse location passed to Drag().
- gfx::Point last_mouse_location_;
-
- // Window the drag has magnetically attached to.
- aura::Window* magnetism_window_;
-
- // Used to verify |magnetism_window_| is still valid.
- aura::WindowTracker window_tracker_;
-
- // If |magnetism_window_| is non-NULL this indicates how the two windows
- // should attach.
- MatchedEdge magnetism_edge_;
-
- // Dock container window layout manager.
- DockedWindowLayoutManager* dock_layout_;
-
- // Used to determine if this has been deleted during a drag such as when a tab
- // gets dragged into another browser window.
- base::WeakPtrFactory<WorkspaceWindowResizer> weak_ptr_factory_;
-
- // Current instance for use by the WorkspaceWindowResizerTest.
- static WorkspaceWindowResizer* instance_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizer);
-};
-
-} // namespace internal
-} // namespace ash
-
-#endif // ASH_WM_WORKSPACE_WINDOW_RESIZER_H_
diff --git a/chromium/ash/wm/workspace/workspace_window_resizer_unittest.cc b/chromium/ash/wm/workspace/workspace_window_resizer_unittest.cc
deleted file mode 100644
index 599c4ea98e8..00000000000
--- a/chromium/ash/wm/workspace/workspace_window_resizer_unittest.cc
+++ /dev/null
@@ -1,2027 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/workspace_window_resizer.h"
-
-#include "ash/ash_constants.h"
-#include "ash/ash_switches.h"
-#include "ash/display/display_manager.h"
-#include "ash/root_window_controller.h"
-#include "ash/screen_ash.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace/phantom_window_controller.h"
-#include "ash/wm/workspace/snap_sizer.h"
-#include "ash/wm/workspace_controller.h"
-#include "base/command_line.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/test/event_generator.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/base/hit_test.h"
-#include "ui/gfx/insets.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
-
-namespace gfx {
-
-// Class to provide access to SlideAnimation internals for testing.
-// TODO: this should be next to SlideAnimation, not here.
-class SlideAnimation::TestApi {
- public:
- explicit TestApi(SlideAnimation* animation) : animation_(animation) {}
-
- void SetStartTime(base::TimeTicks ticks) {
- animation_->SetStartTime(ticks);
- }
-
- void Step(base::TimeTicks ticks) {
- animation_->Step(ticks);
- }
-
- void RunTillComplete() {
- SetStartTime(base::TimeTicks());
- Step(base::TimeTicks() +
- base::TimeDelta::FromMilliseconds(animation_->GetSlideDuration()));
- EXPECT_EQ(1.0, animation_->GetCurrentValue());
- }
-
- private:
- SlideAnimation* animation_;
-
- DISALLOW_COPY_AND_ASSIGN(TestApi);
-};
-
-}
-
-namespace ash {
-namespace internal {
-namespace {
-
-const int kRootHeight = 600;
-
-// A simple window delegate that returns the specified min size.
-class TestWindowDelegate : public aura::test::TestWindowDelegate {
- public:
- TestWindowDelegate() {
- }
- virtual ~TestWindowDelegate() {}
-
- void set_min_size(const gfx::Size& size) {
- min_size_ = size;
- }
-
- void set_max_size(const gfx::Size& size) {
- max_size_ = size;
- }
-
- private:
- // Overridden from aura::Test::TestWindowDelegate:
- virtual gfx::Size GetMinimumSize() const OVERRIDE {
- return min_size_;
- }
-
- virtual gfx::Size GetMaximumSize() const OVERRIDE {
- return max_size_;
- }
-
- gfx::Size min_size_;
- gfx::Size max_size_;
-
- DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
-};
-
-} // namespace
-
-class WorkspaceWindowResizerTest : public test::AshTestBase {
- public:
- WorkspaceWindowResizerTest() : workspace_resizer_(NULL) {}
- virtual ~WorkspaceWindowResizerTest() {}
-
- virtual void SetUp() OVERRIDE {
- AshTestBase::SetUp();
- UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));
-
- aura::Window* root = Shell::GetPrimaryRootWindow();
- gfx::Rect root_bounds(root->bounds());
-#if defined(OS_WIN)
- // RootWindow and Display can't resize on Windows Ash.
- // http://crbug.com/165962
- EXPECT_EQ(kRootHeight, root_bounds.height());
-#endif
- EXPECT_EQ(800, root_bounds.width());
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
- window_.reset(new aura::Window(&delegate_));
- window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window_->Init(ui::LAYER_NOT_DRAWN);
- ParentWindowInPrimaryRootWindow(window_.get());
- window_->set_id(1);
-
- window2_.reset(new aura::Window(&delegate2_));
- window2_->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window2_->Init(ui::LAYER_NOT_DRAWN);
- ParentWindowInPrimaryRootWindow(window2_.get());
- window2_->set_id(2);
-
- window3_.reset(new aura::Window(&delegate3_));
- window3_->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window3_->Init(ui::LAYER_NOT_DRAWN);
- ParentWindowInPrimaryRootWindow(window3_.get());
- window3_->set_id(3);
-
- window4_.reset(new aura::Window(&delegate4_));
- window4_->SetType(aura::client::WINDOW_TYPE_NORMAL);
- window4_->Init(ui::LAYER_NOT_DRAWN);
- ParentWindowInPrimaryRootWindow(window4_.get());
- window4_->set_id(4);
- }
-
- virtual void TearDown() OVERRIDE {
- window_.reset();
- window2_.reset();
- window3_.reset();
- window4_.reset();
- touch_resize_window_.reset();
- AshTestBase::TearDown();
- }
-
- // Returns a string identifying the z-order of each of the known child windows
- // of |parent|. The returned string constains the id of the known windows and
- // is ordered from topmost to bottomost windows.
- std::string WindowOrderAsString(aura::Window* parent) const {
- std::string result;
- const aura::Window::Windows& windows = parent->children();
- for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
- i != windows.rend(); ++i) {
- if (*i == window_ || *i == window2_ || *i == window3_) {
- if (!result.empty())
- result += " ";
- result += base::IntToString((*i)->id());
- }
- }
- return result;
- }
-
- protected:
- WindowResizer* CreateResizerForTest(
- aura::Window* window,
- const gfx::Point& point_in_parent,
- int window_component) {
- WindowResizer* resizer = CreateWindowResizer(
- window,
- point_in_parent,
- window_component,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE).release();
- workspace_resizer_ = WorkspaceWindowResizer::instance_;
- return resizer;
- }
-
- PhantomWindowController* snap_phantom_window_controller() const {
- return workspace_resizer_->snap_phantom_window_controller_.get();
- }
-
- gfx::Point CalculateDragPoint(const WindowResizer& resizer,
- int delta_x,
- int delta_y) const {
- gfx::Point location = resizer.GetInitialLocation();
- location.set_x(location.x() + delta_x);
- location.set_y(location.y() + delta_y);
- return location;
- }
-
- std::vector<aura::Window*> empty_windows() const {
- return std::vector<aura::Window*>();
- }
-
- internal::ShelfLayoutManager* shelf_layout_manager() {
- return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
- }
-
- void InitTouchResizeWindow(const gfx::Rect& bounds, int window_component) {
- touch_resize_delegate_.set_window_component(window_component);
- touch_resize_window_.reset(
- CreateTestWindowInShellWithDelegate(&touch_resize_delegate_, 0,
- bounds));
- gfx::Insets mouse_outer_insets(-ash::kResizeOutsideBoundsSize,
- -ash::kResizeOutsideBoundsSize,
- -ash::kResizeOutsideBoundsSize,
- -ash::kResizeOutsideBoundsSize);
- gfx::Insets touch_outer_insets = mouse_outer_insets.Scale(
- ash::kResizeOutsideBoundsScaleForTouch);
- touch_resize_window_->SetHitTestBoundsOverrideOuter(mouse_outer_insets,
- touch_outer_insets);
- }
-
- // Simulate running the animation.
- void RunAnimationTillComplete(gfx::SlideAnimation* animation) {
- gfx::SlideAnimation::TestApi test_api(animation);
- test_api.RunTillComplete();
- }
-
- TestWindowDelegate delegate_;
- TestWindowDelegate delegate2_;
- TestWindowDelegate delegate3_;
- TestWindowDelegate delegate4_;
- scoped_ptr<aura::Window> window_;
- scoped_ptr<aura::Window> window2_;
- scoped_ptr<aura::Window> window3_;
- scoped_ptr<aura::Window> window4_;
-
- TestWindowDelegate touch_resize_delegate_;
- scoped_ptr<aura::Window> touch_resize_window_;
- WorkspaceWindowResizer* workspace_resizer_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
-};
-
-class WorkspaceWindowResizerTestSticky : public WorkspaceWindowResizerTest {
- public:
- WorkspaceWindowResizerTestSticky() {}
- virtual ~WorkspaceWindowResizerTestSticky() {}
-
- virtual void SetUp() OVERRIDE {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- ash::switches::kAshEnableStickyEdges);
- WorkspaceWindowResizerTest::SetUp();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTestSticky);
-};
-
-// Assertions around attached window resize dragging from the right with 2
-// windows.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_2) {
- window_->SetBounds(gfx::Rect(0, 300, 400, 300));
- window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the right, which should expand w1 and push w2.
- resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
- EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
- EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
-
- // Push off the screen, w2 should be resized to its min.
- delegate2_.set_min_size(gfx::Size(20, 20));
- resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
- EXPECT_EQ("0,300 780x300", window_->bounds().ToString());
- EXPECT_EQ("780,200 20x200", window2_->bounds().ToString());
-
- // Move back to 100 and verify w2 gets its original size.
- resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
- EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
- EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
-
- // Revert and make sure everything moves back.
- resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
- resizer->RevertDrag();
- EXPECT_EQ("0,300 400x300", window_->bounds().ToString());
- EXPECT_EQ("400,200 100x200", window2_->bounds().ToString());
-}
-
-// Assertions around collapsing and expanding.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_Compress) {
- window_->SetBounds(gfx::Rect( 0, 300, 400, 300));
- window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the left, which should expand w2 and collapse w1.
- resizer->Drag(CalculateDragPoint(*resizer, -100, 10), 0);
- EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
- EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
-
- // Collapse all the way to w1's min.
- delegate_.set_min_size(gfx::Size(20, 20));
- resizer->Drag(CalculateDragPoint(*resizer, -800, 20), 0);
- EXPECT_EQ("0,300 20x300", window_->bounds().ToString());
- EXPECT_EQ("20,200 480x200", window2_->bounds().ToString());
-
- // Move 100 to the left.
- resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
- EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
- EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
-
- // Back to -100.
- resizer->Drag(CalculateDragPoint(*resizer, -100, 20), 0);
- EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
- EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
-}
-
-// Assertions around attached window resize dragging from the right with 3
-// windows.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3) {
- window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
- window2_->SetBounds(gfx::Rect(300, 300, 150, 200));
- window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
- delegate2_.set_min_size(gfx::Size(52, 50));
- delegate3_.set_min_size(gfx::Size(38, 50));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the right, which should expand w1 and push w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
- EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
- EXPECT_EQ("400,300 150x200", window2_->bounds().ToString());
- EXPECT_EQ("550,300 100x200", window3_->bounds().ToString());
-
- // Move it 300, things should compress.
- resizer->Drag(CalculateDragPoint(*resizer, 300, -10), 0);
- EXPECT_EQ("100,300 500x300", window_->bounds().ToString());
- EXPECT_EQ("600,300 120x200", window2_->bounds().ToString());
- EXPECT_EQ("720,300 80x200", window3_->bounds().ToString());
-
- // Move it so much the last two end up at their min.
- resizer->Drag(CalculateDragPoint(*resizer, 800, 50), 0);
- EXPECT_EQ("100,300 610x300", window_->bounds().ToString());
- EXPECT_EQ("710,300 52x200", window2_->bounds().ToString());
- EXPECT_EQ("762,300 38x200", window3_->bounds().ToString());
-
- // Revert and make sure everything moves back.
- resizer->RevertDrag();
- EXPECT_EQ("100,300 200x300", window_->bounds().ToString());
- EXPECT_EQ("300,300 150x200", window2_->bounds().ToString());
- EXPECT_EQ("450,300 100x200", window3_->bounds().ToString());
-}
-
-// Assertions around attached window resizing (collapsing and expanding) with
-// 3 windows.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3_Compress) {
- window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
- window2_->SetBounds(gfx::Rect(300, 300, 200, 200));
- window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
- delegate2_.set_min_size(gfx::Size(52, 50));
- delegate3_.set_min_size(gfx::Size(38, 50));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it -100 to the right, which should collapse w1 and expand w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
- EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
- EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
- EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
-
- // Move it 100 to the right.
- resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
- EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
- EXPECT_EQ("400,300 200x200", window2_->bounds().ToString());
- EXPECT_EQ("600,300 100x200", window3_->bounds().ToString());
-
- // 100 to the left again.
- resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
- EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
- EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
- EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
-}
-
-// Assertions around collapsing and expanding from the bottom.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_Compress) {
- window_->SetBounds(gfx::Rect( 0, 100, 400, 300));
- window2_->SetBounds(gfx::Rect(400, 400, 100, 200));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it up 100, which should expand w2 and collapse w1.
- resizer->Drag(CalculateDragPoint(*resizer, 10, -100), 0);
- EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
- EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
-
- // Collapse all the way to w1's min.
- delegate_.set_min_size(gfx::Size(20, 20));
- resizer->Drag(CalculateDragPoint(*resizer, 20, -800), 0);
- EXPECT_EQ("0,100 400x20", window_->bounds().ToString());
- EXPECT_EQ("400,120 100x480", window2_->bounds().ToString());
-
- // Move 100 down.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
- EXPECT_EQ("0,100 400x400", window_->bounds().ToString());
- EXPECT_EQ("400,500 100x100", window2_->bounds().ToString());
-
- // Back to -100.
- resizer->Drag(CalculateDragPoint(*resizer, 20, -100), 0);
- EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
- EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
-}
-
-// Assertions around attached window resize dragging from the bottom with 2
-// windows.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) {
- window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
- window2_->SetBounds(gfx::Rect(0, 250, 200, 100));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the bottom, which should expand w1 and push w2.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
- EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
- EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
-
- // Push off the screen, w2 should be resized to its min.
- delegate2_.set_min_size(gfx::Size(20, 20));
- resizer->Drag(CalculateDragPoint(*resizer, 50, 820), 0);
- EXPECT_EQ("0,50 400x530", window_->bounds().ToString());
- EXPECT_EQ("0,580 200x20", window2_->bounds().ToString());
-
- // Move back to 100 and verify w2 gets its original size.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
- EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
- EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
-
- // Revert and make sure everything moves back.
- resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
- resizer->RevertDrag();
- EXPECT_EQ("0,50 400x200", window_->bounds().ToString());
- EXPECT_EQ("0,250 200x100", window2_->bounds().ToString());
-}
-
-#if defined(OS_WIN)
-// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
-#define MAYBE_AttachedResize_BOTTOM_3 DISABLED_AttachedResize_BOTTOM_3
-#else
-#define MAYBE_AttachedResize_BOTTOM_3 AttachedResize_BOTTOM_3
-#endif
-
-// Assertions around attached window resize dragging from the bottom with 3
-// windows.
-TEST_F(WorkspaceWindowResizerTest, MAYBE_AttachedResize_BOTTOM_3) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- window_->SetBounds(gfx::Rect( 300, 100, 300, 200));
- window2_->SetBounds(gfx::Rect(300, 300, 200, 150));
- window3_->SetBounds(gfx::Rect(300, 450, 200, 100));
- delegate2_.set_min_size(gfx::Size(50, 52));
- delegate3_.set_min_size(gfx::Size(50, 38));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 down, which should expand w1 and push w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, -10, 100), 0);
- EXPECT_EQ("300,100 300x300", window_->bounds().ToString());
- EXPECT_EQ("300,400 200x150", window2_->bounds().ToString());
- EXPECT_EQ("300,550 200x100", window3_->bounds().ToString());
-
- // Move it 296 things should compress.
- resizer->Drag(CalculateDragPoint(*resizer, -10, 296), 0);
- EXPECT_EQ("300,100 300x496", window_->bounds().ToString());
- EXPECT_EQ("300,596 200x123", window2_->bounds().ToString());
- EXPECT_EQ("300,719 200x81", window3_->bounds().ToString());
-
- // Move it so much everything ends up at its min.
- resizer->Drag(CalculateDragPoint(*resizer, 50, 798), 0);
- EXPECT_EQ("300,100 300x610", window_->bounds().ToString());
- EXPECT_EQ("300,710 200x52", window2_->bounds().ToString());
- EXPECT_EQ("300,762 200x38", window3_->bounds().ToString());
-
- // Revert and make sure everything moves back.
- resizer->RevertDrag();
- EXPECT_EQ("300,100 300x200", window_->bounds().ToString());
- EXPECT_EQ("300,300 200x150", window2_->bounds().ToString());
- EXPECT_EQ("300,450 200x100", window3_->bounds().ToString());
-}
-
-// Assertions around attached window resizing (collapsing and expanding) with
-// 3 windows.
-TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3_Compress) {
- window_->SetBounds(gfx::Rect( 0, 0, 200, 200));
- window2_->SetBounds(gfx::Rect(10, 200, 200, 200));
- window3_->SetBounds(gfx::Rect(20, 400, 100, 100));
- delegate2_.set_min_size(gfx::Size(52, 50));
- delegate3_.set_min_size(gfx::Size(38, 50));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 up, which should collapse w1 and expand w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
- EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
- EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
- EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
-
- // Move it 100 down.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
- EXPECT_EQ("0,0 200x300", window_->bounds().ToString());
- EXPECT_EQ("10,300 200x200", window2_->bounds().ToString());
- EXPECT_EQ("20,500 100x100", window3_->bounds().ToString());
-
- // 100 up again.
- resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
- EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
- EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
- EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
-}
-
-// Tests that touch-dragging a window does not lock the mouse cursor
-// and therefore shows the cursor on a mousemove.
-TEST_F(WorkspaceWindowResizerTest, MouseMoveWithTouchDrag) {
- window_->SetBounds(gfx::Rect(0, 300, 400, 300));
- window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
-
- Shell* shell = Shell::GetInstance();
- aura::test::EventGenerator generator(window_->GetRootWindow());
-
- // The cursor should not be locked initially.
- EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_TOUCH, windows));
- ASSERT_TRUE(resizer.get());
-
- // Creating a WorkspaceWindowResizer should not lock the cursor.
- EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
-
- // The cursor should be hidden after touching the screen and
- // starting a drag.
- EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
- generator.PressTouch();
- resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
- EXPECT_FALSE(shell->cursor_manager()->IsCursorVisible());
- EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
-
- // Moving the mouse should show the cursor.
- generator.MoveMouseBy(1, 1);
- EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
- EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
-
- resizer->RevertDrag();
-}
-
-// Assertions around dragging to the left/right edge of the screen.
-TEST_F(WorkspaceWindowResizerTest, Edge) {
- if (!SupportsHostWindowResize())
- return;
-
- // Resize host window to force insets update.
- UpdateDisplay("800x700");
- // TODO(varkha): Insets are reset after every drag because of
- // http://crbug.com/292238.
- // Window is wide enough not to get docked right away.
- window_->SetBounds(gfx::Rect(20, 30, 400, 60));
- wm::WindowState* window_state = wm::GetWindowState(window_.get());
-
- {
- internal::SnapSizer snap_sizer(window_state, gfx::Point(),
- internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT);
- gfx::Rect expected_bounds(snap_sizer.target_bounds());
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
- resizer->CompleteDrag(0);
-
- EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
- ASSERT_TRUE(window_state->HasRestoreBounds());
- EXPECT_EQ("20,30 400x60",
- window_state->GetRestoreBoundsInScreen().ToString());
- }
- // Try the same with the right side.
- {
- internal::SnapSizer snap_sizer(window_state, gfx::Point(),
- internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT);
- gfx::Rect expected_bounds(snap_sizer.target_bounds());
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
- resizer->CompleteDrag(0);
- EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
- ASSERT_TRUE(window_state->HasRestoreBounds());
- EXPECT_EQ("20,30 400x60",
- window_state->GetRestoreBoundsInScreen().ToString());
- }
-
- // Test if the restore bounds is correct in multiple displays.
- if (!SupportsMultipleDisplays())
- return;
-
- // Restore the window to clear snapped state.
- window_state->Restore();
-
- UpdateDisplay("800x600,500x600");
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- EXPECT_EQ(root_windows[0], window_->GetRootWindow());
- // Window is wide enough not to get docked right away.
- window_->SetBoundsInScreen(gfx::Rect(800, 10, 400, 60),
- ScreenAsh::GetSecondaryDisplay());
- EXPECT_EQ(root_windows[1], window_->GetRootWindow());
- {
- EXPECT_EQ("800,10 400x60", window_->GetBoundsInScreen().ToString());
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 499, 0), 0);
- int bottom =
- ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
- resizer->CompleteDrag(0);
- // With the resolution of 500x600 we will hit in this case the 50% screen
- // size setting.
- // TODO(varkha): Insets are updated because of http://crbug.com/292238
- EXPECT_EQ("250,0 250x" + base::IntToString(bottom),
- window_->bounds().ToString());
- EXPECT_EQ("800,10 400x60",
- window_state->GetRestoreBoundsInScreen().ToString());
- }
-}
-
-// Check that non resizable windows will not get resized.
-TEST_F(WorkspaceWindowResizerTest, NonResizableWindows) {
- window_->SetBounds(gfx::Rect(20, 30, 50, 60));
- window_->SetProperty(aura::client::kCanResizeKey, false);
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, -20, 0), 0);
- resizer->CompleteDrag(0);
- EXPECT_EQ("0,30 50x60", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, CancelSnapPhantom) {
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("800x600,800x600");
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- ASSERT_EQ(2U, root_windows.size());
-
- window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
- Shell::GetScreen()->GetPrimaryDisplay());
- EXPECT_EQ(root_windows[0], window_->GetRootWindow());
- EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
- {
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- EXPECT_FALSE(snap_phantom_window_controller());
-
- // The pointer is on the edge but not shared. The snap phantom window
- // controller should be non-NULL.
- resizer->Drag(CalculateDragPoint(*resizer, 799, 0), 0);
- EXPECT_TRUE(snap_phantom_window_controller());
-
- // Move the cursor across the edge. Now the snap phantom window controller
- // should be canceled.
- resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
- EXPECT_FALSE(snap_phantom_window_controller());
- }
-}
-
-// Verifies windows are correctly restacked when reordering multiple windows.
-TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
- window_->SetBounds(gfx::Rect( 0, 0, 200, 300));
- window2_->SetBounds(gfx::Rect(200, 0, 100, 200));
- window3_->SetBounds(gfx::Rect(300, 0, 100, 100));
-
- {
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the right, which should expand w1 and push w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
-
- // 2 should be topmost since it's initially the highest in the stack.
- EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
- }
-
- {
- std::vector<aura::Window*> windows;
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window2_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the right, which should expand w1 and push w2 and w3.
- resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
-
- // 2 should be topmost since it's initially the highest in the stack.
- EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
- }
-}
-
-// Makes sure we don't allow dragging below the work area.
-TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
-
- ASSERT_EQ(1, Shell::GetScreen()->GetNumDisplays());
-
- window_->SetBounds(gfx::Rect(100, 200, 300, 400));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
- int expected_y =
- kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
- EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
- window_->bounds().ToString());
-}
-
-// Makes sure we don't allow dragging on the work area with multidisplay.
-TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("800x600,800x600");
- ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
-
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
-
- // Positions the secondary display at the bottom the primary display.
- Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
- ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
-
- {
- window_->SetBounds(gfx::Rect(100, 200, 300, 20));
- DCHECK_LT(window_->bounds().height(),
- WorkspaceWindowResizer::kMinOnscreenHeight);
- // Drag down avoiding dragging along the edge as that would side-snap.
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(10, 0), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
- int expected_y = kRootHeight - window_->bounds().height() - 10;
- // When the mouse cursor is in the primary display, the window cannot move
- // on non-work area but can get all the way towards the bottom,
- // restricted only by the window height.
- EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x20",
- window_->bounds().ToString());
- // Revert the drag in order to not remember the restore bounds.
- resizer->RevertDrag();
- }
-
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
- {
- window_->SetBounds(gfx::Rect(100, 200, 300, 400));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(10, 0), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Drag down avoiding dragging along the edge as that would side-snap.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
- int expected_y =
- kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
- // When the mouse cursor is in the primary display, the window cannot move
- // on non-work area with kMinOnscreenHeight margin.
- EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
- window_->bounds().ToString());
- resizer->CompleteDrag(0);
- }
-
- {
- window_->SetBounds(gfx::Rect(100, 200, 300, 400));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), window_->bounds().origin(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Drag down avoiding getting stuck against the shelf on the bottom screen.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 500), 0);
- // The window can move to the secondary display beyond non-work area of
- // the primary display.
- EXPECT_EQ("100,700 300x400", window_->bounds().ToString());
- resizer->CompleteDrag(0);
- }
-}
-
-// Makes sure we don't allow dragging off the top of the work area.
-TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0));
-
- window_->SetBounds(gfx::Rect(100, 200, 300, 400));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, -600), 0);
- EXPECT_EQ("100,10 300x400", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
-
- window_->SetBounds(gfx::Rect(100, 200, 300, 380));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOP));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 8, 0), 0);
- EXPECT_EQ("100,200 300x380", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
- int left = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).x();
- int pixels_to_left_border = 50;
- int window_width = 300;
- int window_x = left - window_width + pixels_to_left_border;
- window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
- EXPECT_EQ(base::IntToString(window_x) + ",100 " +
- base::IntToString(kMinimumOnScreenArea - window_x) +
- "x380", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
- int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()).right();
- int pixels_to_right_border = 50;
- int window_width = 300;
- int window_x = right - pixels_to_right_border;
- window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(window_x, 0), HTLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
- EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
- ",100 " +
- base::IntToString(window_width - pixels_to_right_border +
- kMinimumOnScreenArea) +
- "x380", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
- int bottom = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()).bottom();
- int delta_to_bottom = 50;
- int height = 380;
- window_->SetBounds(gfx::Rect(100, bottom - delta_to_bottom, 300, height));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
- EXPECT_EQ("100," +
- base::IntToString(bottom - kMinimumOnScreenArea) +
- " 300x" +
- base::IntToString(height - (delta_to_bottom -
- kMinimumOnScreenArea)),
- window_->bounds().ToString());
-}
-
-// Verifies that 'outside' check of the resizer take into account the extended
-// desktop in case of repositions.
-TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
- // Only primary display. Changes the window position to fit within the
- // display.
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
- int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()).right();
- int pixels_to_right_border = 50;
- int window_width = 300;
- int window_x = right - pixels_to_right_border;
- window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(window_x, 0), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
- EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
- ",100 " +
- base::IntToString(window_width) +
- "x380", window_->bounds().ToString());
-
- if (!SupportsMultipleDisplays())
- return;
-
- // With secondary display. Operation itself is same but doesn't change
- // the position because the window is still within the secondary display.
- UpdateDisplay("1000x600,600x400");
- Shell::GetInstance()->SetDisplayWorkAreaInsets(
- Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
- window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
- resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
- EXPECT_EQ(base::IntToString(window_x + window_width) +
- ",100 " +
- base::IntToString(window_width) +
- "x380", window_->bounds().ToString());
-}
-
-// Verifies snapping to edges works.
-TEST_F(WorkspaceWindowResizerTest, SnapToEdge) {
- Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
- SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
- window_->SetBounds(gfx::Rect(96, 112, 320, 160));
- // Click 50px to the right so that the mouse pointer does not leave the
- // workspace ensuring sticky behavior.
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(),
- window_->bounds().origin() + gfx::Vector2d(50, 0),
- HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move to an x-coordinate of 15, which should not snap.
- resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
- // An x-coordinate of 7 should snap.
- resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
- EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
- // Move to -15, should still snap to 0.
- resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
- EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
- // At -32 should move past snap points.
- resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
- EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
- EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
-
- // Right side should similarly snap.
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
- EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 7, 0), 0);
- EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
- EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 32, 0), 0);
- EXPECT_EQ("512,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 33, 0), 0);
- EXPECT_EQ("513,112 320x160", window_->bounds().ToString());
-
- // And the bottom should snap too.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 - 7), 0);
- EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
- EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 32), 0);
- EXPECT_EQ("96,470 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 33), 0);
- EXPECT_EQ("96,471 320x160", window_->bounds().ToString());
-
- // And the top should snap too.
- resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 20), 0);
- EXPECT_EQ("96,20 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 7), 0);
- EXPECT_EQ("96,0 320x160", window_->bounds().ToString());
-
- // And bottom/left should snap too.
- resizer->Drag(
- CalculateDragPoint(*resizer, 7 - 96, 600 - 160 - 112 - 3 - 7), 0);
- EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
- resizer->Drag(
- CalculateDragPoint(*resizer, -15 - 96, 600 - 160 - 112 - 3 + 15), 0);
- EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
- // should move past snap points.
- resizer->Drag(
- CalculateDragPoint(*resizer, -32 - 96, 600 - 160 - 112 - 2 + 32), 0);
- EXPECT_EQ("-32,470 320x160", window_->bounds().ToString());
- resizer->Drag(
- CalculateDragPoint(*resizer, -33 - 96, 600 - 160 - 112 - 2 + 33), 0);
- EXPECT_EQ("-33,471 320x160", window_->bounds().ToString());
-
- // No need to test dragging < 0 as we force that to 0.
-}
-
-// Verifies a resize snap when dragging TOPLEFT.
-TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, -98, -199), 0);
- EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
-}
-
-// Verifies a resize snap when dragging TOPRIGHT.
-TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(
- CalculateDragPoint(*resizer, work_area.right() - 120 - 1, -199), 0);
- EXPECT_EQ(100, window_->bounds().x());
- EXPECT_EQ(work_area.y(), window_->bounds().y());
- EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
- EXPECT_EQ(230, window_->bounds().height());
-}
-
-// Verifies a resize snap when dragging BOTTOMRIGHT.
-TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(
- CalculateDragPoint(*resizer, work_area.right() - 120 - 1,
- work_area.bottom() - 220 - 2), 0);
- EXPECT_EQ(100, window_->bounds().x());
- EXPECT_EQ(200, window_->bounds().y());
- EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
- EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
-}
-
-// Verifies a resize snap when dragging BOTTOMLEFT.
-TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(
- CalculateDragPoint(*resizer, -98, work_area.bottom() - 220 - 2), 0);
- EXPECT_EQ(0, window_->bounds().x());
- EXPECT_EQ(200, window_->bounds().y());
- EXPECT_EQ(120, window_->bounds().width());
- EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
-}
-
-// Verifies sticking to edges works.
-TEST_F(WorkspaceWindowResizerTestSticky, StickToEdge) {
- Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
- SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
- window_->SetBounds(gfx::Rect(96, 112, 320, 160));
- // Click 50px to the right so that the mouse pointer does not leave the
- // workspace ensuring sticky behavior.
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(),
- window_->bounds().origin() + gfx::Vector2d(50, 0),
- HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move to an x-coordinate of 15, which should not stick.
- resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
- // Move to -15, should still stick to 0.
- resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
- EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
- // At -100 should move past edge.
- resizer->Drag(CalculateDragPoint(*resizer, -100 - 96, 0), 0);
- EXPECT_EQ("-100,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, -101 - 96, 0), 0);
- EXPECT_EQ("-101,112 320x160", window_->bounds().ToString());
-
- // Right side should similarly stick.
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
- EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
- EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 100, 0), 0);
- EXPECT_EQ("580,112 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 101, 0), 0);
- EXPECT_EQ("581,112 320x160", window_->bounds().ToString());
-
- // And the bottom should stick too.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
- EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 100), 0);
- EXPECT_EQ("96,538 320x160", window_->bounds().ToString());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 101), 0);
- EXPECT_EQ("96,539 320x160", window_->bounds().ToString());
-
- // No need to test dragging < 0 as we force that to 0.
-}
-
-// Verifies not sticking to edges when a mouse pointer is outside of work area.
-TEST_F(WorkspaceWindowResizerTestSticky, NoStickToEdgeWhenOutside) {
- Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
- SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
- window_->SetBounds(gfx::Rect(96, 112, 320, 160));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move to an x-coordinate of 15, which should not stick.
- resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
- // Move to -15, should still stick to 0.
- resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
- EXPECT_EQ("-15,112 320x160", window_->bounds().ToString());
-}
-
-// Verifies a resize sticks when dragging TOPLEFT.
-TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, -15 - 100, -15 -200), 0);
- EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
-}
-
-// Verifies a resize sticks when dragging TOPRIGHT.
-TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 + 20,
- -200 - 15), 0);
- EXPECT_EQ(100, window_->bounds().x());
- EXPECT_EQ(work_area.y(), window_->bounds().y());
- EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
- EXPECT_EQ(230, window_->bounds().height());
-}
-
-// Verifies a resize snap when dragging BOTTOMRIGHT.
-TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 - 20 + 15,
- work_area.bottom() - 200 - 30 + 15), 0);
- EXPECT_EQ(100, window_->bounds().x());
- EXPECT_EQ(200, window_->bounds().y());
- EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
- EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
-}
-
-// Verifies a resize snap when dragging BOTTOMLEFT.
-TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- window_.get()));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, -15 - 100,
- work_area.bottom() - 200 - 30 + 15), 0);
- EXPECT_EQ(0, window_->bounds().x());
- EXPECT_EQ(200, window_->bounds().y());
- EXPECT_EQ(120, window_->bounds().width());
- EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
-}
-
-TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
- window_->SetBounds(gfx::Rect(96, 112, 320, 160));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- ASSERT_TRUE(resizer.get());
- // Resize the right bottom to add 10 in width, 12 in height.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 12), ui::EF_CONTROL_DOWN);
- // Both bottom and right sides to resize to exact size requested.
- EXPECT_EQ("96,112 330x172", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) {
- window_->SetBounds(gfx::Rect(96, 112, 320, 160));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Ctrl + drag the window to new poistion by adding (10, 12) to its origin,
- // the window should move to the exact position.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 12), 0);
- resizer->CompleteDrag(ui::EF_CONTROL_DOWN);
- EXPECT_EQ("106,124 320x160", window_->bounds().ToString());
-}
-
-// Verifies that a dragged window will restore to its pre-maximized size.
-TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
- window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
- wm::WindowState* window_state = wm::GetWindowState(window_.get());
- window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Drag the window to new position by adding (10, 10) to original point,
- // the window should get restored.
- resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
- resizer->CompleteDrag(0);
- EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
- // The restore rectangle should get cleared as well.
- EXPECT_FALSE(window_state->HasRestoreBounds());
-}
-
-// Verifies that a dragged window will restore to its pre-maximized size.
-TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
- const gfx::Rect initial_bounds(0, 0, 200, 400);
- window_->SetBounds(initial_bounds);
-
- wm::WindowState* window_state = wm::GetWindowState(window_.get());
- window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Drag the window to new poistion by adding (180, 16) to original point,
- // the window should get restored.
- resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
- resizer->RevertDrag();
- EXPECT_EQ(initial_bounds.ToString(), window_->bounds().ToString());
- EXPECT_EQ("96,112 320x160",
- window_state->GetRestoreBoundsInScreen().ToString());
-}
-
-// Check that only usable sizes get returned by the resizer.
-TEST_F(WorkspaceWindowResizerTest, MagneticallyAttach) {
- window_->SetBounds(gfx::Rect(10, 10, 20, 30));
- window2_->SetBounds(gfx::Rect(150, 160, 25, 20));
- window2_->Show();
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move |window| one pixel to the left of |window2|. Should snap to right and
- // top.
- resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
- EXPECT_EQ("130,160 20x30", window_->bounds().ToString());
-
- // Move |window| one pixel to the right of |window2|. Should snap to left and
- // top.
- resizer->Drag(CalculateDragPoint(*resizer, 164, 145), 0);
- EXPECT_EQ("175,160 20x30", window_->bounds().ToString());
-
- // Move |window| one pixel above |window2|. Should snap to top and left.
- resizer->Drag(CalculateDragPoint(*resizer, 142, 119), 0);
- EXPECT_EQ("150,130 20x30", window_->bounds().ToString());
-
- // Move |window| one pixel above the bottom of |window2|. Should snap to
- // bottom and left.
- resizer->Drag(CalculateDragPoint(*resizer, 142, 169), 0);
- EXPECT_EQ("150,180 20x30", window_->bounds().ToString());
-}
-
-// The following variants verify magnetic snapping during resize when dragging a
-// particular edge.
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOP) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
- window2_->Show();
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOP));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,199 20x31", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
- window2_->Show();
-
- {
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("99,199 21x31", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-
- {
- window2_->SetBounds(gfx::Rect(88, 201, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("98,201 22x29", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->Show();
-
- {
- window2_->SetBounds(gfx::Rect(111, 179, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-
- {
- window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTTOPRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_RIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
- window2_->Show();
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,200 21x30", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMRIGHT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->Show();
-
- {
- window2_->SetBounds(gfx::Rect(122, 212, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,200 22x32", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-
- {
- window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,200 21x33", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOM) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
- window2_->Show();
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOM));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("100,200 20x33", window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMLEFT) {
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->Show();
-
- {
- window2_->SetBounds(gfx::Rect(99, 231, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("99,200 21x31", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-
- {
- window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("99,200 21x29", window_->bounds().ToString());
- resizer->RevertDrag();
- }
-}
-
-TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_LEFT) {
- window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
- window_->SetBounds(gfx::Rect(100, 200, 20, 30));
- window2_->Show();
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTLEFT));
- ASSERT_TRUE(resizer.get());
- resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
- EXPECT_EQ("99,200 21x30", window_->bounds().ToString());
-}
-
-// Test that the user user moved window flag is getting properly set.
-TEST_F(WorkspaceWindowResizerTest, CheckUserWindowManagedFlags) {
- window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
-
- std::vector<aura::Window*> no_attached_windows;
- // Check that an abort doesn't change anything.
- {
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the bottom.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
- EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
- resizer->RevertDrag();
-
- EXPECT_FALSE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
- }
-
- // Check that a completed move / size does change the user coordinates.
- {
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- // Move it 100 to the bottom.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
- EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
- resizer->CompleteDrag(0);
- EXPECT_TRUE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
- }
-}
-
-// Test that a window with a specified max size doesn't exceed it when dragged.
-TEST_F(WorkspaceWindowResizerTest, TestMaxSizeEnforced) {
- window_->SetBounds(gfx::Rect(0, 0, 400, 300));
- delegate_.set_max_size(gfx::Size(401, 301));
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
- EXPECT_EQ(401, window_->bounds().width());
- EXPECT_EQ(301, window_->bounds().height());
-}
-
-// Test that a window with a specified max width doesn't restrict its height.
-TEST_F(WorkspaceWindowResizerTest, TestPartialMaxSizeEnforced) {
- window_->SetBounds(gfx::Rect(0, 0, 400, 300));
- delegate_.set_max_size(gfx::Size(401, 0));
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTBOTTOMRIGHT));
- resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
- EXPECT_EQ(401, window_->bounds().width());
- EXPECT_EQ(302, window_->bounds().height());
-}
-
-// Test that a window with a specified max size can't be snapped.
-TEST_F(WorkspaceWindowResizerTest, PhantomSnapMaxSize) {
- {
- // With max size not set we get a phantom window controller for dragging off
- // the right hand side.
- // Make the window wider than maximum docked width.
- window_->SetBounds(gfx::Rect(0, 0, 400, 200));
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- EXPECT_FALSE(snap_phantom_window_controller());
- resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
- EXPECT_TRUE(snap_phantom_window_controller());
- resizer->RevertDrag();
- }
- {
- // With max size defined, we get no phantom window for snapping but we still
- // get a phantom window (docking guide).
- window_->SetBounds(gfx::Rect(0, 0, 400, 200));
- delegate_.set_max_size(gfx::Size(400, 200));
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
- if (switches::UseDockedWindows())
- EXPECT_TRUE(snap_phantom_window_controller());
- else
- EXPECT_FALSE(snap_phantom_window_controller());
- resizer->RevertDrag();
- }
- {
- // With max size defined, we get no phantom window for snapping.
- window_->SetBounds(gfx::Rect(0, 0, 400, 200));
- delegate_.set_max_size(gfx::Size(400, 200));
- // With min size defined, we get no phantom window for docking.
- delegate_.set_min_size(gfx::Size(400, 200));
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
- EXPECT_FALSE(snap_phantom_window_controller());
- resizer->RevertDrag();
- }
-}
-
-TEST_F(WorkspaceWindowResizerTest, DontRewardRightmostWindowForOverflows) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Four 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
- delegate2_.set_max_size(gfx::Size(101, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 51 to the left, which should contract w1 and expand w2-4.
- // w2 will hit its max size straight away, and in doing so will leave extra
- // pixels that a naive implementation may award to the rightmost window. A
- // fair implementation will give 25 pixels to each of the other windows.
- resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
- EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
- EXPECT_EQ("149,100 101x100", window2_->bounds().ToString());
- EXPECT_EQ("250,100 125x100", window3_->bounds().ToString());
- EXPECT_EQ("375,100 125x100", window4_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, DontExceedMaxWidth) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Four 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
- delegate2_.set_max_size(gfx::Size(101, 0));
- delegate3_.set_max_size(gfx::Size(101, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 52 to the left, which should contract w1 and expand w2-4.
- resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
- EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
- EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
- EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
- EXPECT_EQ("350,100 150x100", window4_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, DontExceedMaxHeight) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Four 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
- window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
- window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
- delegate2_.set_max_size(gfx::Size(0, 101));
- delegate3_.set_max_size(gfx::Size(0, 101));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 52 up, which should contract w1 and expand w2-4.
- resizer->Drag(CalculateDragPoint(*resizer, 0, -52), 0);
- EXPECT_EQ("100,100 100x48", window_->bounds().ToString());
- EXPECT_EQ("100,148 100x101", window2_->bounds().ToString());
- EXPECT_EQ("100,249 100x101", window3_->bounds().ToString());
- EXPECT_EQ("100,350 100x150", window4_->bounds().ToString());
-}
-
-#if defined(OS_WIN)
-// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
-#define MAYBE_DontExceedMinHeight DISABLED_DontExceedMinHeight
-#else
-#define MAYBE_DontExceedMinHeight DontExceedMinHeight
-#endif
-
-TEST_F(WorkspaceWindowResizerTest, MAYBE_DontExceedMinHeight) {
- UpdateDisplay("600x500");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Four 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
- window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
- window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
- delegate2_.set_min_size(gfx::Size(0, 99));
- delegate3_.set_min_size(gfx::Size(0, 99));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTBOTTOM,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 52 down, which should expand w1 and contract w2-4.
- resizer->Drag(CalculateDragPoint(*resizer, 0, 52), 0);
- EXPECT_EQ("100,100 100x152", window_->bounds().ToString());
- EXPECT_EQ("100,252 100x99", window2_->bounds().ToString());
- EXPECT_EQ("100,351 100x99", window3_->bounds().ToString());
- EXPECT_EQ("100,450 100x50", window4_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, DontExpandRightmostPastMaxWidth) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Three 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- delegate3_.set_max_size(gfx::Size(101, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 51 to the left, which should contract w1 and expand w2-3.
- resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
- EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
- EXPECT_EQ("149,100 150x100", window2_->bounds().ToString());
- EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, MoveAttachedWhenGrownToMaxSize) {
- UpdateDisplay("600x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Three 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- delegate2_.set_max_size(gfx::Size(101, 0));
- delegate3_.set_max_size(gfx::Size(101, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 52 to the left, which should contract w1 and expand and move w2-3.
- resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
- EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
- EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
- EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
-}
-
-#if defined(OS_WIN)
-// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
-#define MAYBE_MainWindowHonoursMaxWidth DISABLED_MainWindowHonoursMaxWidth
-#else
-#define MAYBE_MainWindowHonoursMaxWidth MainWindowHonoursMaxWidth
-#endif
-
-TEST_F(WorkspaceWindowResizerTest, MAYBE_MainWindowHonoursMaxWidth) {
- UpdateDisplay("400x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Three 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- delegate_.set_max_size(gfx::Size(102, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- windows.push_back(window4_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 50 to the right, which should expand w1 and contract w2-3, as they
- // won't fit in the root window in their original sizes.
- resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
- EXPECT_EQ("100,100 102x100", window_->bounds().ToString());
- EXPECT_EQ("202,100 99x100", window2_->bounds().ToString());
- EXPECT_EQ("301,100 99x100", window3_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, MainWindowHonoursMinWidth) {
- UpdateDisplay("400x800");
- aura::Window* root = Shell::GetPrimaryRootWindow();
- Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
-
- // Three 100x100 windows flush against eachother, starting at 100,100.
- window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
- window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
- window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
- delegate_.set_min_size(gfx::Size(98, 0));
-
- std::vector<aura::Window*> windows;
- windows.push_back(window2_.get());
- windows.push_back(window3_.get());
- scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
- window_.get(), gfx::Point(), HTRIGHT,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
- ASSERT_TRUE(resizer.get());
- // Move it 50 to the left, which should contract w1 and expand w2-3.
- resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
- EXPECT_EQ("100,100 98x100", window_->bounds().ToString());
- EXPECT_EQ("198,100 101x100", window2_->bounds().ToString());
- EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
-}
-
-// The following variants test that windows are resized correctly to the edges
-// of the screen using touch, when touch point is off of the window border.
-TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_RIGHT) {
- shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-
- InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTRIGHT);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- touch_resize_window_.get());
-
- // Drag out of the right border a bit and check if the border is aligned with
- // the touch point.
- generator.GestureScrollSequence(gfx::Point(715, kRootHeight / 2),
- gfx::Point(725, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 625, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag more, but stop before being snapped to the edge.
- generator.GestureScrollSequence(gfx::Point(725, kRootHeight / 2),
- gfx::Point(760, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 660, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag even more to snap to the edge.
- generator.GestureScrollSequence(gfx::Point(760, kRootHeight / 2),
- gfx::Point(775, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 700, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_LEFT) {
- shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-
- InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTLEFT);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- touch_resize_window_.get());
-
- // Drag out of the left border a bit and check if the border is aligned with
- // the touch point.
- generator.GestureScrollSequence(gfx::Point(85, kRootHeight / 2),
- gfx::Point(75, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(75, 100, 625, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag more, but stop before being snapped to the edge.
- generator.GestureScrollSequence(gfx::Point(75, kRootHeight / 2),
- gfx::Point(40, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(40, 100, 660, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag even more to snap to the edge.
- generator.GestureScrollSequence(gfx::Point(40, kRootHeight / 2),
- gfx::Point(25, kRootHeight / 2),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(0, 100, 700, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_TOP) {
- shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-
- InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTTOP);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- touch_resize_window_.get());
-
- // Drag out of the top border a bit and check if the border is aligned with
- // the touch point.
- generator.GestureScrollSequence(gfx::Point(400, 85),
- gfx::Point(400, 75),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 75, 600, kRootHeight - 175).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag more, but stop before being snapped to the edge.
- generator.GestureScrollSequence(gfx::Point(400, 75),
- gfx::Point(400, 40),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 40, 600, kRootHeight - 140).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag even more to snap to the edge.
- generator.GestureScrollSequence(gfx::Point(400, 40),
- gfx::Point(400, 25),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 0, 600, kRootHeight - 100).ToString(),
- touch_resize_window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
- shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-
- InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTBOTTOM);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
- touch_resize_window_->bounds().ToString());
-
- aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
- touch_resize_window_.get());
-
- // Drag out of the bottom border a bit and check if the border is aligned with
- // the touch point.
- generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 85),
- gfx::Point(400, kRootHeight - 75),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 175).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag more, but stop before being snapped to the edge.
- generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 75),
- gfx::Point(400, kRootHeight - 40),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 140).ToString(),
- touch_resize_window_->bounds().ToString());
- // Drag even more to snap to the edge.
- generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 40),
- gfx::Point(400, kRootHeight - 25),
- base::TimeDelta::FromMilliseconds(10),
- 5);
- EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 100).ToString(),
- touch_resize_window_->bounds().ToString());
-}
-
-TEST_F(WorkspaceWindowResizerTest, PhantomWindowShow) {
- if (!SupportsMultipleDisplays())
- return;
-
- UpdateDisplay("500x400,500x400");
- window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
- Shell::GetScreen()->GetPrimaryDisplay());
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- EXPECT_EQ(root_windows[0], window_->GetRootWindow());
-
- scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
- window_.get(), gfx::Point(), HTCAPTION));
- ASSERT_TRUE(resizer.get());
- EXPECT_FALSE(snap_phantom_window_controller());
-
- // The pointer is on the edge but not shared. The snap phantom window
- // controller should be non-NULL.
- resizer->Drag(CalculateDragPoint(*resizer, -1, 0), 0);
- EXPECT_TRUE(snap_phantom_window_controller());
- PhantomWindowController* phantom_controller(snap_phantom_window_controller());
-
- // phantom widget only in the left screen.
- phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_FALSE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
-
- // Move phantom widget into the right screen. Test that 2 widgets got created.
- phantom_controller->Show(gfx::Rect(600, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_TRUE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[1],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_start_->GetNativeWindow()->
- GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Move phantom widget only in the right screen. Start widget should close.
- phantom_controller->Show(gfx::Rect(700, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_FALSE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[1],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Move phantom widget into the left screen. Start widget should open.
- phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_TRUE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- EXPECT_EQ(
- root_windows[1],
- phantom_controller->phantom_widget_start_->GetNativeWindow()->
- GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Move phantom widget while in the left screen. Start widget should close.
- phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_FALSE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Move phantom widget spanning both screens with most of the window in the
- // right screen. Two widgets are created.
- phantom_controller->Show(gfx::Rect(495, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_TRUE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[1],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_start_->GetNativeWindow()->
- GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Move phantom widget back into the left screen. Phantom widgets should swap.
- phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
- EXPECT_TRUE(phantom_controller->phantom_widget_);
- EXPECT_TRUE(phantom_controller->phantom_widget_start_);
- EXPECT_EQ(
- root_windows[0],
- phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
- EXPECT_EQ(
- root_windows[1],
- phantom_controller->phantom_widget_start_->GetNativeWindow()->
- GetRootWindow());
- RunAnimationTillComplete(phantom_controller->animation_.get());
-
- // Hide phantom controller. Both widgets should close.
- phantom_controller->Hide();
- EXPECT_FALSE(phantom_controller->phantom_widget_);
- EXPECT_FALSE(phantom_controller->phantom_widget_start_);
-}
-
-} // namespace internal
-} // namespace ash