Chromium Code Reviews| 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 |