summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-26 04:02:37 +0000
committerpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-26 04:02:37 +0000
commit20674b4dcd1053defd1ba87acedd1164fa47a8a3 (patch)
treeb7855464b380a1bf2583725a1bfe43a3f8123d1d /ash
parented18102fa62b3ae69cb19891379ed199c86be22e (diff)
downloadchromium_src-20674b4dcd1053defd1ba87acedd1164fa47a8a3.zip
chromium_src-20674b4dcd1053defd1ba87acedd1164fa47a8a3.tar.gz
chromium_src-20674b4dcd1053defd1ba87acedd1164fa47a8a3.tar.bz2
This CL refactors ToplevelWindowEventHandler and TwoFingerDragHandler to make merging the two easier.
Notable changes: - Fixed weirdness due to initiating tab dragging while a different drag is in progress. - Makes it no longer possible to alter the window's show type via a fling while resizing (vs moving) the window. - Moved all of the code to set the state when beginning / completing a drag to ToplevelWindowEventHandler::AttemptToStartDrag() and ToplevelWindowEventHandler::CompleteDrag() - Removed unneeded code to animate to the side snapped states - Made the instances where ToplevelWindowEventHandler::OnGestureEvent() stops propagation more obvious BUG=324038 TEST=ToplevelWindowEventHandlerTest.RunMoveLoopRevertsInProgressDrag Review URL: https://codereview.chromium.org/115863002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242511 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/wm/gestures/two_finger_drag_handler.cc109
-rw-r--r--ash/wm/toplevel_window_event_handler.cc219
-rw-r--r--ash/wm/toplevel_window_event_handler.h20
-rw-r--r--ash/wm/toplevel_window_event_handler_unittest.cc28
4 files changed, 201 insertions, 175 deletions
diff --git a/ash/wm/gestures/two_finger_drag_handler.cc b/ash/wm/gestures/two_finger_drag_handler.cc
index 3f44a04..b1d57fe 100644
--- a/ash/wm/gestures/two_finger_drag_handler.cc
+++ b/ash/wm/gestures/two_finger_drag_handler.cc
@@ -11,61 +11,56 @@
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
-#include "ui/compositor/layer.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/wm/public/window_types.h"
namespace {
-bool IsTopEdge(int component) {
- return component == HTTOPLEFT ||
- component == HTTOP ||
- component == HTTOPRIGHT;
-}
-
-bool IsBottomEdge(int component) {
- return component == HTBOTTOMLEFT ||
- component == HTBOTTOM ||
- component == HTBOTTOMRIGHT;
-}
-
-bool IsRightEdge(int component) {
- return component == HTTOPRIGHT ||
- component == HTRIGHT ||
- component == HTBOTTOMRIGHT;
-}
-
-bool IsLeftEdge(int component) {
- return component == HTTOPLEFT ||
- component == HTLEFT ||
- component == HTBOTTOMLEFT;
-}
+enum Edge {
+ TOP = 1 << 0,
+ LEFT = 1 << 1,
+ BOTTOM = 1 << 2,
+ RIGHT = 1 << 3
+};
-bool IsSomeEdge(int component) {
- switch (component) {
+// Returns the bitfield of Edge which corresponds to |hittest_component|.
+int GetEdges(int hittest_component) {
+ switch (hittest_component) {
case HTTOPLEFT:
+ return TOP | LEFT;
case HTTOP:
+ return TOP;
case HTTOPRIGHT:
+ return TOP | RIGHT;
case HTRIGHT:
+ return RIGHT;
+ case HTGROWBOX:
case HTBOTTOMRIGHT:
+ return BOTTOM | RIGHT;
case HTBOTTOM:
+ return BOTTOM;
case HTBOTTOMLEFT:
+ return BOTTOM | LEFT;
case HTLEFT:
- return true;
+ return LEFT;
+ default:
+ return 0;
}
- return false;
}
-// Returns whether a window-move should be allowed depending on the hit-test
-// results of the two fingers.
-bool WindowComponentsAllowMoving(int component1, int component2) {
- return ((IsTopEdge(component1) && IsTopEdge(component2)) ||
- (IsBottomEdge(component1) && IsBottomEdge(component2)) ||
- (IsLeftEdge(component1) && IsLeftEdge(component2)) ||
- (IsRightEdge(component1) && IsRightEdge(component2)) ||
- (!IsSomeEdge(component1) && !IsSomeEdge(component2)));
+// Returns whether |window| can be moved via a two finger drag given
+// the hittest results of the two fingers.
+bool CanStartTwoFingerDrag(aura::Window* window,
+ int hittest_component1,
+ int hittest_component2) {
+ if (ash::wm::GetWindowState(window)->IsNormalShowState() &&
+ window->type() == ui::wm::WINDOW_TYPE_NORMAL) {
+ int edges1 = GetEdges(hittest_component1);
+ int edges2 = GetEdges(hittest_component2);
+ return (edges1 == edges2 || (edges1 & edges2) != 0);
+ }
+ return false;
}
} // namespace
@@ -97,31 +92,29 @@ bool TwoFingerDragHandler::ProcessGestureEvent(aura::Window* target,
if (event.type() == ui::ET_GESTURE_BEGIN &&
event.details().touch_points() == 2) {
- if (!in_gesture_drag_ && window_state->IsNormalShowState() &&
- target->type() == ui::wm::WINDOW_TYPE_NORMAL) {
- if (WindowComponentsAllowMoving(first_finger_hittest_,
- target->delegate()->GetNonClientComponent(event.location()))) {
- in_gesture_drag_ = true;
- target->AddObserver(this);
- // Only create a new WindowResizer if one doesn't already exist
- // for the target window.
- window_resizer_ = CreateWindowResizer(
- target,
- event.details().bounding_box().CenterPoint(),
- HTCAPTION,
- aura::client::WINDOW_MOVE_SOURCE_TOUCH);
- return true;
- }
+ int second_finger_hittest =
+ target->delegate()->GetNonClientComponent(event.location());
+ if (!in_gesture_drag_ &&
+ CanStartTwoFingerDrag(
+ target, first_finger_hittest_, second_finger_hittest)) {
+ in_gesture_drag_ = true;
+ target->AddObserver(this);
+ // Only create a new WindowResizer if one doesn't already exist
+ // for the target window.
+ window_resizer_ = CreateWindowResizer(
+ target,
+ event.details().bounding_box().CenterPoint(),
+ HTCAPTION,
+ aura::client::WINDOW_MOVE_SOURCE_TOUCH);
+ return true;
}
return false;
}
if (!in_gesture_drag_) {
- // Consume all two-finger gestures on a normal window.
- return event.details().touch_points() == 2 &&
- target->type() == ui::wm::WINDOW_TYPE_NORMAL &&
- window_state->IsNormalShowState();
+ // Consume all two-finger gestures.
+ return event.details().touch_points() == 2;
}
// Since |in_gesture_drag_| is true a resizer was either created above or
// it was created elsewhere and can be found in |window_state|.
@@ -158,10 +151,6 @@ bool TwoFingerDragHandler::ProcessGestureEvent(aura::Window* target,
} else if (event.details().swipe_down() && window_state->CanMinimize()) {
window_state->Minimize();
} else if (window_state->CanSnap()) {
- ui::ScopedLayerAnimationSettings scoped_setter(
- target->layer()->GetAnimator());
- scoped_setter.SetPreemptionStrategy(
- ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
internal::SnapSizer::SnapWindow(window_state,
event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE :
internal::SnapSizer::RIGHT_EDGE);
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc
index 10b2a88..933c947 100644
--- a/ash/wm/toplevel_window_event_handler.cc
+++ b/ash/wm/toplevel_window_event_handler.cc
@@ -22,8 +22,6 @@
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_types.h"
-#include "ui/compositor/layer.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/gestures/gesture_recognizer.h"
@@ -90,19 +88,15 @@ ToplevelWindowEventHandler::ScopedWindowResizer::ScopedWindowResizer(
WindowResizer* resizer)
: handler_(handler),
resizer_(resizer),
- target_container_(NULL) {
- if (resizer_) {
- resizer_->GetTarget()->AddObserver(this);
- wm::GetWindowState(resizer_->GetTarget())->AddObserver(this);
- }
+ target_container_(NULL) {
+ resizer_->GetTarget()->AddObserver(this);
+ wm::GetWindowState(resizer_->GetTarget())->AddObserver(this);
}
ToplevelWindowEventHandler::ScopedWindowResizer::~ScopedWindowResizer() {
RemoveHandlers();
- if (resizer_) {
- resizer_->GetTarget()->RemoveObserver(this);
- wm::GetWindowState(resizer_->GetTarget())->RemoveObserver(this);
- }
+ resizer_->GetTarget()->RemoveObserver(this);
+ wm::GetWindowState(resizer_->GetTarget())->RemoveObserver(this);
}
void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowHierarchyChanging(
@@ -127,7 +121,6 @@ void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowShowTypeChanged(
void ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowDestroying(
aura::Window* window) {
- DCHECK(resizer_.get());
DCHECK_EQ(resizer_->GetTarget(), window);
handler_->ResizerWindowDestroyed();
}
@@ -156,7 +149,7 @@ void ToplevelWindowEventHandler::ScopedWindowResizer::RemoveHandlers() {
ToplevelWindowEventHandler::ToplevelWindowEventHandler(aura::Window* owner)
: owner_(owner),
in_move_loop_(false),
- move_cancelled_(false),
+ drag_reverted_(false),
in_gesture_drag_(false),
destroyed_(NULL) {
aura::client::SetWindowMoveClient(owner, this);
@@ -215,9 +208,14 @@ void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (!target->delegate())
return;
- if (in_move_loop_ && !in_gesture_drag_)
+ if (window_resizer_.get() && !in_gesture_drag_)
return;
+ if (window_resizer_.get() &&
+ window_resizer_->resizer()->GetTarget() != target) {
+ return;
+ }
+
switch (event->type()) {
case ui::ET_GESTURE_TAP_DOWN: {
int component =
@@ -243,89 +241,62 @@ void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) {
return;
int component =
target->delegate()->GetNonClientComponent(event->location());
- if (WindowResizer::GetBoundsChangeForWindowComponent(component) == 0) {
- window_resizer_.reset();
+ if (WindowResizer::GetBoundsChangeForWindowComponent(component) == 0)
return;
- }
- in_gesture_drag_ = true;
- pre_drag_window_bounds_ = target->bounds();
gfx::Point location_in_parent(
ConvertPointToParent(target, event->location()));
- CreateScopedWindowResizer(target, location_in_parent, component,
- aura::client::WINDOW_MOVE_SOURCE_TOUCH);
- break;
+ AttemptToStartDrag(target, location_in_parent, component,
+ aura::client::WINDOW_MOVE_SOURCE_TOUCH);
+ event->StopPropagation();
+ return;
}
+ default:
+ break;
+ }
+
+ if (!in_gesture_drag_)
+ return;
+
+ switch (event->type()) {
case ui::ET_GESTURE_SCROLL_UPDATE: {
- if (!in_gesture_drag_)
- return;
- if (window_resizer_.get() &&
- window_resizer_->resizer()->GetTarget() != target) {
- return;
- }
HandleDrag(target, event);
- break;
+ event->StopPropagation();
+ return;
}
case ui::ET_GESTURE_SCROLL_END:
+ CompleteDrag(DRAG_COMPLETE, event->flags());
+ event->StopPropagation();
+ return;
case ui::ET_SCROLL_FLING_START: {
- if (!in_gesture_drag_)
- return;
- if (window_resizer_.get() &&
- window_resizer_->resizer()->GetTarget() != target) {
- return;
- }
-
CompleteDrag(DRAG_COMPLETE, event->flags());
- if (in_move_loop_) {
- quit_closure_.Run();
- in_move_loop_ = false;
- }
- in_gesture_drag_ = false;
-
- if (event->type() == ui::ET_GESTURE_SCROLL_END) {
- event->StopPropagation();
- return;
- }
int component =
target->delegate()->GetNonClientComponent(event->location());
- if (WindowResizer::GetBoundsChangeForWindowComponent(component) == 0)
+ if (component != HTCAPTION)
return;
wm::WindowState* window_state = wm::GetWindowState(target);
if (!window_state->IsNormalShowState())
return;
- if (fabs(event->details().velocity_y()) >
- kMinVertVelocityForWindowMinimize) {
- // Minimize/maximize.
- if (event->details().velocity_y() > 0 &&
- window_state->CanMinimize()) {
- window_state->Minimize();
- window_state->set_always_restores_to_restore_bounds(true);
- window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
- } else if (window_state->CanMaximize()) {
- window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
- window_state->Maximize();
- }
- } else if (window_state->CanSnap() &&
- fabs(event->details().velocity_x()) >
+ if (event->details().velocity_y() > kMinVertVelocityForWindowMinimize) {
+ SetWindowShowTypeFromGesture(target, wm::SHOW_TYPE_MINIMIZED);
+ } else if (event->details().velocity_y() <
+ -kMinVertVelocityForWindowMinimize) {
+ SetWindowShowTypeFromGesture(target, wm::SHOW_TYPE_MAXIMIZED);
+ } else if (event->details().velocity_x() >
kMinHorizVelocityForWindowSwipe) {
- // Snap left/right.
- ui::ScopedLayerAnimationSettings scoped_setter(
- target->layer()->GetAnimator());
- scoped_setter.SetPreemptionStrategy(
- ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
- internal::SnapSizer::SnapWindow(window_state,
- event->details().velocity_x() < 0 ?
- internal::SnapSizer::LEFT_EDGE : internal::SnapSizer::RIGHT_EDGE);
+ SetWindowShowTypeFromGesture(target, wm::SHOW_TYPE_RIGHT_SNAPPED);
+ } else if (event->details().velocity_x() <
+ -kMinHorizVelocityForWindowSwipe) {
+ SetWindowShowTypeFromGesture(target, wm::SHOW_TYPE_LEFT_SNAPPED);
}
- break;
+ event->StopPropagation();
+ return;
}
default:
return;
}
-
- event->StopPropagation();
}
aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
@@ -333,14 +304,11 @@ aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
const gfx::Vector2d& drag_offset,
aura::client::WindowMoveSource move_source) {
DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
- in_move_loop_ = true;
- move_cancelled_ = false;
aura::Window* root_window = source->GetRootWindow();
DCHECK(root_window);
gfx::Point drag_location;
if (move_source == aura::client::WINDOW_MOVE_SOURCE_TOUCH &&
aura::Env::GetInstance()->is_touch_down()) {
- in_gesture_drag_ = true;
bool has_point = ui::GestureRecognizer::Get()->
GetLastTouchPointForTarget(source, &drag_location);
DCHECK(has_point);
@@ -349,13 +317,15 @@ aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
aura::Window::ConvertPointToTarget(
root_window, source->parent(), &drag_location);
}
- // Set the cursor before calling CreateScopedWindowResizer(), as that will
+ // Set the cursor before calling AttemptToStartDrag(), as that will
// eventually call LockCursor() and prevent the cursor from changing.
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root_window);
if (cursor_client)
cursor_client->SetCursor(ui::kCursorPointer);
- CreateScopedWindowResizer(source, drag_location, HTCAPTION, move_source);
+ AttemptToStartDrag(source, drag_location, HTCAPTION, move_source);
+
+ in_move_loop_ = true;
bool destroyed = false;
destroyed_ = &destroyed;
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
@@ -366,40 +336,36 @@ aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
if (destroyed)
return aura::client::MOVE_CANCELED;
destroyed_ = NULL;
- in_gesture_drag_ = in_move_loop_ = false;
- return move_cancelled_ ? aura::client::MOVE_CANCELED :
+ in_move_loop_ = false;
+ return drag_reverted_ ? aura::client::MOVE_CANCELED :
aura::client::MOVE_SUCCESSFUL;
}
void ToplevelWindowEventHandler::EndMoveLoop() {
- if (!in_move_loop_)
- return;
-
- in_move_loop_ = false;
- CompleteDrag(DRAG_REVERT, 0);
- quit_closure_.Run();
+ if (in_move_loop_)
+ CompleteDrag(DRAG_REVERT, 0);
}
void ToplevelWindowEventHandler::OnDisplayConfigurationChanging() {
- if (in_move_loop_) {
- move_cancelled_ = true;
- EndMoveLoop();
- } else {
- CompleteDrag(DRAG_REVERT, 0);
- }
+ CompleteDrag(DRAG_REVERT, 0);
}
-void ToplevelWindowEventHandler::CreateScopedWindowResizer(
+void ToplevelWindowEventHandler::AttemptToStartDrag(
aura::Window* window,
const gfx::Point& point_in_parent,
int window_component,
aura::client::WindowMoveSource source) {
- window_resizer_.reset();
- WindowResizer* resizer =
- CreateWindowResizer(window, point_in_parent, window_component,
- source).release();
- if (resizer)
- window_resizer_.reset(new ScopedWindowResizer(this, resizer));
+ if (window_resizer_.get())
+ CompleteDrag(DRAG_REVERT, 0);
+ WindowResizer* resizer = CreateWindowResizer(window, point_in_parent,
+ window_component, source).release();
+ if (!resizer)
+ return;
+
+ window_resizer_.reset(new ScopedWindowResizer(this, resizer));
+
+ pre_drag_window_bounds_ = window->bounds();
+ in_gesture_drag_ = (source == aura::client::WINDOW_MOVE_SOURCE_TOUCH);
}
void ToplevelWindowEventHandler::CompleteDrag(DragCompletionStatus status,
@@ -411,6 +377,11 @@ void ToplevelWindowEventHandler::CompleteDrag(DragCompletionStatus status,
else
resizer->resizer()->RevertDrag();
}
+ drag_reverted_ = (status == DRAG_REVERT);
+
+ in_gesture_drag_ = false;
+ if (in_move_loop_)
+ quit_closure_.Run();
}
void ToplevelWindowEventHandler::HandleMousePressed(
@@ -431,8 +402,8 @@ void ToplevelWindowEventHandler::HandleMousePressed(
WindowResizer::GetBoundsChangeForWindowComponent(component)) {
gfx::Point location_in_parent(
ConvertPointToParent(target, event->location()));
- CreateScopedWindowResizer(target, location_in_parent, component,
- aura::client::WINDOW_MOVE_SOURCE_MOUSE);
+ AttemptToStartDrag(target, location_in_parent, component,
+ aura::client::WINDOW_MOVE_SOURCE_MOUSE);
} else {
window_resizer_.reset();
}
@@ -447,12 +418,8 @@ void ToplevelWindowEventHandler::HandleMouseReleased(
return;
CompleteDrag(event->type() == ui::ET_MOUSE_RELEASED ?
- DRAG_COMPLETE : DRAG_REVERT,
- event->flags());
- if (in_move_loop_) {
- quit_closure_.Run();
- in_move_loop_ = false;
- }
+ DRAG_COMPLETE : DRAG_REVERT,
+ event->flags());
// Completing the drag may result in hiding the window. If this happens
// return true so no other handlers/observers see the event. Otherwise
// they see the event on a hidden window.
@@ -522,13 +489,49 @@ void ToplevelWindowEventHandler::HandleMouseExited(
controller->HideShadow(target);
}
+void ToplevelWindowEventHandler::SetWindowShowTypeFromGesture(
+ aura::Window* window,
+ wm::WindowShowType new_show_type) {
+ wm::WindowState* window_state = ash::wm::GetWindowState(window);
+ switch (new_show_type) {
+ case wm::SHOW_TYPE_MINIMIZED:
+ if (window_state->CanMinimize()) {
+ window_state->Minimize();
+ window_state->set_always_restores_to_restore_bounds(true);
+ window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
+ }
+ break;
+ case wm::SHOW_TYPE_MAXIMIZED:
+ if (window_state->CanMaximize()) {
+ window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
+ window_state->Maximize();
+ }
+ break;
+ case wm::SHOW_TYPE_LEFT_SNAPPED:
+ if (window_state->CanSnap()) {
+ window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
+ internal::SnapSizer::SnapWindow(window_state,
+ internal::SnapSizer::LEFT_EDGE);
+ }
+ break;
+ case wm::SHOW_TYPE_RIGHT_SNAPPED:
+ if (window_state->CanSnap()) {
+ window_state->SetRestoreBoundsInParent(pre_drag_window_bounds_);
+ internal::SnapSizer::SnapWindow(window_state,
+ internal::SnapSizer::RIGHT_EDGE);
+ }
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
void ToplevelWindowEventHandler::ResizerWindowDestroyed() {
// We explicitly don't invoke RevertDrag() since that may do things to window.
// Instead we destroy the resizer.
window_resizer_.reset();
- // End the move loop. This does nothing if we're not in a move loop.
- EndMoveLoop();
+ CompleteDrag(DRAG_REVERT, 0);
}
} // namespace ash
diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h
index 98c9296..3d4c629 100644
--- a/ash/wm/toplevel_window_event_handler.h
+++ b/ash/wm/toplevel_window_event_handler.h
@@ -9,6 +9,7 @@
#include "ash/ash_export.h"
#include "ash/display/display_controller.h"
+#include "ash/wm/wm_types.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
@@ -62,10 +63,11 @@ class ASH_EXPORT ToplevelWindowEventHandler
DRAG_REVERT
};
- void CreateScopedWindowResizer(aura::Window* window,
- const gfx::Point& point_in_parent,
- int window_component,
- aura::client::WindowMoveSource source);
+ // Attempts to start a drag if one is not already in progress.
+ void AttemptToStartDrag(aura::Window* window,
+ const gfx::Point& point_in_parent,
+ int window_component,
+ aura::client::WindowMoveSource source);
// Finishes the drag.
void CompleteDrag(DragCompletionStatus status, int event_flags);
@@ -85,6 +87,11 @@ class ASH_EXPORT ToplevelWindowEventHandler
// Return value is returned by OnMouseEvent() above.
void HandleMouseExited(aura::Window* target, ui::LocatedEvent* event);
+ // Sets |window|'s show type to |new_show_type|. Called after the drag has
+ // been completed for fling gestures.
+ void SetWindowShowTypeFromGesture(aura::Window* window,
+ wm::WindowShowType new_show_type);
+
// Invoked from ScopedWindowResizer if the window is destroyed.
void ResizerWindowDestroyed();
@@ -94,9 +101,8 @@ class ASH_EXPORT ToplevelWindowEventHandler
// Are we running a nested message loop from RunMoveLoop().
bool in_move_loop_;
- // Was the move operation cancelled? Used only when the nested loop
- // is used to move a window.
- bool move_cancelled_;
+ // Whether the drag was reverted. Set by CompleteDrag().
+ bool drag_reverted_;
// Is a window move/resize in progress because of gesture events?
bool in_gesture_drag_;
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc
index 4038779..17761a0 100644
--- a/ash/wm/toplevel_window_event_handler_unittest.cc
+++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -19,6 +19,7 @@
#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/client/window_move_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/event_generator.h"
@@ -687,6 +688,33 @@ TEST_F(ToplevelWindowEventHandlerTest, MAYBE_MinimizeMaximizeCompletes) {
}
}
+// Verifies that starting a drag via
+// aura::client::WindowMoveClient::RunMoveLoop() reverts the in progress drag
+// (if any).
+TEST_F(ToplevelWindowEventHandlerTest, RunMoveLoopRevertsInProgressDrag) {
+ scoped_ptr<aura::Window> window1(CreateWindow(HTCAPTION));
+ gfx::Rect window1_initial_bounds = window1->bounds();
+ scoped_ptr<aura::Window> window2(CreateWindow(HTCAPTION));
+
+ aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
+ window1.get());
+ window1->Focus();
+ generator.PressLeftButton();
+ generator.MoveMouseBy(10, 11);
+ RunAllPendingInMessageLoop();
+ EXPECT_NE(window1_initial_bounds.ToString(), window1->bounds().ToString());
+
+ aura::client::WindowMoveClient* move_client =
+ aura::client::GetWindowMoveClient(window2->parent());
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&aura::client::WindowMoveClient::EndMoveLoop,
+ base::Unretained(move_client)));
+ move_client->RunMoveLoop(window2.get(), gfx::Vector2d(),
+ aura::client::WINDOW_MOVE_SOURCE_MOUSE);
+ EXPECT_EQ(window1_initial_bounds.ToString(), window1->bounds().ToString());
+}
+
// Showing the resize shadows when the mouse is over the window edges is tested
// in resize_shadow_and_cursor_test.cc