[exo] Relax image drag/drop conditions for touch tab dragging
Tab drag/drop does not have drag images associated with it.
BUG=1140736
R=oshima@chromium.org
Change-Id: If613d4e4edc9a349d65cdf049d2d4972cfbabd56
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3035903
Commit-Queue: Antonio Gomes <tonikitoo@igalia.com>
Reviewed-by: Mitsuru Oshima (catching up) <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#903876}
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 9aabdee..ed44b65 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -172,10 +172,13 @@
return DragOperation::kNone;
const ui::OSExchangeDataProvider* provider = &data->provider();
- // We do not support touch drag/drop without a drag image.
+ // We do not support touch drag/drop without a drag image, unless it is a tab
+ // drag/drop.
if (source == ui::mojom::DragEventSource::kTouch &&
- provider->GetDragImage().size().IsEmpty())
+ provider->GetDragImage().size().IsEmpty() &&
+ !toplevel_window_drag_delegate_) {
return DragOperation::kNone;
+ }
operation_ = DragOperation::kNone;
current_drag_event_source_ = source;
@@ -383,16 +386,20 @@
if (current_drag_event_source_ != ui::mojom::DragEventSource::kTouch)
return;
- // Apply kTouchDragImageVerticalOffset to the location.
+ // Apply kTouchDragImageVerticalOffset to the location, if it is not a tab
+ // drag/drop.
ui::GestureEvent touch_offset_event(*event,
static_cast<aura::Window*>(nullptr),
static_cast<aura::Window*>(nullptr));
- gfx::PointF touch_offset_location = touch_offset_event.location_f();
- gfx::PointF touch_offset_root_location = touch_offset_event.root_location_f();
- touch_offset_location.Offset(0, kTouchDragImageVerticalOffset);
- touch_offset_root_location.Offset(0, kTouchDragImageVerticalOffset);
- touch_offset_event.set_location_f(touch_offset_location);
- touch_offset_event.set_root_location_f(touch_offset_root_location);
+ if (!toplevel_window_drag_delegate_) {
+ gfx::PointF touch_offset_location = touch_offset_event.location_f();
+ gfx::PointF touch_offset_root_location =
+ touch_offset_event.root_location_f();
+ touch_offset_location.Offset(0, kTouchDragImageVerticalOffset);
+ touch_offset_root_location.Offset(0, kTouchDragImageVerticalOffset);
+ touch_offset_event.set_location_f(touch_offset_location);
+ touch_offset_event.set_root_location_f(touch_offset_root_location);
+ }
aura::Window* translated_target =
drag_drop_tracker_->GetTarget(touch_offset_event);
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index c871fc0..060d3b7e4 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -1503,6 +1503,29 @@
}
}
+TEST_F(DragDropControllerTest, ToplevelWindowDragDelegateWithTouch) {
+ std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
+ aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), -1,
+ gfx::Rect(0, 0, 100, 100)));
+
+ // Emulate a full drag and drop flow and verify that toplevel window drag
+ // delegate gets notified about the events as expected.
+ TestToplevelWindowDragDelegate delegate;
+ drag_drop_controller_->set_toplevel_window_drag_delegate(&delegate);
+
+ auto data(std::make_unique<ui::OSExchangeData>());
+ drag_drop_controller_->StartDragAndDrop(
+ std::move(data), window->GetRootWindow(), window.get(), gfx::Point(5, 5),
+ ui::DragDropTypes::DRAG_MOVE, ui::mojom::DragEventSource::kTouch);
+
+ EXPECT_EQ(TestToplevelWindowDragDelegate::State::kDragStartedInvoked,
+ delegate.state());
+ EXPECT_EQ(ui::mojom::DragEventSource::kTouch, delegate.source());
+ EXPECT_TRUE(delegate.current_location().has_value());
+ EXPECT_EQ(gfx::PointF(5, 5), *delegate.current_location());
+ EXPECT_EQ(0, delegate.events_forwarded());
+}
+
namespace {
class MockDataTransferPolicyController