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

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: Uploaded for a few comments. Created 4 years, 4 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 7780d57fe07600d53bc4349aea0e04805ad1d170..30245666b2e9d927296b1e9c5c7f9743f14cdc14 100644
--- a/services/ui/ws/window_tree.cc
+++ b/services/ui/ws/window_tree.cc
@@ -455,6 +455,11 @@ void WindowTree::AddActivationParent(const ClientWindowId& window_id) {
}
void WindowTree::OnChangeCompleted(uint32_t change_id, bool success) {
+ if (window_server_->in_drag_loop() &&
+ change_id == window_server_->GetCurrentDragLoopChangeId()) {
+ window_server_->EndDragLoop();
+ }
+
client()->OnChangeCompleted(change_id, success);
}
@@ -482,6 +487,64 @@ void WindowTree::ClientJankinessChanged(WindowTree* tree) {
}
}
+void WindowTree::PerformOnDragEnter(
+ const ServerWindow* window,
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data,
+ 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, std::move(mime_data), 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::ProcessWindowBoundsChanged(const ServerWindow* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
@@ -1385,6 +1448,16 @@ void WindowTree::SetHitTestMask(Id transport_window_id,
window->ClearHitTestMask();
}
+void WindowTree::SetCanAcceptDrags(Id window_id, bool accepts_drags) {
+ ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
+ if (!window || !access_policy_->CanSetAcceptDrags(window)) {
+ DVLOG(1) << "SetAcceptsDrags failed";
+ return;
+ }
+
+ window->SetCanAcceptDrags(accepts_drags);
+}
+
void WindowTree::Embed(Id transport_window_id,
mojom::WindowTreeClientPtr client,
uint32_t flags,
@@ -1450,6 +1523,48 @@ void WindowTree::GetCursorLocationMemory(
GetCursorLocationMemory());
}
+void WindowTree::PerformDragDrop(
+ uint32_t change_id,
+ uint32_t source_window_id,
+ mojo::Map<mojo::String, mojo::Array<uint8_t>> drag_data,
+ uint32_t drag_operation,
+ const gfx::Point& cursor_offset,
+ const SkBitmap& drag_representation) {
+ 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);
+ wms->SetDragDropSourceWindow(change_id, std::move(drag_data), drag_operation,
+ this, window);
+}
+
void WindowTree::PerformWindowMove(uint32_t change_id,
Id window_id,
ui::mojom::MoveLoopSource source,
@@ -1470,9 +1585,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;
}

Powered by Google App Engine
This is Rietveld 408576698