Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_drag_drop_client_win.cc
blob8afa69bdcbfd2055274f650445393b66e2041f8d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "base/tracked_objects.h"
9 #include "ui/base/dragdrop/drag_drop_types.h"
10 #include "ui/base/dragdrop/drag_source_win.h"
11 #include "ui/base/dragdrop/drop_target_event.h"
12 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
13 #include "ui/views/widget/desktop_aura/desktop_drop_target_win.h"
14 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
16 namespace views {
18 DesktopDragDropClientWin::DesktopDragDropClientWin(
19 aura::Window* root_window,
20 HWND window)
21 : drag_drop_in_progress_(false),
22 drag_operation_(0),
23 weak_factory_(this) {
24 drop_target_ = new DesktopDropTargetWin(root_window, window);
27 DesktopDragDropClientWin::~DesktopDragDropClientWin() {
28 if (drag_drop_in_progress_)
29 DragCancel();
32 int DesktopDragDropClientWin::StartDragAndDrop(
33 const ui::OSExchangeData& data,
34 aura::Window* root_window,
35 aura::Window* source_window,
36 const gfx::Point& screen_location,
37 int operation,
38 ui::DragDropTypes::DragEventSource source) {
39 drag_drop_in_progress_ = true;
40 drag_operation_ = operation;
42 base::WeakPtr<DesktopDragDropClientWin> alive(weak_factory_.GetWeakPtr());
44 drag_source_ = Microsoft::WRL::Make<ui::DragSourceWin>();
45 Microsoft::WRL::ComPtr<ui::DragSourceWin> drag_source_copy = drag_source_;
46 drag_source_copy->set_data(&data);
47 ui::OSExchangeDataProviderWin::GetDataObjectImpl(data)
48 ->set_in_drag_loop(true);
50 DWORD effect;
52 UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Start", source,
53 ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
55 // Use task stopwatch to exclude the drag-drop time current task, if any.
56 tracked_objects::TaskStopwatch stopwatch;
57 stopwatch.Start();
58 HRESULT result = DoDragDrop(
59 ui::OSExchangeDataProviderWin::GetIDataObject(data), drag_source_.Get(),
60 ui::DragDropTypes::DragOperationToDropEffect(operation), &effect);
61 stopwatch.Stop();
62 drag_source_copy->set_data(nullptr);
64 if (alive)
65 drag_drop_in_progress_ = false;
67 if (result != DRAGDROP_S_DROP)
68 effect = DROPEFFECT_NONE;
70 int drag_operation = ui::DragDropTypes::DropEffectToDragOperation(effect);
72 if (drag_operation == ui::DragDropTypes::DRAG_NONE) {
73 UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Cancel", source,
74 ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
75 } else {
76 UMA_HISTOGRAM_ENUMERATION("Event.DragDrop.Drop", source,
77 ui::DragDropTypes::DRAG_EVENT_SOURCE_COUNT);
80 return drag_operation;
83 void DesktopDragDropClientWin::DragUpdate(aura::Window* target,
84 const ui::LocatedEvent& event) {
87 void DesktopDragDropClientWin::Drop(aura::Window* target,
88 const ui::LocatedEvent& event) {
91 void DesktopDragDropClientWin::DragCancel() {
92 drag_source_->CancelDrag();
93 drag_operation_ = 0;
96 bool DesktopDragDropClientWin::IsDragDropInProgress() {
97 return drag_drop_in_progress_;
100 void DesktopDragDropClientWin::OnNativeWidgetDestroying(HWND window) {
101 if (drop_target_.get()) {
102 RevokeDragDrop(window);
103 drop_target_ = NULL;
107 } // namespace views