Index: services/ui/public/cpp/window_tree_client.cc |
diff --git a/services/ui/public/cpp/window_tree_client.cc b/services/ui/public/cpp/window_tree_client.cc |
index 07f856e1a8e081a9bd603d99a7242ba836a62bf5..0b6a5f2757601d944e5146ab6cb9c6cb4542bb02 100644 |
--- a/services/ui/public/cpp/window_tree_client.cc |
+++ b/services/ui/public/cpp/window_tree_client.cc |
@@ -16,6 +16,7 @@ |
#include "services/ui/common/util.h" |
#include "services/ui/public/cpp/in_flight_change.h" |
#include "services/ui/public/cpp/input_event_handler.h" |
+#include "services/ui/public/cpp/window_drop_target.h" |
#include "services/ui/public/cpp/window_manager_delegate.h" |
#include "services/ui/public/cpp/window_observer.h" |
#include "services/ui/public/cpp/window_private.h" |
@@ -82,6 +83,14 @@ Window* BuildWindowTree(WindowTreeClient* client, |
return root; |
} |
+struct WindowTreeClient::CurrentDragState { |
+ // The current change id of the current drag an drop ipc. |
+ uint32_t change_id; |
+ |
+ // Callback executed when a drag initiated by PerformDragDrop() is completed. |
+ base::Callback<void(bool)> on_finished; |
+}; |
+ |
WindowTreeClient::WindowTreeClient( |
WindowTreeClientDelegate* delegate, |
WindowManagerDelegate* window_manager_delegate, |
@@ -631,6 +640,37 @@ void WindowTreeClient::StopPointerWatcher() { |
has_pointer_watcher_ = false; |
} |
+void WindowTreeClient::PerformDragDrop( |
+ Window* window, |
+ int drag_pointer, |
+ const std::map<std::string, std::vector<uint8_t>>& drag_data, |
+ int drag_operation, |
+ const gfx::Point& cursor_location, |
+ const SkBitmap& bitmap, |
+ const base::Callback<void(bool)>& callback) { |
+ DCHECK(!current_drag_state_); |
+ |
+ // TODO(erg): Pass |cursor_location| and |bitmap| in PerformDragDrop() when |
+ // we start showing an image representation of the drag under he cursor. |
+ |
+ if (window->drop_target()) { |
+ // To minimize the number of round trips, copy the drag drop data to our |
+ // handler here, instead of forcing mus to send this same data back. |
+ OnDragDropStart( |
+ mojo::Map<mojo::String, mojo::Array<uint8_t>>::From(drag_data)); |
+ } |
+ |
+ uint32_t current_drag_change = ScheduleInFlightChange( |
+ base::MakeUnique<InFlightDragChange>(window, ChangeType::DRAG_LOOP)); |
+ current_drag_state_.reset( |
+ new CurrentDragState{current_drag_change, callback}); |
+ |
+ tree_->PerformDragDrop( |
+ current_drag_change, window->server_id(), drag_pointer, |
+ mojo::Map<mojo::String, mojo::Array<uint8_t>>::From(drag_data), |
+ drag_operation); |
+} |
+ |
void WindowTreeClient::PerformWindowMove( |
Window* window, |
ui::mojom::MoveLoopSource source, |
@@ -640,7 +680,7 @@ void WindowTreeClient::PerformWindowMove( |
on_current_move_finished_ = callback; |
current_move_loop_change_ = ScheduleInFlightChange( |
- base::MakeUnique<InFlightMoveLoopChange>(window)); |
+ base::MakeUnique<InFlightDragChange>(window, ChangeType::MOVE_LOOP)); |
// Tell the window manager to take over moving us. |
tree_->PerformWindowMove(current_move_loop_change_, window->server_id(), |
source, cursor_location); |
@@ -698,6 +738,11 @@ void WindowTreeClient::RemoveObserver(WindowTreeClientObserver* observer) { |
observers_.RemoveObserver(observer); |
} |
+void WindowTreeClient::SetCanAcceptDrops(Id window_id, bool can_accept_drops) { |
+ DCHECK(tree_); |
+ tree_->SetCanAcceptDrops(window_id, can_accept_drops); |
+} |
+ |
void WindowTreeClient::SetCanAcceptEvents(Id window_id, |
bool can_accept_events) { |
DCHECK(tree_); |
@@ -1044,6 +1089,83 @@ void WindowTreeClient::OnWindowPredefinedCursorChanged( |
WindowPrivate(window).LocalSetPredefinedCursor(cursor); |
} |
+void WindowTreeClient::OnDragDropStart( |
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) { |
+ mime_drag_data_ = std::move(mime_data); |
+} |
+ |
+void WindowTreeClient::OnDragEnter(Id window_id, |
+ uint32_t key_state, |
+ const gfx::Point& position, |
+ uint32_t effect_bitmask, |
+ const OnDragEnterCallback& callback) { |
+ Window* window = GetWindowByServerId(window_id); |
+ if (!window || !window->drop_target()) { |
+ callback.Run(mojom::kDropEffectNone); |
+ return; |
+ } |
+ |
+ if (!base::ContainsKey(drag_entered_windows_, window_id)) { |
+ window->drop_target()->OnDragDropStart( |
+ mime_drag_data_.To<std::map<std::string, std::vector<uint8_t>>>()); |
+ drag_entered_windows_.insert(window_id); |
+ } |
+ |
+ uint32_t ret = |
+ window->drop_target()->OnDragEnter(key_state, position, effect_bitmask); |
+ callback.Run(ret); |
+} |
+ |
+void WindowTreeClient::OnDragOver(Id window_id, |
+ uint32_t key_state, |
+ const gfx::Point& position, |
+ uint32_t effect_bitmask, |
+ const OnDragOverCallback& callback) { |
+ Window* window = GetWindowByServerId(window_id); |
+ if (!window || !window->drop_target()) { |
+ callback.Run(mojom::kDropEffectNone); |
+ return; |
+ } |
+ |
+ uint32_t ret = |
+ window->drop_target()->OnDragOver(key_state, position, effect_bitmask); |
+ callback.Run(ret); |
+} |
+ |
+void WindowTreeClient::OnDragLeave(Id window_id) { |
+ Window* window = GetWindowByServerId(window_id); |
+ if (!window || !window->drop_target()) |
+ return; |
+ |
+ window->drop_target()->OnDragLeave(); |
+} |
+ |
+void WindowTreeClient::OnDragDropDone() { |
+ for (Id id : drag_entered_windows_) { |
+ Window* window = GetWindowByServerId(id); |
+ if (!window || !window->drop_target()) |
+ continue; |
+ window->drop_target()->OnDragDropDone(); |
+ } |
+ drag_entered_windows_.clear(); |
+} |
+ |
+void WindowTreeClient::OnCompleteDrop(Id window_id, |
+ uint32_t key_state, |
+ const gfx::Point& position, |
+ uint32_t effect_bitmask, |
+ const OnCompleteDropCallback& callback) { |
+ Window* window = GetWindowByServerId(window_id); |
+ if (!window || !window->drop_target()) { |
+ callback.Run(mojom::kDropEffectNone); |
+ return; |
+ } |
+ |
+ uint32_t ret = window->drop_target()->OnCompleteDrop(key_state, position, |
+ effect_bitmask); |
+ callback.Run(ret); |
+} |
+ |
void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { |
std::unique_ptr<InFlightChange> change(std::move(in_flight_map_[change_id])); |
in_flight_map_.erase(change_id); |
@@ -1066,6 +1188,13 @@ void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) { |
on_current_move_finished_.Run(success); |
on_current_move_finished_.Reset(); |
} |
+ |
+ if (current_drag_state_ && change_id == current_drag_state_->change_id) { |
+ OnDragDropDone(); |
+ |
+ current_drag_state_->on_finished.Run(success); |
+ current_drag_state_.reset(); |
+ } |
} |
void WindowTreeClient::GetWindowManager( |