Commit ffa1595c authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

ws2: Wire the drop code path

This CL wires up the drop code path for remote window. That is,
dragging from a local window and drop it on a remote window.

Bug: 837716
Test: services_unittests DragDropDelegateTest.*
Change-Id: I3490864b169ca0873ee3def4dce74d855913643c
Reviewed-on: https://chromium-review.googlesource.com/1099176Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567352}
parent fd5d8f89
......@@ -32,6 +32,8 @@ component("lib") {
"client_change_tracker.h",
"client_root.cc",
"client_root.h",
"drag_drop_delegate.cc",
"drag_drop_delegate.h",
"embedding.cc",
"embedding.h",
"focus_handler.cc",
......@@ -134,6 +136,7 @@ source_set("tests") {
testonly = true
sources = [
"drag_drop_delegate_unittest.cc",
"embedding_unittest.cc",
"focus_handler_unittest.cc",
"screen_provider_unittest.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/ui/ws2/drag_drop_delegate.h"
#include "base/bind.h"
#include "base/strings/string16.h"
#include "mojo/public/cpp/bindings/map.h"
#include "ui/aura/mus/os_exchange_data_provider_mus.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/file_info.h"
#include "ui/gfx/geometry/point.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "url/gurl.h"
namespace ui {
namespace ws2 {
namespace {
// Converts OSExchangeData into mime type data.
using DragDataType = aura::OSExchangeDataProviderMus::Data;
DragDataType GetDragData(const ui::OSExchangeData& data) {
aura::OSExchangeDataProviderMus mus_provider;
base::string16 string;
if (data.GetString(&string))
mus_provider.SetString(string);
GURL url;
base::string16 title;
if (data.GetURLAndTitle(ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url,
&title)) {
mus_provider.SetURL(url, title);
}
std::vector<ui::FileInfo> file_names;
if (data.GetFilenames(&file_names))
mus_provider.SetFilenames(file_names);
base::string16 html;
GURL base_url;
if (data.GetHtml(&html, &base_url))
mus_provider.SetHtml(html, base_url);
return mus_provider.GetData();
}
// Converts |location| in |window| coordinates to screen coordinates.
gfx::Point ToScreenLocation(aura::Window* window, const gfx::Point& location) {
gfx::Point screen_location(location);
wm::ConvertPointToScreen(window, &screen_location);
return screen_location;
}
} // namespace
DragDropDelegate::DragDropDelegate(mojom::WindowTreeClient* window_tree_client,
aura::Window* window,
Id transport_window_id)
: tree_client_(window_tree_client),
window_(window),
transport_window_id_(transport_window_id) {}
DragDropDelegate::~DragDropDelegate() {
if (in_drag_)
EndDrag();
}
void DragDropDelegate::OnDragEntered(const ui::DropTargetEvent& event) {
StartDrag(event);
tree_client_->OnDragEnter(
transport_window_id_, event.flags(),
ToScreenLocation(window_, event.location()), event.source_operations(),
base::BindOnce(&DragDropDelegate::UpdateDragOperations,
weak_ptr_factory_.GetWeakPtr()));
}
int DragDropDelegate::OnDragUpdated(const ui::DropTargetEvent& event) {
DCHECK(in_drag_);
tree_client_->OnDragOver(
transport_window_id_, event.flags(),
ToScreenLocation(window_, event.location()), event.source_operations(),
base::BindOnce(&DragDropDelegate::UpdateDragOperations,
weak_ptr_factory_.GetWeakPtr()));
return last_drag_operations_;
}
void DragDropDelegate::OnDragExited() {
DCHECK(in_drag_);
tree_client_->OnDragLeave(transport_window_id_);
EndDrag();
}
int DragDropDelegate::OnPerformDrop(const ui::DropTargetEvent& event) {
DCHECK(in_drag_);
tree_client_->OnCompleteDrop(transport_window_id_, event.flags(),
ToScreenLocation(window_, event.location()),
event.source_operations(), base::DoNothing());
EndDrag();
// Returns a drop action derived from |last_drag_operations_| because it is
// not safe to hold the stack and wait for the mojo to return the actual one.
if (last_drag_operations_ == ui::DragDropTypes::DRAG_NONE)
return ui::DragDropTypes::DRAG_NONE;
return (last_drag_operations_ & ui::DragDropTypes::DRAG_MOVE)
? ui::DragDropTypes::DRAG_MOVE
: ui::DragDropTypes::DRAG_COPY;
}
void DragDropDelegate::StartDrag(const ui::DropTargetEvent& event) {
DCHECK(!in_drag_);
in_drag_ = true;
tree_client_->OnDragDropStart(mojo::MapToFlatMap(GetDragData(event.data())));
}
void DragDropDelegate::EndDrag() {
DCHECK(in_drag_);
in_drag_ = false;
tree_client_->OnDragDropDone();
}
void DragDropDelegate::UpdateDragOperations(uint32_t drag_operations) {
last_drag_operations_ = drag_operations;
}
} // namespace ws2
} // namespace ui
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_UI_WS2_DRAG_DROP_DELEGATE_H_
#define SERVICES_UI_WS2_DRAG_DROP_DELEGATE_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "services/ui/ws2/ids.h"
#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/base/dragdrop/drag_drop_types.h"
namespace ui {
namespace ws2 {
// A delegate to forward drag and drop events to a remote client window via
// mojom::WindowTreeClient.
class DragDropDelegate : public aura::client::DragDropDelegate {
public:
DragDropDelegate(mojom::WindowTreeClient* window_tree_client,
aura::Window* window,
Id transport_window_id);
~DragDropDelegate() override;
// aura::client::DragDropDelegate:
void OnDragEntered(const ui::DropTargetEvent& event) override;
int OnDragUpdated(const ui::DropTargetEvent& event) override;
void OnDragExited() override;
int OnPerformDrop(const ui::DropTargetEvent& event) override;
private:
void StartDrag(const ui::DropTargetEvent& event);
void EndDrag();
// Callback invoked to update |last_drag_operations_|.
void UpdateDragOperations(uint32_t drag_operations);
mojom::WindowTreeClient* const tree_client_;
aura::Window* const window_;
const Id transport_window_id_;
// Whether a drag is over |window_|.
bool in_drag_ = false;
// Cached drag operations as a workaround to return drag operations for
// synchronous OnDragUpdated.
uint32_t last_drag_operations_ = ui::DragDropTypes::DRAG_NONE;
base::WeakPtrFactory<DragDropDelegate> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DragDropDelegate);
};
} // namespace ws2
} // namespace ui
#endif // SERVICES_UI_WS2_DRAG_DROP_DELEGATE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/ui/ws2/drag_drop_delegate.h"
#include <memory>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/map.h"
#include "services/ui/ws2/test_change_tracker.h"
#include "services/ui/ws2/window_service_test_setup.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/mus/os_exchange_data_provider_mus.h"
#include "ui/aura/window.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/file_info.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/default_screen_position_client.h"
#include "url/gurl.h"
namespace ui {
// An equal-to operator to make EXPECT_EQ happy.
bool operator==(const FileInfo& info1, const FileInfo& info2) {
return info1.path == info2.path && info1.display_name == info2.display_name;
}
namespace ws2 {
class DragDropDelegateTest : public testing::Test {
public:
DragDropDelegateTest() = default;
~DragDropDelegateTest() override = default;
// testing::Test
void SetUp() override {
window_ = window_tree_test_helper()->NewTopLevelWindow();
aura::client::SetScreenPositionClient(window_->GetRootWindow(),
&screen_position_client_);
}
void SetCanAcceptDrops(bool accepts_drops) {
window_tree_test_helper()->window_tree()->SetCanAcceptDrops(
window_tree_test_helper()->TransportIdForWindow(window_),
accepts_drops);
}
// Simulates drag starts with |data| at given |location| in |window_|. The
// drag is updated in UpdateDrag call before and should be completed with
// either PerformDrop or CancelDrag.
void StartDrag(const ui::OSExchangeData& data, const gfx::Point& location) {
DCHECK_EQ(nullptr, drag_data_);
drag_data_ = &data;
delegate()->OnDragEntered(ui::DropTargetEvent(
*drag_data_, location, location, ui::DragDropTypes::DRAG_MOVE));
}
// Simulates drag moves at given |location| in |window_|.
void UpdateDrag(const gfx::Point& location) {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnDragUpdated(ui::DropTargetEvent(
*drag_data_, location, location, ui::DragDropTypes::DRAG_MOVE));
}
// Simulates drag finished with a drop at |location|.
void PerformDrop(const gfx::Point& location) {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnPerformDrop(ui::DropTargetEvent(
*drag_data_, location, location, ui::DragDropTypes::DRAG_MOVE));
drag_data_ = nullptr;
}
// Simulates a drag is canceled.
void EndDrag() {
DCHECK_NE(nullptr, drag_data_);
delegate()->OnDragExited();
drag_data_ = nullptr;
}
// Triggers a WindowTreeClient::OnDragDropStart and returns drag data.
using DragDataType = aura::OSExchangeDataProviderMus::Data;
DragDataType GetDragData(const ui::OSExchangeData& data) {
// A point in |window()|'s coordinates.
gfx::Point point = gfx::Rect(window()->bounds().size()).CenterPoint();
changes()->clear();
StartDrag(data, point);
EndDrag();
const Change& first_change = changes()->front();
DCHECK_EQ(CHANGE_TYPE_DRAG_DROP_START, first_change.type);
return mojo::FlatMapToMap(first_change.drag_data);
}
aura::client::DragDropDelegate* delegate() {
return aura::client::GetDragDropDelegate(window_);
}
aura::Window* window() { return window_; }
WindowTreeTestHelper* window_tree_test_helper() {
return setup_.window_tree_test_helper();
}
std::vector<Change>* changes() { return setup_.changes(); }
private:
wm::DefaultScreenPositionClient screen_position_client_;
WindowServiceTestSetup setup_;
aura::Window* window_ = nullptr;
const ui::OSExchangeData* drag_data_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(DragDropDelegateTest);
};
// Tests that DragDropDelegate is created when window can accept drops and
// destroyed otherwise.
TEST_F(DragDropDelegateTest, CreateAndReset) {
// No DragDropDelegate by default.
EXPECT_FALSE(delegate());
// DragDropDelegate is created when the window accepts drops.
SetCanAcceptDrops(true);
EXPECT_TRUE(delegate());
// DragDropDelegate is gone when the window accepts drops.
SetCanAcceptDrops(false);
EXPECT_FALSE(delegate());
}
// Tests that the window tree client gets correct drag data.
TEST_F(DragDropDelegateTest, DragData) {
SetCanAcceptDrops(true);
// String data.
{
const base::string16 kTestString = base::ASCIIToUTF16("dragged string");
ui::OSExchangeData data;
data.SetString(kTestString);
aura::OSExchangeDataProviderMus mus_provider(GetDragData(data));
base::string16 dropped_string;
EXPECT_TRUE(mus_provider.GetString(&dropped_string));
EXPECT_EQ(kTestString, dropped_string);
}
// URL data.
{
const GURL kTestURL("http://test.com");
const base::string16 kTestTitle = base::ASCIIToUTF16("test title");
ui::OSExchangeData data;
data.SetURL(kTestURL, kTestTitle);
aura::OSExchangeDataProviderMus mus_provider(GetDragData(data));
GURL dropped_url;
base::string16 dropped_title;
EXPECT_TRUE(mus_provider.GetURLAndTitle(
ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &dropped_url,
&dropped_title));
EXPECT_EQ(kTestURL, dropped_url);
EXPECT_EQ(kTestTitle, dropped_title);
}
#if !defined(OS_WIN)
// File names.
// Exclude from Windows because OSExchangeDataProviderWin works in a different
// way and does not return the exactly the same filenames as the ones being
// set.
{
// No "display_name" since OSExchangeDataProviderMus does not support it.
const std::vector<FileInfo> kTestFilenames = {
{base::FilePath(FILE_PATH_LITERAL("/tmp/test_file1")),
base::FilePath()},
{base::FilePath(FILE_PATH_LITERAL("/tmp/test_file2")),
base::FilePath()},
};
ui::OSExchangeData data;
data.SetFilenames(kTestFilenames);
aura::OSExchangeDataProviderMus mus_provider(GetDragData(data));
std::vector<FileInfo> dropped_filenames;
EXPECT_TRUE(mus_provider.GetFilenames(&dropped_filenames));
EXPECT_EQ(kTestFilenames, dropped_filenames);
}
#endif
// HTML
{
const GURL kTestURL("http://test.com");
const base::string16 kTestHtml = base::ASCIIToUTF16(
"<HTML>\n<BODY>\n"
"<b>bold.</b> <i><b>This is bold italic.</b></i>\n"
"</BODY>\n</HTML>");
ui::OSExchangeData data;
data.SetHtml(kTestHtml, kTestURL);
aura::OSExchangeDataProviderMus mus_provider(GetDragData(data));
base::string16 dropped_html;
GURL dropped_url;
EXPECT_TRUE(mus_provider.GetHtml(&dropped_html, &dropped_url));
EXPECT_EQ(kTestHtml, dropped_html);
// Not testing url because OSExchangeDataProviderMus does not support it.
}
}
// Tests the window tree client sequence of drag enter and exit.
TEST_F(DragDropDelegateTest, EnterAndExit) {
SetCanAcceptDrops(true);
ui::OSExchangeData data;
data.SetString(base::ASCIIToUTF16("dragged string"));
// A point in |window()|'s coordinates.
gfx::Point point = gfx::Rect(window()->bounds().size()).CenterPoint();
changes()->clear();
StartDrag(data, point);
UpdateDrag(point);
EndDrag();
EXPECT_EQ(
std::vector<std::string>({"DragDropStart", "DragEnter window_id=0,1",
"DragOver window_id=0,1",
"DragLeave window_id=0,1", "DragDropDone"}),
ChangesToDescription1(*changes()));
}
// Tests the window tree client sequence of drag enter and drop.
TEST_F(DragDropDelegateTest, EnterAndDrop) {
SetCanAcceptDrops(true);
ui::OSExchangeData data;
data.SetString(base::ASCIIToUTF16("dragged string"));
// A point in |window()|'s coordinates.
gfx::Point point = gfx::Rect(window()->bounds().size()).CenterPoint();
changes()->clear();
StartDrag(data, point);
UpdateDrag(point);
PerformDrop(point);
EXPECT_EQ(
std::vector<std::string>({"DragDropStart", "DragEnter window_id=0,1",
"DragOver window_id=0,1",
"CompleteDrop window_id=0,1", "DragDropDone"}),
ChangesToDescription1(*changes()));
}
} // namespace ws2
} // namespace ui
......@@ -4,8 +4,11 @@
#include "services/ui/ws2/server_window.h"
#include <utility>
#include "base/containers/flat_map.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "services/ui/ws2/drag_drop_delegate.h"
#include "services/ui/ws2/embedding.h"
#include "services/ui/ws2/window_tree.h"
#include "ui/aura/client/capture_client_observer.h"
......@@ -473,6 +476,11 @@ bool ServerWindow::IsTopLevel() const {
return owning_window_tree_ && owning_window_tree_->IsTopLevel(window_);
}
void ServerWindow::SetDragDropDelegate(
std::unique_ptr<DragDropDelegate> drag_drop_delegate) {
drag_drop_delegate_ = std::move(drag_drop_delegate);
}
void ServerWindow::AttachCompositorFrameSink(
viz::mojom::CompositorFrameSinkRequest compositor_frame_sink,
viz::mojom::CompositorFrameSinkClientPtr client) {
......
......@@ -27,6 +27,7 @@ class EventHandler;
namespace ws2 {
class DragDropDelegate;
class Embedding;
class WindowTree;
......@@ -105,6 +106,12 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) ServerWindow {
return local_surface_id_;
}
bool HasDragDropDelegate() const {
return drag_drop_delegate_.get() != nullptr;
}
void SetDragDropDelegate(
std::unique_ptr<DragDropDelegate> drag_drop_delegate);
private:
friend class ServerWindowTestHelper;
......@@ -158,6 +165,8 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) ServerWindow {
base::Optional<viz::LocalSurfaceId> local_surface_id_;
std::unique_ptr<DragDropDelegate> drag_drop_delegate_;
DISALLOW_COPY_AND_ASSIGN(ServerWindow);
};
......
......@@ -159,6 +159,22 @@ std::string ChangeToDescription(const Change& change,
case CHANGE_TYPE_TRANSFORM_CHANGED:
return base::StringPrintf("TransformChanged window_id=%s",
WindowIdToString(change.window_id).c_str());
case CHANGE_TYPE_DRAG_DROP_START:
return "DragDropStart";
case CHANGE_TYPE_DRAG_ENTER:
return base::StringPrintf("DragEnter window_id=%s",
WindowIdToString(change.window_id).c_str());
case CHANGE_TYPE_DRAG_OVER:
return base::StringPrintf("DragOver window_id=%s",
WindowIdToString(change.window_id).c_str());
case CHANGE_TYPE_DRAG_LEAVE:
return base::StringPrintf("DragLeave window_id=%s",
WindowIdToString(change.window_id).c_str());
case CHANGE_TYPE_COMPLETE_DROP:
return base::StringPrintf("CompleteDrop window_id=%s",
WindowIdToString(change.window_id).c_str());
case CHANGE_TYPE_DRAG_DROP_DONE:
return "DragDropDone";
}
return std::string();
}
......@@ -500,6 +516,48 @@ void TestChangeTracker::OnWindowSurfaceChanged(
AddChange(change);
}
void TestChangeTracker::OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& drag_data) {
Change change;
change.type = CHANGE_TYPE_DRAG_DROP_START;
change.drag_data = drag_data;
AddChange(change);
}
void TestChangeTracker::OnDragEnter(Id window_id) {
Change change;
change.type = CHANGE_TYPE_DRAG_ENTER;
change.window_id = window_id;
AddChange(change);
}
void TestChangeTracker::OnDragOver(Id window_id) {
Change change;
change.type = CHANGE_TYPE_DRAG_OVER;
change.window_id = window_id;
AddChange(change);
}
void TestChangeTracker::OnDragLeave(Id window_id) {
Change change;
change.type = CHANGE_TYPE_DRAG_LEAVE;
change.window_id = window_id;
AddChange(change);
}
void TestChangeTracker::OnCompleteDrop(Id window_id) {
Change change;
change.type = CHANGE_TYPE_COMPLETE_DROP;
change.window_id = window_id;
AddChange(change);
}
void TestChangeTracker::OnDragDropDone() {
Change change;
change.type = CHANGE_TYPE_DRAG_DROP_DONE;
AddChange(change);
}
void TestChangeTracker::RequestClose(Id window_id) {
Change change;
change.type = CHANGE_TYPE_REQUEST_CLOSE;
......
......@@ -48,6 +48,12 @@ enum ChangeType {
CHANGE_TYPE_REQUEST_CLOSE,
CHANGE_TYPE_SURFACE_CHANGED,
CHANGE_TYPE_TRANSFORM_CHANGED,
CHANGE_TYPE_DRAG_DROP_START,
CHANGE_TYPE_DRAG_ENTER,
CHANGE_TYPE_DRAG_OVER,
CHANGE_TYPE_DRAG_LEAVE,
CHANGE_TYPE_COMPLETE_DROP,
CHANGE_TYPE_DRAG_DROP_DONE,
};
// TODO(sky): consider nuking and converting directly to WindowData.
......@@ -104,6 +110,7 @@ struct Change {
int64_t display_id;
gfx::Point location1;
gfx::PointF location2;
base::flat_map<std::string, std::vector<uint8_t>> drag_data;
};
// The ChangeToDescription related functions convert a Change into a string.
......@@ -212,6 +219,13 @@ class TestChangeTracker {
bool drawn);
void OnWindowSurfaceChanged(Id window_id,
const viz::SurfaceInfo& surface_info);
void OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& drag_data);
void OnDragEnter(Id window_id);
void OnDragOver(Id window_id);
void OnDragLeave(Id widnow_id);
void OnCompleteDrop(Id window_id);
void OnDragDropDone();
void RequestClose(Id window_id);
private:
......
......@@ -237,40 +237,52 @@ void TestWindowTreeClient::OnWindowCursorChanged(Id window_id,
tracker_.OnWindowCursorChanged(window_id, cursor);
}
void TestWindowTreeClient::OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& drag_data) {}
void TestWindowTreeClient::OnWindowSurfaceChanged(
Id window_id,
const viz::SurfaceInfo& surface_info) {
tracker_.OnWindowSurfaceChanged(window_id, surface_info);
}
void TestWindowTreeClient::OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& drag_data) {
tracker_.OnDragDropStart(drag_data);
}
void TestWindowTreeClient::OnDragEnter(Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
OnDragEnterCallback callback) {}
OnDragEnterCallback callback) {
tracker_.OnDragEnter(window);
}
void TestWindowTreeClient::OnDragOver(Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
OnDragOverCallback callback) {}
OnDragOverCallback callback) {
tracker_.OnDragOver(window);
}
void TestWindowTreeClient::OnDragLeave(Id window) {}
void TestWindowTreeClient::OnDragLeave(Id window) {
tracker_.OnDragLeave(window);
}
void TestWindowTreeClient::OnCompleteDrop(Id window,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
OnCompleteDropCallback callback) {}
OnCompleteDropCallback callback) {
tracker_.OnCompleteDrop(window);
}
void TestWindowTreeClient::OnPerformDragDropCompleted(uint32_t change_id,
bool success,
uint32_t action_taken) {}
void TestWindowTreeClient::OnDragDropDone() {}
void TestWindowTreeClient::OnDragDropDone() {
tracker_.OnDragDropDone();
}
void TestWindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
tracker_.OnChangeCompleted(change_id, success);
......
......@@ -158,10 +158,10 @@ class TestWindowTreeClient : public mojom::WindowTreeClient,
const base::Optional<std::vector<uint8_t>>& new_data) override;
void OnWindowFocused(Id focused_window_id) override;
void OnWindowCursorChanged(Id window_id, ui::CursorData cursor) override;
void OnDragDropStart(const base::flat_map<std::string, std::vector<uint8_t>>&
drag_data) override;
void OnWindowSurfaceChanged(Id window_id,
const viz::SurfaceInfo& surface_info) override;
void OnDragDropStart(const base::flat_map<std::string, std::vector<uint8_t>>&
drag_data) override;
void OnDragEnter(Id window,
uint32_t key_state,
const gfx::Point& position,
......
......@@ -16,6 +16,7 @@
#include "services/ui/ws2/client_change.h"
#include "services/ui/ws2/client_change_tracker.h"
#include "services/ui/ws2/client_root.h"
#include "services/ui/ws2/drag_drop_delegate.h"
#include "services/ui/ws2/embedding.h"
#include "services/ui/ws2/pointer_watcher.h"
#include "services/ui/ws2/server_window.h"
......@@ -1117,7 +1118,27 @@ void WindowTree::SetHitTestMask(Id window_id,
}
void WindowTree::SetCanAcceptDrops(Id window_id, bool accepts_drops) {
NOTIMPLEMENTED_LOG_ONCE();
aura::Window* window = GetWindowByTransportId(window_id);
if (!window) {
DVLOG(1) << "SetCanAcceptDrops failed (no window)";
return;
}
if (!IsClientCreatedWindow(window)) {
DVLOG(1) << "SetCanAcceptDrops failed (access denied)";
return;
}
ServerWindow* server_window = ServerWindow::GetMayBeNull(window);
DCHECK(server_window); // Must exist because of preceeding conditionals.
if (accepts_drops && !server_window->HasDragDropDelegate()) {
auto drag_drop_delegate = std::make_unique<DragDropDelegate>(
window_tree_client_, window, window_id);
aura::client::SetDragDropDelegate(window, drag_drop_delegate.get());
server_window->SetDragDropDelegate(std::move(drag_drop_delegate));
} else if (!accepts_drops && server_window->HasDragDropDelegate()) {
aura::client::SetDragDropDelegate(window, nullptr);
server_window->SetDragDropDelegate(nullptr);
}
}
void WindowTree::SetWindowVisibility(uint32_t change_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment