Index: services/ui/ws/window_tree.cc |
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc |
index 1841ffee0ca8a83d009cc303e5cd7f72f46a07c8..5a7674831be25de6d05045e08c1778380db84cb1 100644 |
--- a/services/ui/ws/window_tree.cc |
+++ b/services/ui/ws/window_tree.cc |
@@ -1387,6 +1387,16 @@ void WindowTree::SetHitTestMask(Id transport_window_id, |
window->ClearHitTestMask(); |
} |
+void WindowTree::SetCanAcceptDrops(Id window_id, bool accepts_drops) { |
+ ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); |
+ if (!window || !access_policy_->CanSetAcceptDrops(window)) { |
+ DVLOG(1) << "SetAcceptsDrops failed"; |
+ return; |
+ } |
+ |
+ window->SetCanAcceptDrops(accepts_drops); |
+} |
+ |
void WindowTree::Embed(Id transport_window_id, |
mojom::WindowTreeClientPtr client, |
uint32_t flags, |
@@ -1452,6 +1462,47 @@ void WindowTree::GetCursorLocationMemory( |
GetCursorLocationMemory()); |
} |
+void WindowTree::PerformDragDrop( |
+ uint32_t change_id, |
+ uint32_t source_window_id, |
sky
2016/09/13 18:15:32
uint32_t -> Id
|
+ int32_t drag_pointer, |
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> drag_data, |
+ uint32_t drag_operation) { |
+ ServerWindow* window = GetWindowByClientId(ClientWindowId(source_window_id)); |
+ bool success = window && access_policy_->CanInitiateMoveLoop(window); |
sky
2016/09/13 18:15:32
Please add a new function, CanInitiateDragLoop?
|
+ if (!success || !ShouldRouteToWindowManager(window)) { |
+ // We need to fail this move loop change, otherwise the client will just be |
+ // waiting for |change_id|. |
+ OnChangeCompleted(change_id, false); |
sky
2016/09/13 18:15:32
Please DVLOG the failures.
|
+ return; |
+ } |
+ |
+ WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window); |
+ if (!display_root) { |
+ // The window isn't parented. There's nothing to do. |
+ OnChangeCompleted(change_id, false); |
+ return; |
+ } |
+ |
+ if (window_server_->in_move_loop() || window_server_->in_drag_loop()) { |
+ // Either the window manager is servicing a window drag or we're servicing |
+ // a drag and drop operation. We can't start a second drag. |
+ OnChangeCompleted(change_id, false); |
+ return; |
+ } |
+ |
+ // TODO(erg): Dealing with |drag_representation| is hard, so we're going to |
+ // deal with that later. |
+ |
+ // Here, we need to dramatically change how the mouse pointer works. Once |
+ // we've started a drag drop operation, cursor events don't go to windows as |
+ // normal. |
+ WindowManagerState* wms = display_root->window_manager_state(); |
+ window_server_->StartDragLoop(change_id, window, this); |
+ wms->SetDragDropSourceWindow(this, window, this, drag_pointer, |
sky
2016/09/13 18:15:32
optional: it's mildly weird that WindowServer::Sta
|
+ std::move(drag_data), drag_operation); |
+} |
+ |
void WindowTree::PerformWindowMove(uint32_t change_id, |
Id window_id, |
ui::mojom::MoveLoopSource source, |
@@ -1472,9 +1523,9 @@ void WindowTree::PerformWindowMove(uint32_t change_id, |
return; |
} |
- if (window_server_->in_move_loop()) { |
- // A window manager is already servicing a move loop; we can't start a |
- // second one. |
+ if (window_server_->in_move_loop() || window_server_->in_drag_loop()) { |
+ // Either the window manager is servicing a window drag or we're servicing |
+ // a drag and drop operation. We can't start a second drag. |
OnChangeCompleted(change_id, false); |
return; |
} |
@@ -1681,5 +1732,97 @@ bool WindowTree::IsWindowRootOfAnotherTreeForAccessPolicy( |
return tree && tree != this; |
} |
+void WindowTree::OnDragCompleted(bool success) { |
+ DCHECK(window_server_->in_drag_loop()); |
+ DCHECK_EQ(this, window_server_->GetCurrentDragLoopInitiator()); |
+ |
+ uint32_t change_id = window_server_->GetCurrentDragLoopChangeId(); |
+ ServerWindow* window = window_server_->GetCurrentDragLoopWindow(); |
+ WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window); |
+ if (!display_root) |
+ return; |
+ |
+ window_server_->EndDragLoop(); |
+ WindowManagerState* wms = display_root->window_manager_state(); |
+ wms->EndDragDrop(); |
+ |
+ client()->OnChangeCompleted(change_id, success); |
+} |
+ |
+ServerWindow* WindowTree::GetWindowById(const WindowId& id) { |
+ return GetWindow(id); |
+} |
+ |
+DragTargetConnection* WindowTree::GetDragTargetWithRoot( |
+ const ServerWindow* window) { |
+ return window_server_->GetTreeWithRoot(window); |
sky
2016/09/13 18:15:32
This returns the WindowTree that has |window| as o
|
+} |
+ |
+void WindowTree::PerformOnDragMimeTypes( |
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) { |
+ client()->OnDragMimeTypes(std::move(mime_data)); |
+} |
+ |
+void WindowTree::PerformOnDragEnter( |
+ const ServerWindow* window, |
+ uint32_t event_flags, |
+ const gfx::Point& cursor_offset, |
+ uint32_t effect_bitmask, |
+ const base::Callback<void(uint32_t)>& callback) { |
+ ClientWindowId client_window_id; |
+ if (!IsWindowKnown(window, &client_window_id)) { |
+ NOTREACHED(); |
+ callback.Run(0); |
+ return; |
+ } |
+ client()->OnDragEnter(client_window_id.id, event_flags, cursor_offset, |
+ effect_bitmask, callback); |
+} |
+ |
+void WindowTree::PerformOnDragOver( |
+ const ServerWindow* window, |
+ uint32_t event_flags, |
+ const gfx::Point& cursor_offset, |
+ uint32_t effect_bitmask, |
+ const base::Callback<void(uint32_t)>& callback) { |
+ ClientWindowId client_window_id; |
+ if (!IsWindowKnown(window, &client_window_id)) { |
+ NOTREACHED(); |
+ callback.Run(0); |
+ return; |
+ } |
+ client()->OnDragOver(client_window_id.id, event_flags, cursor_offset, |
+ effect_bitmask, callback); |
+} |
+ |
+void WindowTree::PerformOnDragLeave(const ServerWindow* window) { |
+ ClientWindowId client_window_id; |
+ if (!IsWindowKnown(window, &client_window_id)) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ client()->OnDragLeave(client_window_id.id); |
+} |
+ |
+void WindowTree::PerformOnCompleteDrop( |
+ const ServerWindow* window, |
+ uint32_t event_flags, |
+ const gfx::Point& cursor_offset, |
+ uint32_t effect_bitmask, |
+ const base::Callback<void(uint32_t)>& callback) { |
+ ClientWindowId client_window_id; |
+ if (!IsWindowKnown(window, &client_window_id)) { |
+ NOTREACHED(); |
+ callback.Run(0); |
+ return; |
+ } |
+ client()->OnCompleteDrop(client_window_id.id, event_flags, cursor_offset, |
+ effect_bitmask, callback); |
+} |
+ |
+void WindowTree::PerformOnDragFinish() { |
+ client()->OnDragFinish(); |
+} |
+ |
} // namespace ws |
} // namespace ui |