diff options
author | oshima <oshima@chromium.org> | 2016-03-15 10:37:00 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-15 17:39:15 +0000 |
commit | 3d990e41305fb59c8660461fde7a2d459095e60f (patch) | |
tree | 4bdd85da92a3a6bd8c3e1d871adc6475f46b85f0 /ash | |
parent | e67cbae553e592e7683aefc74c775f1e4a99296a (diff) | |
download | chromium_src-3d990e41305fb59c8660461fde7a2d459095e60f.zip chromium_src-3d990e41305fb59c8660461fde7a2d459095e60f.tar.gz chromium_src-3d990e41305fb59c8660461fde7a2d459095e60f.tar.bz2 |
Check if the resizer has been deleted during drag start.
BUG=579226
TEST=ToplevelWindowEventHandler.CancelWhileDragStart
Review URL: https://codereview.chromium.org/1800793003
Cr-Commit-Position: refs/heads/master@{#381243}
Diffstat (limited to 'ash')
-rw-r--r-- | ash/wm/dock/docked_window_resizer.cc | 15 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_resizer.h | 4 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler_unittest.cc | 35 |
3 files changed, 48 insertions, 6 deletions
diff --git a/ash/wm/dock/docked_window_resizer.cc b/ash/wm/dock/docked_window_resizer.cc index 9e4eb2d..624dc72 100644 --- a/ash/wm/dock/docked_window_resizer.cc +++ b/ash/wm/dock/docked_window_resizer.cc @@ -64,17 +64,21 @@ DockedWindowResizer::Create(WindowResizer* next_window_resizer, void DockedWindowResizer::Drag(const gfx::Point& location, int event_flags) { last_location_ = location; ::wm::ConvertPointToScreen(GetTarget()->parent(), &last_location_); + base::WeakPtr<DockedWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); + if (!did_move_or_resize_) { did_move_or_resize_ = true; - StartedDragging(); + StartedDragging(resizer); } + if (!resizer) + return; + gfx::Point offset; gfx::Rect bounds(CalculateBoundsForDrag(location)); MaybeSnapToEdge(bounds, &offset); gfx::Point modified_location(location); modified_location.Offset(offset.x(), offset.y()); - base::WeakPtr<DockedWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); next_window_resizer_->Drag(modified_location, event_flags); if (!resizer) return; @@ -181,7 +185,8 @@ void DockedWindowResizer::MaybeSnapToEdge(const gfx::Rect& bounds, } } -void DockedWindowResizer::StartedDragging() { +void DockedWindowResizer::StartedDragging( + base::WeakPtr<DockedWindowResizer>& resizer) { // During resizing the window width is preserved by DockedwindowLayoutManager. if (is_docked_ && (details().bounds_change & WindowResizer::kBoundsChange_Resizes)) { @@ -192,6 +197,8 @@ void DockedWindowResizer::StartedDragging() { // At this point we are not yet animating the window as it may not be // inside the docked area. dock_layout_->StartDragging(GetTarget()); + if (!resizer) + return; // Reparent workspace windows during the drag to elevate them above workspace. // Other windows for which the DockedWindowResizer is instantiated include // panels and windows that are already docked. Those do not need reparenting. @@ -205,6 +212,8 @@ void DockedWindowResizer::StartedDragging() { wm::ReparentChildWithTransientChildren(GetTarget(), GetTarget()->parent(), docked_container); + if (!resizer) + return; } if (is_docked_) dock_layout_->DockDraggedWindow(GetTarget()); diff --git a/ash/wm/dock/docked_window_resizer.h b/ash/wm/dock/docked_window_resizer.h index 4d5dbde..ad0e02b 100644 --- a/ash/wm/dock/docked_window_resizer.h +++ b/ash/wm/dock/docked_window_resizer.h @@ -54,7 +54,9 @@ class ASH_EXPORT DockedWindowResizer : public WindowResizer { // Tracks the window's initial position and attachment at the start of a drag // and informs the DockLayoutManager that a drag has started if necessary. - void StartedDragging(); + // |resizer| can be used to check if the resizer has been deleted during + // StartedDragging. + void StartedDragging(base::WeakPtr<DockedWindowResizer>& resizer); // Informs the DockLayoutManager that the drag is complete if it was informed // of the drag start. |move_result| specifies if the drag was completed or diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index 55129eb..165c92c 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc @@ -17,6 +17,7 @@ #include "base/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/capture_client.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window_event_dispatcher.h" @@ -67,8 +68,8 @@ class ToplevelWindowEventHandlerTest : public AshTestBase { w1->SetType(ui::wm::WINDOW_TYPE_NORMAL); w1->set_id(1); w1->Init(ui::LAYER_TEXTURED); - aura::Window* parent = Shell::GetContainer( - Shell::GetPrimaryRootWindow(), kShellWindowId_AlwaysOnTopContainer); + aura::Window* parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(), + kShellWindowId_DefaultContainer); parent->AddChild(w1); w1->SetBounds(gfx::Rect(0, 0, 100, 100)); w1->Show(); @@ -109,6 +110,36 @@ TEST_F(ToplevelWindowEventHandlerTest, Caption) { EXPECT_EQ(size.ToString(), w1->bounds().size().ToString()); } +namespace { + +class CancelDragObserver : public aura::WindowObserver { + public: + CancelDragObserver() {} + ~CancelDragObserver() override {} + + void OnWindowHierarchyChanging(const HierarchyChangeParams& params) override { + aura::client::CaptureClient* client = + aura::client::GetCaptureClient(params.target->GetRootWindow()); + client->SetCapture(nullptr); + } + + private: + DISALLOW_COPY_AND_ASSIGN(CancelDragObserver); +}; + +} // namespace + +// Cancelling drag while starting window drag should not crash. +TEST_F(ToplevelWindowEventHandlerTest, CancelWhileDragStart) { + scoped_ptr<aura::Window> w1(CreateWindow(HTCAPTION)); + CancelDragObserver observer; + w1->AddObserver(&observer); + gfx::Point origin = w1->bounds().origin(); + DragFromCenterBy(w1.get(), 100, 100); + EXPECT_EQ(origin, w1->bounds().origin()); + w1->RemoveObserver(&observer); +} + TEST_F(ToplevelWindowEventHandlerTest, BottomRight) { scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOMRIGHT)); gfx::Point position = w1->bounds().origin(); |