Commit 4e4f3ec7 authored by Alexander Dunaev's avatar Alexander Dunaev Committed by Commit Bot

[ozone] Added propagation of drop event modifiers from the platform.

The drag and drop client is supposed to set event flags according to the
current state of modifier keys (i.e., Ctrl, Shift, and Alt).  It was
not implemented in Ozone, but migration of Linux/X11 to Ozone requires
that.  This CL adds the methods that allow the DDDClientOzone to get
these flags from the platform.

The issue has been found by a test that broke at the attempt to use
DesktopDragDropClientOzone in place of DesktopDragDropClientAuraX11.

Bug: 990756
Change-Id: I2657383011a1bf9d716bb5bfa90dbcf010bba48f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2279975
Commit-Queue: Alexander Dunaev <adunaev@igalia.com>
Reviewed-by: default avatarNick Yamane <nickdiego@igalia.com>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Auto-Submit: Alexander Dunaev <adunaev@igalia.com>
Cr-Commit-Position: refs/heads/master@{#785872}
parent 0c10a671
......@@ -76,11 +76,13 @@ class MockDropHandler : public WmDropHandler {
MockDropHandler() = default;
~MockDropHandler() override = default;
MOCK_METHOD3(OnDragEnter,
MOCK_METHOD4(OnDragEnter,
void(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation));
MOCK_METHOD2(OnDragMotion, int(const gfx::PointF& point, int operation));
int operation,
int modifiers));
MOCK_METHOD3(OnDragMotion,
int(const gfx::PointF& point, int operation, int modifiers));
MOCK_METHOD0(MockOnDragDrop, void());
MOCK_METHOD0(OnDragLeave, void());
......@@ -91,7 +93,8 @@ class MockDropHandler : public WmDropHandler {
OSExchangeData* dropped_data() { return dropped_data_.get(); }
protected:
void OnDragDrop(std::unique_ptr<OSExchangeData> data) override {
void OnDragDrop(std::unique_ptr<OSExchangeData> data,
int modifiers) override {
dropped_data_ = std::move(data);
MockOnDragDrop();
on_drop_closure_.Run();
......@@ -279,7 +282,7 @@ TEST_P(WaylandDataDragControllerTest, DropSeveralMimeTypes) {
kMimeTypeURIList,
ToClipboardData(std::string("file:///home/user/file\r\n")));
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _)).Times(1);
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _, _)).Times(1);
gfx::Point entered_point(10, 10);
data_device_manager_->data_device()->OnEnter(
1002, surface_->resource(), wl_fixed_from_int(entered_point.x()),
......@@ -326,7 +329,7 @@ TEST_P(WaylandDataDragControllerTest, ValidateDroppedUriList) {
auto* data_offer = data_device_manager_->data_device()->OnDataOffer();
data_offer->OnOffer(kMimeTypeURIList, ToClipboardData(kCase.content));
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _)).Times(1);
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _, _)).Times(1);
gfx::Point entered_point(10, 10);
data_device_manager_->data_device()->OnEnter(
1002, surface_->resource(), wl_fixed_from_int(entered_point.x()),
......@@ -381,7 +384,7 @@ TEST_P(WaylandDataDragControllerTest, ValidateDroppedXMozUrl) {
data_offer->OnOffer(kMimeTypeMozillaURL,
ToClipboardData(base::UTF8ToUTF16(kCase.content)));
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _)).Times(1);
EXPECT_CALL(*drop_handler_, OnDragEnter(_, _, _, _)).Times(1);
gfx::Point entered_point(10, 10);
data_device_manager_->data_device()->OnEnter(
1002, surface_->resource(), wl_fixed_from_int(entered_point.x()),
......
......@@ -254,9 +254,11 @@ void WaylandToplevelWindow::OnDragEnter(const gfx::PointF& point,
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
// TODO(crbug.com/1102857): get the real event modifier here.
drop_handler->OnDragEnter(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), std::move(data),
operation);
operation,
/*modifiers=*/0);
}
int WaylandToplevelWindow::OnDragMotion(const gfx::PointF& point,
......@@ -267,15 +269,18 @@ int WaylandToplevelWindow::OnDragMotion(const gfx::PointF& point,
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
// TODO(crbug.com/1102857): get the real event modifier here.
return drop_handler->OnDragMotion(
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), operation);
gfx::ScalePoint(point, buffer_scale(), buffer_scale()), operation,
/*modifiers=*/0);
}
void WaylandToplevelWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragDrop(std::move(data));
// TODO(crbug.com/1102857): get the real event modifier here.
drop_handler->OnDragDrop(std::move(data), /*modifiers=*/0);
}
void WaylandToplevelWindow::OnDragLeave() {
......
......@@ -20,23 +20,31 @@ class OSExchangeData;
class WM_PLATFORM_EXPORT WmDropHandler {
public:
// Notifies that dragging is entered to the window. |point| is in the
// coordinate space of the PlatformWindow.
// Notifies that drag has entered the window.
// |point| is in the coordinate space of the PlatformWindow.
// |operation| contains bitmask of ui::DragDropTypes suggested by the source.
// |modifiers| contains bitmask of ui::EventFlags that accompany the event.
virtual void OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
int operation) = 0;
// Notifies that dragging is moved. |widget_out| will be set with the
// widget located at |point|. |point| is in the coordinate space of the
// PlatformWindow. It returns the operation selected by client and the
// returned value should be from ui::DragDropTypes.
virtual int OnDragMotion(const gfx::PointF& point, int operation) = 0;
int operation,
int modifiers) = 0;
// Notifies that drag location has changed.
// |point| is in the coordinate space of the PlatformWindow.
// |operation| contains bitmask of ui::DragDropTypes suggested by the source.
// |modifiers| contains bitmask of ui::EventFlags that accompany the event.
// Returns one of ui::DragDropTypes values selected by the client.
virtual int OnDragMotion(const gfx::PointF& point,
int operation,
int modifiers) = 0;
// Notifies that dragged data is dropped. When it doesn't deliver
// the dragged data on OnDragEnter, it should put it to |data|. The location
// of the drop is the location of the latest DragEnter/DragMotion. If
// OSExchangeData is provided on OnDragEnter, the |data| should be same as it.
virtual void OnDragDrop(std::unique_ptr<ui::OSExchangeData> data) = 0;
// |modifiers| contains bitmask of ui::EventFlags that accompany the event.
virtual void OnDragDrop(std::unique_ptr<ui::OSExchangeData> data,
int modifiers) = 0;
// Notifies that dragging is left.
virtual void OnDragLeave() = 0;
......
......@@ -117,6 +117,14 @@ bool CoalesceEventsIfNeeded(x11::Event* const x11_event,
return false;
}
#if defined(USE_OZONE)
int GetKeyModifiers(const XDragDropClient* client) {
if (!client)
return ui::XGetMaskAsEventFlags();
return client->current_modifier_state();
}
#endif // defined(USE_OZONE)
} // namespace
X11Window::X11Window(PlatformWindowDelegate* platform_window_delegate)
......@@ -828,22 +836,24 @@ int X11Window::UpdateDrag(const gfx::Point& screen_point) {
WmDropHandler* drop_handler = GetWmDropHandler(*this);
if (!drop_handler)
return DragDropTypes::DRAG_NONE;
DCHECK(drag_drop_client_);
auto* target_current_context = drag_drop_client_->target_current_context();
DCHECK(target_current_context);
if (!notified_enter_) {
DCHECK(drag_drop_client_);
auto* target_current_context = drag_drop_client_->target_current_context();
DCHECK(target_current_context);
drop_handler->OnDragEnter(
gfx::PointF(screen_point),
std::make_unique<ui::OSExchangeData>(
std::make_unique<ui::XOSExchangeDataProvider>(
drag_drop_client_->xwindow(),
target_current_context->fetched_targets())),
ui::DragDropTypes::DRAG_COPY);
ui::DragDropTypes::DRAG_COPY,
GetKeyModifiers(target_current_context->source_client()));
notified_enter_ = true;
}
drag_operation_ = drop_handler->OnDragMotion(gfx::PointF(screen_point),
ui::DragDropTypes::DRAG_COPY);
drag_operation_ = drop_handler->OnDragMotion(
gfx::PointF(screen_point), ui::DragDropTypes::DRAG_COPY,
GetKeyModifiers(target_current_context->source_client()));
return drag_operation_;
}
......@@ -878,7 +888,10 @@ int X11Window::PerformDrop() {
// The drop data has been supplied on entering the window. The drop handler
// should have it since then.
drop_handler->OnDragDrop({});
auto* target_current_context = drag_drop_client_->target_current_context();
DCHECK(target_current_context);
drop_handler->OnDragDrop(
{}, GetKeyModifiers(target_current_context->source_client()));
notified_enter_ = false;
return drag_operation_;
}
......
......@@ -178,7 +178,7 @@ void DesktopDragDropClientOzone::DragCancel() {
}
bool DesktopDragDropClientOzone::IsDragDropInProgress() {
return bool(drag_context_) && bool(drag_context_->quit_closure);
return drag_context_ && !drag_context_->quit_closure.is_null();
}
void DesktopDragDropClientOzone::AddObserver(
......@@ -194,7 +194,8 @@ void DesktopDragDropClientOzone::RemoveObserver(
void DesktopDragDropClientOzone::OnDragEnter(
const gfx::PointF& point,
std::unique_ptr<ui::OSExchangeData> data,
int operation) {
int operation,
int modifiers) {
last_drag_point_ = point;
drag_operation_ = operation;
......@@ -204,11 +205,12 @@ void DesktopDragDropClientOzone::OnDragEnter(
return;
data_to_drop_ = std::move(data);
UpdateTargetAndCreateDropEvent(point);
UpdateTargetAndCreateDropEvent(point, modifiers);
}
int DesktopDragDropClientOzone::OnDragMotion(const gfx::PointF& point,
int operation) {
int operation,
int modifiers) {
last_drag_point_ = point;
drag_operation_ = operation;
......@@ -219,14 +221,15 @@ int DesktopDragDropClientOzone::OnDragMotion(const gfx::PointF& point,
// Ask the delegate what operation it would accept for the current data.
int client_operation = ui::DragDropTypes::DRAG_NONE;
std::unique_ptr<ui::DropTargetEvent> event =
UpdateTargetAndCreateDropEvent(point);
UpdateTargetAndCreateDropEvent(point, modifiers);
if (drag_drop_delegate_ && event)
client_operation = drag_drop_delegate_->OnDragUpdated(*event);
return client_operation;
}
void DesktopDragDropClientOzone::OnDragDrop(
std::unique_ptr<ui::OSExchangeData> data) {
std::unique_ptr<ui::OSExchangeData> data,
int modifiers) {
// If we didn't have |data_to_drop_|, then |drag_drop_delegate_| had never
// been updated, and now it needs to receive deferred enter and update events
// before handling the actual drop.
......@@ -239,7 +242,7 @@ void DesktopDragDropClientOzone::OnDragDrop(
data_to_drop_ = std::move(data);
// This will call the delegate's OnDragEntered if needed.
auto event = UpdateTargetAndCreateDropEvent(last_drag_point_);
auto event = UpdateTargetAndCreateDropEvent(last_drag_point_, modifiers);
if (drag_drop_delegate_ && event) {
if (posponed_enter_and_update) {
// TODO(https://crbug.com/1014860): deal with drop refusals.
......@@ -328,7 +331,8 @@ void DesktopDragDropClientOzone::QuitRunLoop() {
std::unique_ptr<ui::DropTargetEvent>
DesktopDragDropClientOzone::UpdateTargetAndCreateDropEvent(
const gfx::PointF& location) {
const gfx::PointF& location,
int modifiers) {
const gfx::Point point(location.x(), location.y());
aura::Window* window = GetTargetWindow(root_window_, point);
if (!window) {
......@@ -356,6 +360,7 @@ DesktopDragDropClientOzone::UpdateTargetAndCreateDropEvent(
auto event = std::make_unique<ui::DropTargetEvent>(
*data_to_drop_, target_location, gfx::PointF(root_location),
drag_operation_);
event->set_flags(modifiers);
if (delegate_has_changed)
drag_drop_delegate_->OnDragEntered(*event);
return event;
......
......@@ -89,9 +89,13 @@ class VIEWS_EXPORT DesktopDragDropClientOzone
// ui::WmDropHandler
void OnDragEnter(const gfx::PointF& point,
std::unique_ptr<ui::OSExchangeData> data,
int operation) override;
int OnDragMotion(const gfx::PointF& point, int operation) override;
void OnDragDrop(std::unique_ptr<ui::OSExchangeData> data) override;
int operation,
int modifiers) override;
int OnDragMotion(const gfx::PointF& point,
int operation,
int modifiers) override;
void OnDragDrop(std::unique_ptr<ui::OSExchangeData> data,
int modifiers) override;
void OnDragLeave() override;
// aura::WindowObserver
......@@ -111,7 +115,8 @@ class VIEWS_EXPORT DesktopDragDropClientOzone
// is ready to accept OnDragUpdated or OnPerformDrop. Returns nullptr if
// drop is not possible.
std::unique_ptr<ui::DropTargetEvent> UpdateTargetAndCreateDropEvent(
const gfx::PointF& point);
const gfx::PointF& point,
int modifiers);
// Updates |drag_drop_delegate_| along with |window|.
void UpdateDragDropDelegate(aura::Window* window);
......
......@@ -81,7 +81,7 @@ class FakePlatformWindow : public ui::PlatformWindow, public ui::WmDragHandler {
ui::WmDropHandler* drop_handler = ui::GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragEnter(point, std::move(data), operation);
drop_handler->OnDragEnter(point, std::move(data), operation, 0);
}
int OnDragMotion(const gfx::PointF& point, int operation) {
......@@ -89,14 +89,14 @@ class FakePlatformWindow : public ui::PlatformWindow, public ui::WmDragHandler {
if (!drop_handler)
return 0;
return drop_handler->OnDragMotion(point, operation);
return drop_handler->OnDragMotion(point, operation, 0);
}
void OnDragDrop(std::unique_ptr<OSExchangeData> data) {
ui::WmDropHandler* drop_handler = ui::GetWmDropHandler(*this);
if (!drop_handler)
return;
drop_handler->OnDragDrop(std::move(data));
drop_handler->OnDragDrop(std::move(data), 0);
}
void OnDragLeave() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment