Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Unified Diff: services/ui/ws/window_tree.cc

Issue 2266603002: mus: Implement interwindow drag and drop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove 'window &&' Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/ui/ws/window_tree.cc
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc
index d25ce00a41e3b706328990879d2b9761ef6edbc1..4af13d6344f88bff5fe8d9d25d18bb83540519eb 100644
--- a/services/ui/ws/window_tree.cc
+++ b/services/ui/ws/window_tree.cc
@@ -1388,6 +1388,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,
@@ -1453,6 +1463,50 @@ void WindowTree::GetCursorLocationMemory(
GetCursorLocationMemory());
}
+void WindowTree::PerformDragDrop(
+ uint32_t change_id,
+ Id 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_->CanInitiateDragLoop(window);
+ if (!success || !ShouldRouteToWindowManager(window)) {
+ // We need to fail this move loop change, otherwise the client will just be
+ // waiting for |change_id|.
+ DVLOG(1) << "PerformDragDrop failed (access denied).";
sky 2016/09/15 18:10:47 Thanks for adding the logs. I think they're helpfu
+ OnChangeCompleted(change_id, false);
+ return;
+ }
+
+ WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window);
+ if (!display_root) {
+ // The window isn't parented. There's nothing to do.
+ DVLOG(1) << "PerformDragDrop failed (window unparented).";
+ 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.
+ DVLOG(1) << "PerformDragDrop failed (already performing a 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,
+ std::move(drag_data), drag_operation);
+}
+
void WindowTree::PerformWindowMove(uint32_t change_id,
Id window_id,
ui::mojom::MoveLoopSource source,
@@ -1462,6 +1516,7 @@ void WindowTree::PerformWindowMove(uint32_t change_id,
if (!success || !ShouldRouteToWindowManager(window)) {
// We need to fail this move loop change, otherwise the client will just be
// waiting for |change_id|.
+ DVLOG(1) << "PerformWindowMove failed (access denied).";
OnChangeCompleted(change_id, false);
return;
}
@@ -1469,13 +1524,15 @@ void WindowTree::PerformWindowMove(uint32_t change_id,
WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window);
if (!display_root) {
// The window isn't parented. There's nothing to do.
+ DVLOG(1) << "PerformWindowMove failed (window unparented).";
OnChangeCompleted(change_id, false);
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.
+ DVLOG(1) << "PerformWindowMove failed (already performing a drag).";
OnChangeCompleted(change_id, false);
return;
}
@@ -1682,5 +1739,104 @@ bool WindowTree::IsWindowRootOfAnotherTreeForAccessPolicy(
return tree && tree != this;
}
+void WindowTree::OnDragCompleted(bool success) {
+ DCHECK(window_server_->in_drag_loop());
+
+ if (window_server_->GetCurrentDragLoopInitiator() != this)
+ return;
+
+ 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::GetDragTargetForWindow(
+ const ServerWindow* window) {
+ if (!window)
+ return nullptr;
+ DragTargetConnection* connection = window_server_->GetTreeWithRoot(window);
+ if (connection)
+ return connection;
+ return window_server_->GetTreeWithId(window->id().client_id);
+}
+
+void WindowTree::PerformOnDragDropStart(
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) {
+ client()->OnDragDropStart(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::PerformOnDragDropDone() {
+ client()->OnDragDropDone();
+}
+
} // namespace ws
} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698