summaryrefslogtreecommitdiffstats
path: root/ash/drag_drop
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-26 00:55:17 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-26 00:55:17 +0000
commit3f94b49b9a6422e91b4c1087d389bcff9fe9f0b5 (patch)
treec03c94e0bd83fffccc4806315faa081be8173b0b /ash/drag_drop
parentbb54e63c4ecd10ea4379386cc2bdc540f76a6907 (diff)
downloadchromium_src-3f94b49b9a6422e91b4c1087d389bcff9fe9f0b5.zip
chromium_src-3f94b49b9a6422e91b4c1087d389bcff9fe9f0b5.tar.gz
chromium_src-3f94b49b9a6422e91b4c1087d389bcff9fe9f0b5.tar.bz2
Cancel drag upon screen lock.
I believe cancel upon capture lost is necessary regardless. BUG=175486 TEST=covered by tests, manually on lock screen. Review URL: https://codereview.chromium.org/13041002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190534 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/drag_drop')
-rw-r--r--ash/drag_drop/drag_drop_controller.cc63
-rw-r--r--ash/drag_drop/drag_drop_controller.h2
-rw-r--r--ash/drag_drop/drag_drop_controller_unittest.cc59
-rw-r--r--ash/drag_drop/drag_drop_tracker.cc17
-rw-r--r--ash/drag_drop/drag_drop_tracker.h4
-rw-r--r--ash/drag_drop/drag_drop_tracker_unittest.cc6
6 files changed, 140 insertions, 11 deletions
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index c13e087..1500dae 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -16,11 +16,14 @@
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_delegate.h"
#include "ui/base/animation/linear_animation.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_utils.h"
+#include "ui/base/hit_test.h"
+#include "ui/gfx/path.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/rect_conversions.h"
@@ -77,6 +80,61 @@ void DispatchGestureEndToWindow(aura::Window* window) {
}
} // namespace
+class DragDropTrackerDelegate : public aura::WindowDelegate {
+ public:
+ explicit DragDropTrackerDelegate(DragDropController* controller)
+ : drag_drop_controller_(controller) {}
+ virtual ~DragDropTrackerDelegate() {}
+
+ // Overridden from WindowDelegate:
+ virtual gfx::Size GetMinimumSize() const OVERRIDE {
+ return gfx::Size();
+ }
+
+ virtual gfx::Size GetMaximumSize() const OVERRIDE {
+ return gfx::Size();
+ }
+
+ virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE {}
+ virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
+ return gfx::kNullCursor;
+ }
+ virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
+ return HTCAPTION;
+ }
+ virtual bool ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) OVERRIDE {
+ return true;
+ }
+ virtual bool CanFocus() OVERRIDE { return true; }
+ virtual void OnCaptureLost() OVERRIDE {
+ if (drag_drop_controller_->IsDragDropInProgress())
+ drag_drop_controller_->DragCancel();
+ }
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+ }
+ virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {}
+ virtual void OnWindowDestroying() OVERRIDE {}
+ virtual void OnWindowDestroyed() OVERRIDE {}
+ virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {}
+ virtual bool HasHitTestMask() const OVERRIDE {
+ return true;
+ }
+ virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {
+ DCHECK(mask->isEmpty());
+ }
+ virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE {
+ return scoped_refptr<ui::Texture>();
+ }
+
+ private:
+ DragDropController* drag_drop_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(DragDropTrackerDelegate);
+};
+
////////////////////////////////////////////////////////////////////////////////
// DragDropController, public:
@@ -87,6 +145,8 @@ DragDropController::DragDropController()
drag_window_(NULL),
drag_source_window_(NULL),
should_block_during_drag_drop_(true),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ drag_drop_window_delegate_(new DragDropTrackerDelegate(this))),
current_drag_event_source_(ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE),
weak_factory_(this) {
Shell::GetInstance()->AddPreTargetHandler(this);
@@ -118,7 +178,8 @@ int DragDropController::StartDragAndDrop(
return 0;
current_drag_event_source_ = source;
- DragDropTracker* tracker = new DragDropTracker(root_window);
+ DragDropTracker* tracker =
+ new DragDropTracker(root_window, drag_drop_window_delegate_.get());
if (source == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH) {
// We need to transfer the current gesture sequence and the GR's touch event
// queue to the |drag_drop_tracker_|'s capture window so that when it takes
diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h
index 8c4e6bb..a23ed91 100644
--- a/ash/drag_drop/drag_drop_controller.h
+++ b/ash/drag_drop/drag_drop_controller.h
@@ -34,6 +34,7 @@ class DragDropControllerTest;
namespace internal {
class DragDropTracker;
+class DragDropTrackerDelegate;
class DragImageView;
class ASH_EXPORT DragDropController
@@ -127,6 +128,7 @@ class ASH_EXPORT DragDropController
base::Closure quit_closure_;
scoped_ptr<ash::internal::DragDropTracker> drag_drop_tracker_;
+ scoped_ptr<DragDropTrackerDelegate> drag_drop_window_delegate_;
ui::DragDropTypes::DragEventSource current_drag_event_source_;
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 8599535..2b0091f 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -4,12 +4,14 @@
#include "ash/drag_drop/drag_drop_controller.h"
+#include "ash/drag_drop/drag_drop_tracker.h"
#include "ash/drag_drop/drag_image_view.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/utf_string_conversions.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/event_generator.h"
#include "ui/base/animation/linear_animation.h"
@@ -329,6 +331,10 @@ class DragDropControllerTest : public AshTestBase {
NULL;
}
+ internal::DragDropTracker* drag_drop_tracker() {
+ return drag_drop_controller_->drag_drop_tracker_.get();
+ }
+
void CompleteCancelAnimation() {
CompletableLinearAnimation* animation =
static_cast<CompletableLinearAnimation*>(
@@ -754,8 +760,10 @@ TEST_F(DragDropControllerTest, SyntheticEventsDuringDragDrop) {
// TODO(win_aura) http://crbug.com/154081
#if defined(OS_WIN)
#define MAYBE_PressingEscapeCancelsDragDrop DISABLED_PressingEscapeCancelsDragDrop
+#define MAYBE_CaptureLostCancelsDragDrop DISABLED_CaptureLostCancelsDragDrop
#else
#define MAYBE_PressingEscapeCancelsDragDrop PressingEscapeCancelsDragDrop
+#define MAYBE_CaptureLostCancelsDragDrop CaptureLostCancelsDragDrop
#endif
TEST_F(DragDropControllerTest, MAYBE_PressingEscapeCancelsDragDrop) {
scoped_ptr<views::Widget> widget(CreateNewWidget());
@@ -799,6 +807,57 @@ TEST_F(DragDropControllerTest, MAYBE_PressingEscapeCancelsDragDrop) {
EXPECT_TRUE(drag_view->drag_done_received_);
}
+TEST_F(DragDropControllerTest, MAYBE_CaptureLostCancelsDragDrop) {
+ scoped_ptr<views::Widget> widget(CreateNewWidget());
+ DragTestView* drag_view = new DragTestView;
+ AddViewToWidgetAndResize(widget.get(), drag_view);
+ ui::OSExchangeData data;
+ data.SetString(UTF8ToUTF16("I am being dragged"));
+ aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
+ widget->GetNativeView());
+ generator.PressLeftButton();
+
+ int num_drags = 17;
+ for (int i = 0; i < num_drags; ++i) {
+ // Because we are not doing a blocking drag and drop, the original
+ // OSDragExchangeData object is lost as soon as we return from the drag
+ // initiation in DragDropController::StartDragAndDrop(). Hence we set the
+ // drag_data_ to a fake drag data object that we created.
+ if (i > 0)
+ UpdateDragData(&data);
+ generator.MoveMouseBy(0, 1);
+
+ // Execute any scheduled draws to process deferred mouse events.
+ RunAllPendingInMessageLoop();
+ }
+ // Make sure the capture window won't handle mouse events.
+ aura::Window* capture_window = drag_drop_tracker()->capture_window();
+ ASSERT_TRUE(!!capture_window);
+ EXPECT_EQ("0x0", capture_window->bounds().size().ToString());
+ EXPECT_EQ(NULL,
+ capture_window->GetEventHandlerForPoint(gfx::Point()));
+ EXPECT_EQ(NULL,
+ capture_window->GetTopWindowContainingPoint(gfx::Point()));
+
+ aura::client::GetCaptureClient(widget->GetNativeView()->GetRootWindow())->
+ SetCapture(NULL);
+
+ EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
+ EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
+ drag_drop_controller_->num_drag_updates_);
+ EXPECT_FALSE(drag_drop_controller_->drop_received_);
+ EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
+ EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
+ drag_drop_controller_->drag_string_);
+
+ EXPECT_EQ(1, drag_view->num_drag_enters_);
+ EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
+ drag_view->num_drag_updates_);
+ EXPECT_EQ(0, drag_view->num_drops_);
+ EXPECT_EQ(1, drag_view->num_drag_exits_);
+ EXPECT_TRUE(drag_view->drag_done_received_);
+}
+
TEST_F(DragDropControllerTest, TouchDragDropInMultipleWindows) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableTouchDragDrop);
diff --git a/ash/drag_drop/drag_drop_tracker.cc b/ash/drag_drop/drag_drop_tracker.cc
index 269e2edb..9de4645 100644
--- a/ash/drag_drop/drag_drop_tracker.cc
+++ b/ash/drag_drop/drag_drop_tracker.cc
@@ -11,25 +11,28 @@
#include "ui/base/events/event.h"
#include "ui/gfx/screen.h"
+namespace ash {
+namespace internal {
+
namespace {
// Creates a window for capturing drag events.
-aura::Window* CreateCaptureWindow(aura::RootWindow* context_root) {
- aura::Window* window = new aura::Window(NULL);
+aura::Window* CreateCaptureWindow(aura::RootWindow* context_root,
+ aura::WindowDelegate* delegate) {
+ aura::Window* window = new aura::Window(delegate);
window->SetType(aura::client::WINDOW_TYPE_NORMAL);
window->Init(ui::LAYER_NOT_DRAWN);
window->SetDefaultParentByRootWindow(context_root, gfx::Rect());
window->Show();
+ DCHECK(window->bounds().size().IsEmpty());
return window;
}
} // namespace
-namespace ash {
-namespace internal {
-
-DragDropTracker::DragDropTracker(aura::RootWindow* context_root)
- : capture_window_(CreateCaptureWindow(context_root)) {
+DragDropTracker::DragDropTracker(aura::RootWindow* context_root,
+ aura::WindowDelegate* delegate)
+ : capture_window_(CreateCaptureWindow(context_root, delegate)) {
}
DragDropTracker::~DragDropTracker() {
diff --git a/ash/drag_drop/drag_drop_tracker.h b/ash/drag_drop/drag_drop_tracker.h
index 22cf630..d7212ef 100644
--- a/ash/drag_drop/drag_drop_tracker.h
+++ b/ash/drag_drop/drag_drop_tracker.h
@@ -13,6 +13,7 @@
namespace aura {
class RootWindow;
class Window;
+class WindowDelegate;
}
namespace ash {
@@ -25,7 +26,8 @@ namespace internal {
// is supported for now.
class ASH_EXPORT DragDropTracker {
public:
- explicit DragDropTracker(aura::RootWindow* context_root);
+ DragDropTracker(aura::RootWindow* context_root,
+ aura::WindowDelegate* delegate);
~DragDropTracker();
aura::Window* capture_window() { return capture_window_.get(); }
diff --git a/ash/drag_drop/drag_drop_tracker_unittest.cc b/ash/drag_drop/drag_drop_tracker_unittest.cc
index 7113c22..acb87a4 100644
--- a/ash/drag_drop/drag_drop_tracker_unittest.cc
+++ b/ash/drag_drop/drag_drop_tracker_unittest.cc
@@ -32,7 +32,8 @@ class DragDropTrackerTest : public test::AshTestBase {
static aura::Window* GetTarget(const gfx::Point& location) {
scoped_ptr<internal::DragDropTracker> tracker(
- new internal::DragDropTracker(Shell::GetPrimaryRootWindow()));
+ new internal::DragDropTracker(Shell::GetPrimaryRootWindow(),
+ NULL));
ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
location,
location,
@@ -44,7 +45,8 @@ class DragDropTrackerTest : public test::AshTestBase {
static ui::LocatedEvent* ConvertEvent(aura::Window* target,
const ui::MouseEvent& event) {
scoped_ptr<internal::DragDropTracker> tracker(
- new internal::DragDropTracker(Shell::GetPrimaryRootWindow()));
+ new internal::DragDropTracker(Shell::GetPrimaryRootWindow(),
+ NULL));
ui::LocatedEvent* converted = tracker->ConvertEvent(target, event);
return converted;
}