Android: Get rid of extra dup()s on launching child processes
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_drop_target_win.cc
blobf10fc1fc34b3b4e2573478c1710c62cb0ae84f91
1 // Copyright (c) 2011 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_drop_target_win.h"
7 #include "base/metrics/histogram.h"
8 #include "base/win/win_util.h"
9 #include "ui/aura/window.h"
10 #include "ui/aura/window_tree_host.h"
11 #include "ui/base/dragdrop/drag_drop_types.h"
12 #include "ui/base/dragdrop/drop_target_event.h"
13 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/wm/public/drag_drop_client.h"
16 #include "ui/wm/public/drag_drop_delegate.h"
18 using aura::client::DragDropClient;
19 using aura::client::DragDropDelegate;
20 using ui::OSExchangeData;
21 using ui::OSExchangeDataProviderWin;
23 namespace views {
25 DesktopDropTargetWin::DesktopDropTargetWin(aura::Window* root_window,
26 HWND window)
27 : ui::DropTargetWin(window),
28 root_window_(root_window),
29 target_window_(NULL) {
32 DesktopDropTargetWin::~DesktopDropTargetWin() {
33 if (target_window_)
34 target_window_->RemoveObserver(this);
37 DWORD DesktopDropTargetWin::OnDragEnter(IDataObject* data_object,
38 DWORD key_state,
39 POINT position,
40 DWORD effect) {
41 scoped_ptr<OSExchangeData> data;
42 scoped_ptr<ui::DropTargetEvent> event;
43 DragDropDelegate* delegate;
44 // Translate will call OnDragEntered.
45 Translate(data_object, key_state, position, effect, &data, &event, &delegate);
46 return ui::DragDropTypes::DragOperationToDropEffect(
47 ui::DragDropTypes::DRAG_NONE);
50 DWORD DesktopDropTargetWin::OnDragOver(IDataObject* data_object,
51 DWORD key_state,
52 POINT position,
53 DWORD effect) {
54 int drag_operation = ui::DragDropTypes::DRAG_NONE;
55 scoped_ptr<OSExchangeData> data;
56 scoped_ptr<ui::DropTargetEvent> event;
57 DragDropDelegate* delegate;
58 Translate(data_object, key_state, position, effect, &data, &event, &delegate);
59 if (delegate)
60 drag_operation = delegate->OnDragUpdated(*event);
61 return ui::DragDropTypes::DragOperationToDropEffect(drag_operation);
64 void DesktopDropTargetWin::OnDragLeave(IDataObject* data_object) {
65 NotifyDragLeave();
68 DWORD DesktopDropTargetWin::OnDrop(IDataObject* data_object,
69 DWORD key_state,
70 POINT position,
71 DWORD effect) {
72 int drag_operation = ui::DragDropTypes::DRAG_NONE;
73 scoped_ptr<OSExchangeData> data;
74 scoped_ptr<ui::DropTargetEvent> event;
75 DragDropDelegate* delegate;
76 Translate(data_object, key_state, position, effect, &data, &event, &delegate);
77 if (delegate) {
78 drag_operation = delegate->OnPerformDrop(*event);
79 DragDropClient* client = aura::client::GetDragDropClient(root_window_);
80 if (client && !client->IsDragDropInProgress() &&
81 drag_operation != ui::DragDropTypes::DRAG_NONE) {
82 UMA_HISTOGRAM_COUNTS("Event.DragDrop.ExternalOriginDrop", 1);
85 if (target_window_) {
86 target_window_->RemoveObserver(this);
87 target_window_ = NULL;
89 return ui::DragDropTypes::DragOperationToDropEffect(drag_operation);
92 void DesktopDropTargetWin::OnWindowDestroyed(aura::Window* window) {
93 DCHECK(window == target_window_);
94 target_window_ = NULL;
97 void DesktopDropTargetWin::Translate(
98 IDataObject* data_object,
99 DWORD key_state,
100 POINT position,
101 DWORD effect,
102 scoped_ptr<OSExchangeData>* data,
103 scoped_ptr<ui::DropTargetEvent>* event,
104 DragDropDelegate** delegate) {
105 gfx::Point location(position.x, position.y);
106 gfx::Point root_location = location;
107 root_window_->GetHost()->ConvertPointFromNativeScreen(
108 &root_location);
109 aura::Window* target_window =
110 root_window_->GetEventHandlerForPoint(root_location);
111 bool target_window_changed = false;
112 if (target_window != target_window_) {
113 if (target_window_)
114 NotifyDragLeave();
115 target_window_ = target_window;
116 if (target_window_)
117 target_window_->AddObserver(this);
118 target_window_changed = true;
120 *delegate = NULL;
121 if (!target_window_)
122 return;
123 *delegate = aura::client::GetDragDropDelegate(target_window_);
124 if (!*delegate)
125 return;
127 data->reset(new OSExchangeData(new OSExchangeDataProviderWin(data_object)));
128 location = root_location;
129 aura::Window::ConvertPointToTarget(root_window_, target_window_, &location);
130 event->reset(new ui::DropTargetEvent(
131 *(data->get()),
132 location,
133 root_location,
134 ui::DragDropTypes::DropEffectToDragOperation(effect)));
135 int flags = 0;
136 flags |= base::win::IsAltPressed() ? ui::EF_ALT_DOWN : ui::EF_NONE;
137 flags |= base::win::IsShiftPressed() ? ui::EF_SHIFT_DOWN : ui::EF_NONE;
138 flags |= base::win::IsCtrlPressed() ? ui::EF_CONTROL_DOWN : ui::EF_NONE;
139 (*event)->set_flags(flags);
140 if (target_window_changed)
141 (*delegate)->OnDragEntered(*event->get());
144 void DesktopDropTargetWin::NotifyDragLeave() {
145 if (!target_window_)
146 return;
147 DragDropDelegate* delegate =
148 aura::client::GetDragDropDelegate(target_window_);
149 if (delegate)
150 delegate->OnDragExited();
151 target_window_->RemoveObserver(this);
152 target_window_ = NULL;
155 } // namespace views