Commit 5ef4d91b authored by erg's avatar erg Committed by Commit bot

mus drag and drop: return the completed effect to the caller.

While implementing the views drag implementation, I had thought that you
didn't need to return this value, as nothing in views uses it. However,
it does get used in WebContents, so add it in.

BUG=614037

Review-Url: https://codereview.chromium.org/2349973010
Cr-Commit-Position: refs/heads/master@{#419924}
parent 5aa0631c
...@@ -487,7 +487,7 @@ void Window::PerformDragDrop( ...@@ -487,7 +487,7 @@ void Window::PerformDragDrop(
int drag_operation, int drag_operation,
const gfx::Point& cursor_location, const gfx::Point& cursor_location,
const SkBitmap& bitmap, const SkBitmap& bitmap,
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool, uint32_t)>& callback) {
client_->PerformDragDrop(this, drag_pointer, drag_data, drag_operation, client_->PerformDragDrop(this, drag_pointer, drag_data, drag_operation,
cursor_location, bitmap, callback); cursor_location, bitmap, callback);
} }
......
...@@ -231,14 +231,17 @@ class Window { ...@@ -231,14 +231,17 @@ class Window {
// to a better place. // to a better place.
void RequestClose(); void RequestClose();
// Starts an inter-process drag and drop operation. // Starts an inter-process drag and drop operation. When this finishes, will
// return the tuple [success, action_taken] to |callback|, where action_taken
// is one of the ui::mojom::kDropEffect constants in
// window_tree_constants.mojom.
void PerformDragDrop( void PerformDragDrop(
int drag_pointer, int drag_pointer,
const std::map<std::string, std::vector<uint8_t>>& drag_data, const std::map<std::string, std::vector<uint8_t>>& drag_data,
int drag_operation, int drag_operation,
const gfx::Point& cursor_location, const gfx::Point& cursor_location,
const SkBitmap& bitmap, const SkBitmap& bitmap,
const base::Callback<void(bool)>& callback); const base::Callback<void(bool, uint32_t)>& callback);
// Tells the window manager to take control of moving the window. Returns // Tells the window manager to take control of moving the window. Returns
// true if the move wasn't canceled. // true if the move wasn't canceled.
......
...@@ -87,8 +87,11 @@ struct WindowTreeClient::CurrentDragState { ...@@ -87,8 +87,11 @@ struct WindowTreeClient::CurrentDragState {
// The current change id of the current drag an drop ipc. // The current change id of the current drag an drop ipc.
uint32_t change_id; uint32_t change_id;
// The effect to return when we send our finish signal.
uint32_t completed_action;
// Callback executed when a drag initiated by PerformDragDrop() is completed. // Callback executed when a drag initiated by PerformDragDrop() is completed.
base::Callback<void(bool)> on_finished; base::Callback<void(bool, uint32_t)> on_finished;
}; };
WindowTreeClient::WindowTreeClient( WindowTreeClient::WindowTreeClient(
...@@ -647,7 +650,7 @@ void WindowTreeClient::PerformDragDrop( ...@@ -647,7 +650,7 @@ void WindowTreeClient::PerformDragDrop(
int drag_operation, int drag_operation,
const gfx::Point& cursor_location, const gfx::Point& cursor_location,
const SkBitmap& bitmap, const SkBitmap& bitmap,
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool, uint32_t)>& callback) {
DCHECK(!current_drag_state_); DCHECK(!current_drag_state_);
// TODO(erg): Pass |cursor_location| and |bitmap| in PerformDragDrop() when // TODO(erg): Pass |cursor_location| and |bitmap| in PerformDragDrop() when
...@@ -662,8 +665,8 @@ void WindowTreeClient::PerformDragDrop( ...@@ -662,8 +665,8 @@ void WindowTreeClient::PerformDragDrop(
uint32_t current_drag_change = ScheduleInFlightChange( uint32_t current_drag_change = ScheduleInFlightChange(
base::MakeUnique<InFlightDragChange>(window, ChangeType::DRAG_LOOP)); base::MakeUnique<InFlightDragChange>(window, ChangeType::DRAG_LOOP));
current_drag_state_.reset( current_drag_state_.reset(new CurrentDragState{
new CurrentDragState{current_drag_change, callback}); current_drag_change, ui::mojom::kDropEffectNone, callback});
tree_->PerformDragDrop( tree_->PerformDragDrop(
current_drag_change, window->server_id(), drag_pointer, current_drag_change, window->server_id(), drag_pointer,
...@@ -1166,6 +1169,15 @@ void WindowTreeClient::OnCompleteDrop(Id window_id, ...@@ -1166,6 +1169,15 @@ void WindowTreeClient::OnCompleteDrop(Id window_id,
callback.Run(ret); callback.Run(ret);
} }
void WindowTreeClient::OnPerformDragDropCompleted(uint32_t change_id,
bool success,
uint32_t action_taken) {
if (current_drag_state_ && change_id == current_drag_state_->change_id) {
current_drag_state_->completed_action = action_taken;
OnChangeCompleted(change_id, success);
}
}
void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
std::unique_ptr<InFlightChange> change(std::move(in_flight_map_[change_id])); std::unique_ptr<InFlightChange> change(std::move(in_flight_map_[change_id]));
in_flight_map_.erase(change_id); in_flight_map_.erase(change_id);
...@@ -1192,7 +1204,8 @@ void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { ...@@ -1192,7 +1204,8 @@ void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
if (current_drag_state_ && change_id == current_drag_state_->change_id) { if (current_drag_state_ && change_id == current_drag_state_->change_id) {
OnDragDropDone(); OnDragDropDone();
current_drag_state_->on_finished.Run(success); current_drag_state_->on_finished.Run(success,
current_drag_state_->completed_action);
current_drag_state_.reset(); current_drag_state_.reset();
} }
} }
......
...@@ -183,7 +183,7 @@ class WindowTreeClient : public mojom::WindowTreeClient, ...@@ -183,7 +183,7 @@ class WindowTreeClient : public mojom::WindowTreeClient,
int drag_operation, int drag_operation,
const gfx::Point& cursor_location, const gfx::Point& cursor_location,
const SkBitmap& bitmap, const SkBitmap& bitmap,
const base::Callback<void(bool)>& callback); const base::Callback<void(bool, uint32_t)>& callback);
// Performs a window move. |callback| will be asynchronously called with the // Performs a window move. |callback| will be asynchronously called with the
// whether the move loop completed successfully. // whether the move loop completed successfully.
...@@ -338,6 +338,9 @@ class WindowTreeClient : public mojom::WindowTreeClient, ...@@ -338,6 +338,9 @@ class WindowTreeClient : public mojom::WindowTreeClient,
const gfx::Point& position, const gfx::Point& position,
uint32_t effect_bitmask, uint32_t effect_bitmask,
const OnCompleteDropCallback& callback) override; const OnCompleteDropCallback& callback) override;
void OnPerformDragDropCompleted(uint32_t window,
bool success,
uint32_t action_taken) override;
void OnDragDropDone() override; void OnDragDropDone() override;
void OnChangeCompleted(uint32_t change_id, bool success) override; void OnChangeCompleted(uint32_t change_id, bool success) override;
void RequestClose(uint32_t window_id) override; void RequestClose(uint32_t window_id) override;
......
...@@ -450,10 +450,14 @@ interface WindowTreeClient { ...@@ -450,10 +450,14 @@ interface WindowTreeClient {
OnCompleteDrop(uint32 window, OnCompleteDrop(uint32 window,
uint32 key_state, uint32 key_state,
gfx.mojom.Point position, gfx.mojom.Point position,
uint32 effect_bitmask) => (uint32 effect_taken); uint32 effect_bitmask) => (uint32 action_taken);
// Called after OnDragDrop completes for every connection which received an // Called on the client that requested PerformDragDrop() to return which drag
// OnDragDropStart() message. This signals that a client can forget the // action was completed. This is called instead of OnChangeCompleted().
OnPerformDragDropCompleted(uint32 window, bool success, uint32 action_taken);
// Called after OnCompleteDrop completes for every connection which received
// an OnDragDropStart() message. This signals that a client can forget the
// |drag_data| passed in via the first message. // |drag_data| passed in via the first message.
OnDragDropDone(); OnDragDropDone();
......
...@@ -57,7 +57,7 @@ DragController::~DragController() { ...@@ -57,7 +57,7 @@ DragController::~DragController() {
} }
void DragController::Cancel() { void DragController::Cancel() {
MessageDragCompleted(false); MessageDragCompleted(false, ui::mojom::kDropEffectNone);
// |this| may be deleted now. // |this| may be deleted now.
} }
...@@ -117,7 +117,7 @@ bool DragController::DispatchPointerEvent(const ui::PointerEvent& event, ...@@ -117,7 +117,7 @@ bool DragController::DispatchPointerEvent(const ui::PointerEvent& event,
} else { } else {
// The pointer was released over no window or a window that doesn't // The pointer was released over no window or a window that doesn't
// accept drags. // accept drags.
MessageDragCompleted(false); MessageDragCompleted(false, ui::mojom::kDropEffectNone);
} }
} }
...@@ -129,12 +129,12 @@ void DragController::OnWillDestroyDragTargetConnection( ...@@ -129,12 +129,12 @@ void DragController::OnWillDestroyDragTargetConnection(
called_on_drag_mime_types_.erase(connection); called_on_drag_mime_types_.erase(connection);
} }
void DragController::MessageDragCompleted(bool success) { void DragController::MessageDragCompleted(bool success, uint32_t action_taken) {
for (DragTargetConnection* connection : called_on_drag_mime_types_) for (DragTargetConnection* connection : called_on_drag_mime_types_)
connection->PerformOnDragDropDone(); connection->PerformOnDragDropDone();
called_on_drag_mime_types_.clear(); called_on_drag_mime_types_.clear();
source_->OnDragCompleted(success); source_->OnDragCompleted(success, action_taken);
// |this| may be deleted now. // |this| may be deleted now.
} }
...@@ -255,18 +255,18 @@ void DragController::OnDragStatusCompleted(const WindowId& id, ...@@ -255,18 +255,18 @@ void DragController::OnDragStatusCompleted(const WindowId& id,
// should use this data to change the cursor. // should use this data to change the cursor.
} }
void DragController::OnDragDropCompleted(const WindowId& id, uint32_t bitmask) { void DragController::OnDragDropCompleted(const WindowId& id, uint32_t action) {
ServerWindow* window = source_->GetWindowById(id); ServerWindow* window = source_->GetWindowById(id);
if (!window) { if (!window) {
// The window has been deleted after we sent the drop message. It's really // The window has been deleted after we sent the drop message. It's really
// hard to recover from this so just signal to the source that our drag // hard to recover from this so just signal to the source that our drag
// failed. // failed.
MessageDragCompleted(false); MessageDragCompleted(false, ui::mojom::kDropEffectNone);
return; return;
} }
OnRespondToOperation(window); OnRespondToOperation(window);
MessageDragCompleted(bitmask != 0u); MessageDragCompleted(action != 0u, action);
} }
void DragController::OnWindowDestroying(ServerWindow* window) { void DragController::OnWindowDestroying(ServerWindow* window) {
...@@ -282,7 +282,7 @@ void DragController::OnWindowDestroying(ServerWindow* window) { ...@@ -282,7 +282,7 @@ void DragController::OnWindowDestroying(ServerWindow* window) {
if (source_window_ == window) { if (source_window_ == window) {
source_window_ = nullptr; source_window_ = nullptr;
// Our source window is being deleted, fail the drag. // Our source window is being deleted, fail the drag.
MessageDragCompleted(false); MessageDragCompleted(false, ui::mojom::kDropEffectNone);
} }
} }
......
...@@ -52,7 +52,7 @@ class DragController : public ServerWindowObserver { ...@@ -52,7 +52,7 @@ class DragController : public ServerWindowObserver {
// Notifies all windows we messaged that the drag is finished, and then tell // Notifies all windows we messaged that the drag is finished, and then tell
// |source| the result. // |source| the result.
void MessageDragCompleted(bool success); void MessageDragCompleted(bool success, uint32_t action_taken);
// Returns the number of events on |window|. A value of 1 means that there's // Returns the number of events on |window|. A value of 1 means that there's
// a single event outstanding that we're waiting for a response from the // a single event outstanding that we're waiting for a response from the
...@@ -77,7 +77,7 @@ class DragController : public ServerWindowObserver { ...@@ -77,7 +77,7 @@ class DragController : public ServerWindowObserver {
// Callback methods. // Callback methods.
void OnDragStatusCompleted(const WindowId& id, uint32_t bitmask); void OnDragStatusCompleted(const WindowId& id, uint32_t bitmask);
void OnDragDropCompleted(const WindowId& id, uint32_t bitmask); void OnDragDropCompleted(const WindowId& id, uint32_t action);
// ServerWindowObserver: // ServerWindowObserver:
void OnWindowDestroying(ServerWindow* window) override; void OnWindowDestroying(ServerWindow* window) override;
......
...@@ -179,6 +179,10 @@ class DragControllerTest : public testing::Test, public DragSource { ...@@ -179,6 +179,10 @@ class DragControllerTest : public testing::Test, public DragSource {
} }
DragController* drag_operation() const { return drag_operation_.get(); } DragController* drag_operation() const { return drag_operation_.get(); }
const base::Optional<uint32_t>& drag_completed_action() {
return drag_completed_action_;
}
const base::Optional<bool>& drag_completed_value() { const base::Optional<bool>& drag_completed_value() {
return drag_completed_value_; return drag_completed_value_;
} }
...@@ -207,7 +211,8 @@ class DragControllerTest : public testing::Test, public DragSource { ...@@ -207,7 +211,8 @@ class DragControllerTest : public testing::Test, public DragSource {
} }
// Overridden from DragControllerSource: // Overridden from DragControllerSource:
void OnDragCompleted(bool success) override { void OnDragCompleted(bool success, uint32_t action_taken) override {
drag_completed_action_ = action_taken;
drag_completed_value_ = success; drag_completed_value_ = success;
} }
...@@ -236,6 +241,7 @@ class DragControllerTest : public testing::Test, public DragSource { ...@@ -236,6 +241,7 @@ class DragControllerTest : public testing::Test, public DragSource {
std::unique_ptr<DragController> drag_operation_; std::unique_ptr<DragController> drag_operation_;
base::Optional<uint32_t> drag_completed_action_;
base::Optional<bool> drag_completed_value_; base::Optional<bool> drag_completed_value_;
}; };
...@@ -261,9 +267,37 @@ TEST_F(DragControllerTest, SimpleDragDrop) { ...@@ -261,9 +267,37 @@ TEST_F(DragControllerTest, SimpleDragDrop) {
EXPECT_EQ(QueuedType::DROP, window->queue_response_type()); EXPECT_EQ(QueuedType::DROP, window->queue_response_type());
window->Respond(true); window->Respond(true);
EXPECT_EQ(ui::mojom::kDropEffectMove,
drag_completed_action().value_or(ui::mojom::kDropEffectNone));
EXPECT_TRUE(drag_completed_value().value_or(false)); EXPECT_TRUE(drag_completed_value().value_or(false));
} }
TEST_F(DragControllerTest, FailsOnWindowSayingNo) {
std::unique_ptr<DragTestWindow> window = BuildWindow();
mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
StartDragOperation(std::move(mime_data), window.get(),
ui::mojom::kDropEffectMove);
DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
window->Respond(true);
DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
window->Respond(true);
DispatchDrag(window.get(), true, 0, gfx::Point(2, 2));
EXPECT_EQ(QueuedType::DROP, window->queue_response_type());
// Unlike SimpleDragDrop, respond with kDropEffectNone, which should make the
// drag fail.
window->Respond(false);
EXPECT_EQ(ui::mojom::kDropEffectNone,
drag_completed_action().value_or(ui::mojom::kDropEffectCopy));
EXPECT_FALSE(drag_completed_value().value_or(true));
}
TEST_F(DragControllerTest, OnlyDeliverMimeDataOnce) { TEST_F(DragControllerTest, OnlyDeliverMimeDataOnce) {
std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window1 = BuildWindow();
std::unique_ptr<DragTestWindow> window2 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow();
......
...@@ -20,8 +20,9 @@ class DragSource { ...@@ -20,8 +20,9 @@ class DragSource {
// Called when a drag operation is completed. |success| is true when a target // Called when a drag operation is completed. |success| is true when a target
// window signaled the successful completion of the drag, false in all other // window signaled the successful completion of the drag, false in all other
// cases where a drag was aborted at any step in the process. // cases where a drag was aborted at any step in the process. |action_taken|
virtual void OnDragCompleted(bool success) = 0; // is one of the kDropEffect constants in window_tree_constants.mojom.
virtual void OnDragCompleted(bool success, uint32_t action_taken) = 0;
virtual ServerWindow* GetWindowById(const WindowId& id) = 0; virtual ServerWindow* GetWindowById(const WindowId& id) = 0;
......
...@@ -381,6 +381,10 @@ void TestWindowTreeClient::OnCompleteDrop( ...@@ -381,6 +381,10 @@ void TestWindowTreeClient::OnCompleteDrop(
uint32_t effect_bitmask, uint32_t effect_bitmask,
const OnCompleteDropCallback& callback) {} const OnCompleteDropCallback& callback) {}
void TestWindowTreeClient::OnPerformDragDropCompleted(uint32_t window,
bool success,
uint32_t action_taken) {}
void TestWindowTreeClient::OnDragDropDone() {} void TestWindowTreeClient::OnDragDropDone() {}
void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
......
...@@ -456,6 +456,9 @@ class TestWindowTreeClient : public ui::mojom::WindowTreeClient { ...@@ -456,6 +456,9 @@ class TestWindowTreeClient : public ui::mojom::WindowTreeClient {
const gfx::Point& position, const gfx::Point& position,
uint32_t effect_bitmask, uint32_t effect_bitmask,
const OnCompleteDropCallback& callback) override; const OnCompleteDropCallback& callback) override;
void OnPerformDragDropCompleted(uint32_t window,
bool success,
uint32_t action_taken) override;
void OnDragDropDone() override; void OnDragDropDone() override;
void OnChangeCompleted(uint32_t change_id, bool success) override; void OnChangeCompleted(uint32_t change_id, bool success) override;
void RequestClose(uint32_t window_id) override; void RequestClose(uint32_t window_id) override;
......
...@@ -1778,7 +1778,7 @@ bool WindowTree::IsWindowRootOfAnotherTreeForAccessPolicy( ...@@ -1778,7 +1778,7 @@ bool WindowTree::IsWindowRootOfAnotherTreeForAccessPolicy(
return tree && tree != this; return tree && tree != this;
} }
void WindowTree::OnDragCompleted(bool success) { void WindowTree::OnDragCompleted(bool success, uint32_t action_taken) {
DCHECK(window_server_->in_drag_loop()); DCHECK(window_server_->in_drag_loop());
if (window_server_->GetCurrentDragLoopInitiator() != this) if (window_server_->GetCurrentDragLoopInitiator() != this)
...@@ -1794,7 +1794,7 @@ void WindowTree::OnDragCompleted(bool success) { ...@@ -1794,7 +1794,7 @@ void WindowTree::OnDragCompleted(bool success) {
WindowManagerState* wms = display_root->window_manager_state(); WindowManagerState* wms = display_root->window_manager_state();
wms->EndDragDrop(); wms->EndDragDrop();
client()->OnChangeCompleted(change_id, success); client()->OnPerformDragDropCompleted(change_id, success, action_taken);
} }
ServerWindow* WindowTree::GetWindowById(const WindowId& id) { ServerWindow* WindowTree::GetWindowById(const WindowId& id) {
......
...@@ -484,7 +484,7 @@ class WindowTree : public mojom::WindowTree, ...@@ -484,7 +484,7 @@ class WindowTree : public mojom::WindowTree,
const ServerWindow* window) const override; const ServerWindow* window) const override;
// DragSource: // DragSource:
void OnDragCompleted(bool success) override; void OnDragCompleted(bool success, uint32_t action_taken) override;
ServerWindow* GetWindowById(const WindowId& id) override; ServerWindow* GetWindowById(const WindowId& id) override;
DragTargetConnection* GetDragTargetForWindow( DragTargetConnection* GetDragTargetForWindow(
const ServerWindow* window) override; const ServerWindow* window) override;
......
...@@ -399,6 +399,13 @@ class TestWindowTreeClient : public mojom::WindowTreeClient, ...@@ -399,6 +399,13 @@ class TestWindowTreeClient : public mojom::WindowTreeClient,
const OnCompleteDropCallback& callback) override { const OnCompleteDropCallback& callback) override {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void OnPerformDragDropCompleted(uint32_t window,
bool success,
uint32_t action_taken) override {
NOTIMPLEMENTED();
}
void OnDragDropDone() override { NOTIMPLEMENTED(); } void OnDragDropDone() override { NOTIMPLEMENTED(); }
void OnChangeCompleted(uint32_t change_id, bool success) override { void OnChangeCompleted(uint32_t change_id, bool success) override {
......
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