| 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..b02f987482b147e17455ff9fee308ca2fd287556 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,
|
| + 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);
|
| + 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);
|
| + 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, drag_pointer, 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,108 @@ 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);
|
| +}
|
| +
|
| +void WindowTree::PerformOnDragStart(
|
| + const ServerWindow* window,
|
| + mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) {
|
| + ClientWindowId client_window_id;
|
| + if (!IsWindowKnown(window, &client_window_id)) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + client()->OnDragStart(client_window_id.id, std::move(mime_data));
|
| +}
|
| +
|
| +void WindowTree::PerformOnDragEnter(
|
| + const ServerWindow* window,
|
| + uint32_t key_state,
|
| + 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, key_state, cursor_offset,
|
| + effect_bitmask, callback);
|
| +}
|
| +
|
| +void WindowTree::PerformOnDragOver(
|
| + const ServerWindow* window,
|
| + uint32_t key_state,
|
| + 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, key_state, 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::PerformOnDragDrop(
|
| + const ServerWindow* window,
|
| + uint32_t key_state,
|
| + 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()->OnDragDrop(client_window_id.id, key_state, cursor_offset,
|
| + effect_bitmask, callback);
|
| +}
|
| +
|
| +void WindowTree::PerformOnDragFinish(const ServerWindow* window) {
|
| + ClientWindowId client_window_id;
|
| + if (!IsWindowKnown(window, &client_window_id)) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + client()->OnDragFinish(client_window_id.id);
|
| +}
|
| +
|
| } // namespace ws
|
| } // namespace ui
|
|
|