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

Side by Side Diff: ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc

Issue 17029020: linux_aura: Redo how memory is handled in clipboard/drag code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes for sky; ptal Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" 5 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
6 6
7 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
8 8
9 #include "base/event_types.h" 9 #include "base/event_types.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 152
153 // Called to request the next target from the source window. This is only 153 // Called to request the next target from the source window. This is only
154 // done on the first XdndPosition; after that, we cache the data offered by 154 // done on the first XdndPosition; after that, we cache the data offered by
155 // the source window. 155 // the source window.
156 void RequestNextTarget(); 156 void RequestNextTarget();
157 157
158 // Called when XSelection data has been copied to our process. 158 // Called when XSelection data has been copied to our process.
159 void OnSelectionNotify(const XSelectionEvent& xselection); 159 void OnSelectionNotify(const XSelectionEvent& xselection);
160 160
161 // Clones the fetched targets. 161 // Clones the fetched targets.
162 scoped_ptr<ui::SelectionFormatMap> CloneFetchedTargets() { 162 const ui::SelectionFormatMap& fetched_targets() { return fetched_targets_; }
163 DCHECK(fetched_targets_);
164 return fetched_targets_->Clone();
165 }
166 163
167 // Reads the "XdndActionList" property from |source_window| and copies it 164 // Reads the "XdndActionList" property from |source_window| and copies it
168 // into |actions|. 165 // into |actions|.
169 void ReadActions(); 166 void ReadActions();
170 167
171 // Creates a ui::DragDropTypes::DragOperation representation of the current 168 // Creates a ui::DragDropTypes::DragOperation representation of the current
172 // action list. 169 // action list.
173 int GetDragOperation() const; 170 int GetDragOperation() const;
174 171
175 private: 172 private:
(...skipping 13 matching lines...) Expand all
189 DesktopDragDropClientAuraX11* drag_drop_client_; 186 DesktopDragDropClientAuraX11* drag_drop_client_;
190 187
191 // Whether we're blocking the handling of an XdndPosition message by waiting 188 // Whether we're blocking the handling of an XdndPosition message by waiting
192 // for |unfetched_targets_| to be fetched. 189 // for |unfetched_targets_| to be fetched.
193 bool waiting_to_handle_position_; 190 bool waiting_to_handle_position_;
194 191
195 // Where the cursor is on screen. 192 // Where the cursor is on screen.
196 gfx::Point screen_point_; 193 gfx::Point screen_point_;
197 194
198 // A SelectionFormatMap of data that we have in our process. 195 // A SelectionFormatMap of data that we have in our process.
199 scoped_ptr<ui::SelectionFormatMap> fetched_targets_; 196 ui::SelectionFormatMap fetched_targets_;
200 197
201 // The names of various data types offered by the other window that we 198 // The names of various data types offered by the other window that we
202 // haven't fetched and put in |fetched_targets_| yet. 199 // haven't fetched and put in |fetched_targets_| yet.
203 std::vector<Atom> unfetched_targets_; 200 std::vector<Atom> unfetched_targets_;
204 201
205 // Possible actions. 202 // Possible actions.
206 std::vector<Atom> actions_; 203 std::vector<Atom> actions_;
207 204
208 DISALLOW_COPY_AND_ASSIGN(X11DragContext); 205 DISALLOW_COPY_AND_ASSIGN(X11DragContext);
209 }; 206 };
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 XSelectInput(base::MessagePumpAuraX11::GetDefaultXDisplay(), 241 XSelectInput(base::MessagePumpAuraX11::GetDefaultXDisplay(),
245 source_window_, PropertyChangeMask); 242 source_window_, PropertyChangeMask);
246 243
247 // We must perform a full sync here because we could be racing 244 // We must perform a full sync here because we could be racing
248 // |source_window_|. 245 // |source_window_|.
249 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), False); 246 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), False);
250 } else { 247 } else {
251 // This drag originates from an aura window within our process. This means 248 // This drag originates from an aura window within our process. This means
252 // that we can shortcut the X11 server and ask the owning SelectionOwner 249 // that we can shortcut the X11 server and ask the owning SelectionOwner
253 // for the data it's offering. 250 // for the data it's offering.
254 fetched_targets_ = client->CloneFormatMap(); 251 fetched_targets_ = client->GetFormatMap();
255 unfetched_targets_.clear(); 252 unfetched_targets_.clear();
256 } 253 }
257 254
258 ReadActions(); 255 ReadActions();
259 } 256 }
260 257
261 DesktopDragDropClientAuraX11::X11DragContext::~X11DragContext() { 258 DesktopDragDropClientAuraX11::X11DragContext::~X11DragContext() {
262 DesktopDragDropClientAuraX11* client = 259 DesktopDragDropClientAuraX11* client =
263 DesktopDragDropClientAuraX11::GetForWindow(source_window_); 260 DesktopDragDropClientAuraX11::GetForWindow(source_window_);
264 if (!client) { 261 if (!client) {
265 // Unsubscribe from message events. 262 // Unsubscribe from message events.
266 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow( 263 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(
267 source_window_); 264 source_window_);
268 } 265 }
269 } 266 }
270 267
271 void DesktopDragDropClientAuraX11::X11DragContext::OnStartXdndPositionMessage( 268 void DesktopDragDropClientAuraX11::X11DragContext::OnStartXdndPositionMessage(
272 DesktopDragDropClientAuraX11* client, 269 DesktopDragDropClientAuraX11* client,
273 ::Window source_window, 270 ::Window source_window,
274 const gfx::Point& screen_point) { 271 const gfx::Point& screen_point) {
275 DCHECK_EQ(source_window_, source_window); 272 DCHECK_EQ(source_window_, source_window);
276 273
277 if (!unfetched_targets_.empty()) { 274 if (!unfetched_targets_.empty()) {
278 // We have unfetched targets. That means we need to pause the handling of 275 // We have unfetched targets. That means we need to pause the handling of
279 // the position message and ask the other window for its data. 276 // the position message and ask the other window for its data.
280 screen_point_ = screen_point; 277 screen_point_ = screen_point;
281 drag_drop_client_ = client; 278 drag_drop_client_ = client;
282 waiting_to_handle_position_ = true; 279 waiting_to_handle_position_ = true;
283 280
284 fetched_targets_.reset(new ui::SelectionFormatMap); 281 fetched_targets_ = ui::SelectionFormatMap();
285 RequestNextTarget(); 282 RequestNextTarget();
286 } else { 283 } else {
287 client->CompleteXdndPosition(source_window, screen_point); 284 client->CompleteXdndPosition(source_window, screen_point);
288 } 285 }
289 } 286 }
290 287
291 void DesktopDragDropClientAuraX11::X11DragContext::RequestNextTarget() { 288 void DesktopDragDropClientAuraX11::X11DragContext::RequestNextTarget() {
292 ::Atom target = unfetched_targets_.back(); 289 ::Atom target = unfetched_targets_.back();
293 unfetched_targets_.pop_back(); 290 unfetched_targets_.pop_back();
294 291
295 XConvertSelection(base::MessagePumpAuraX11::GetDefaultXDisplay(), 292 XConvertSelection(base::MessagePumpAuraX11::GetDefaultXDisplay(),
296 atom_cache_->GetAtom(kXdndSelection), 293 atom_cache_->GetAtom(kXdndSelection),
297 target, 294 target,
298 atom_cache_->GetAtom(kChromiumDragReciever), 295 atom_cache_->GetAtom(kChromiumDragReciever),
299 local_window_, 296 local_window_,
300 CurrentTime); 297 CurrentTime);
301 } 298 }
302 299
303 void DesktopDragDropClientAuraX11::X11DragContext::OnSelectionNotify( 300 void DesktopDragDropClientAuraX11::X11DragContext::OnSelectionNotify(
304 const XSelectionEvent& event) { 301 const XSelectionEvent& event) {
305 DCHECK(waiting_to_handle_position_); 302 DCHECK(waiting_to_handle_position_);
306 DCHECK(drag_drop_client_); 303 DCHECK(drag_drop_client_);
307 DCHECK_EQ(event.property, atom_cache_->GetAtom(kChromiumDragReciever)); 304 DCHECK_EQ(event.property, atom_cache_->GetAtom(kChromiumDragReciever));
308 305
309 unsigned char* data = NULL; 306 scoped_refptr<base::RefCountedMemory> data;
310 size_t data_bytes = 0;
311 ::Atom type = None; 307 ::Atom type = None;
312 if (ui::GetRawBytesOfProperty(local_window_, event.property, 308 if (ui::GetRawBytesOfProperty(local_window_, event.property,
313 &data, &data_bytes, NULL, &type)) { 309 &data, NULL, NULL, &type)) {
314 char* copied_data = new char[data_bytes]; 310 fetched_targets_.Insert(event.target, data);
315 memcpy(copied_data, data, data_bytes);
316 fetched_targets_->Insert(event.target, copied_data, data_bytes);
317 XFree(data);
318 } 311 }
319 312
320 if (!unfetched_targets_.empty()) { 313 if (!unfetched_targets_.empty()) {
321 RequestNextTarget(); 314 RequestNextTarget();
322 } else { 315 } else {
323 waiting_to_handle_position_ = false; 316 waiting_to_handle_position_ = false;
324 drag_drop_client_->CompleteXdndPosition(source_window_, screen_point_); 317 drag_drop_client_->CompleteXdndPosition(source_window_, screen_point_);
325 drag_drop_client_ = NULL; 318 drag_drop_client_ = NULL;
326 } 319 }
327 } 320 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 DVLOG(1) << "XdndDrop"; 503 DVLOG(1) << "XdndDrop";
511 504
512 unsigned long source_window = event.data.l[0]; 505 unsigned long source_window = event.data.l[0];
513 506
514 int drag_operation = ui::DragDropTypes::DRAG_NONE; 507 int drag_operation = ui::DragDropTypes::DRAG_NONE;
515 if (target_window_) { 508 if (target_window_) {
516 aura::client::DragDropDelegate* delegate = 509 aura::client::DragDropDelegate* delegate =
517 aura::client::GetDragDropDelegate(target_window_); 510 aura::client::GetDragDropDelegate(target_window_);
518 if (delegate) { 511 if (delegate) {
519 ui::OSExchangeData data(new ui::OSExchangeDataProviderAuraX11( 512 ui::OSExchangeData data(new ui::OSExchangeDataProviderAuraX11(
520 xwindow_, target_current_context_->CloneFetchedTargets())); 513 xwindow_, target_current_context_->fetched_targets()));
521 514
522 ui::DropTargetEvent event(data, 515 ui::DropTargetEvent event(data,
523 target_window_location_, 516 target_window_location_,
524 target_window_root_location_, 517 target_window_root_location_,
525 target_current_context_->GetDragOperation()); 518 target_current_context_->GetDragOperation());
526 drag_operation = delegate->OnPerformDrop(event); 519 drag_operation = delegate->OnPerformDrop(event);
527 } 520 }
528 521
529 target_window_->RemoveObserver(this); 522 target_window_->RemoveObserver(this);
530 target_window_ = NULL; 523 target_window_ = NULL;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 target_window_changed = true; 679 target_window_changed = true;
687 } 680 }
688 *delegate = NULL; 681 *delegate = NULL;
689 if (!target_window_) 682 if (!target_window_)
690 return; 683 return;
691 *delegate = aura::client::GetDragDropDelegate(target_window_); 684 *delegate = aura::client::GetDragDropDelegate(target_window_);
692 if (!*delegate) 685 if (!*delegate)
693 return; 686 return;
694 687
695 data->reset(new OSExchangeData(new ui::OSExchangeDataProviderAuraX11( 688 data->reset(new OSExchangeData(new ui::OSExchangeDataProviderAuraX11(
696 xwindow_, target_current_context_->CloneFetchedTargets()))); 689 xwindow_, target_current_context_->fetched_targets())));
697 gfx::Point location = root_location; 690 gfx::Point location = root_location;
698 aura::Window::ConvertPointToTarget(root_window_, target_window_, &location); 691 aura::Window::ConvertPointToTarget(root_window_, target_window_, &location);
699 692
700 target_window_location_ = location; 693 target_window_location_ = location;
701 target_window_root_location_ = root_location; 694 target_window_root_location_ = root_location;
702 695
703 event->reset(new ui::DropTargetEvent( 696 event->reset(new ui::DropTargetEvent(
704 *(data->get()), 697 *(data->get()),
705 location, 698 location,
706 root_location, 699 root_location,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 std::vector< ::Atom> operations; 740 std::vector< ::Atom> operations;
748 if (drag_operation_ & ui::DragDropTypes::DRAG_COPY) 741 if (drag_operation_ & ui::DragDropTypes::DRAG_COPY)
749 operations.push_back(atom_cache_.GetAtom(kXdndActionCopy)); 742 operations.push_back(atom_cache_.GetAtom(kXdndActionCopy));
750 if (drag_operation_ & ui::DragDropTypes::DRAG_MOVE) 743 if (drag_operation_ & ui::DragDropTypes::DRAG_MOVE)
751 operations.push_back(atom_cache_.GetAtom(kXdndActionMove)); 744 operations.push_back(atom_cache_.GetAtom(kXdndActionMove));
752 if (drag_operation_ & ui::DragDropTypes::DRAG_LINK) 745 if (drag_operation_ & ui::DragDropTypes::DRAG_LINK)
753 operations.push_back(atom_cache_.GetAtom(kXdndActionLink)); 746 operations.push_back(atom_cache_.GetAtom(kXdndActionLink));
754 return operations; 747 return operations;
755 } 748 }
756 749
757 scoped_ptr<ui::SelectionFormatMap> 750 ui::SelectionFormatMap DesktopDragDropClientAuraX11::GetFormatMap() const {
758 DesktopDragDropClientAuraX11::CloneFormatMap() const { 751 return source_provider_ ? source_provider_->GetFormatMap() :
759 return source_provider_ ? source_provider_->CloneFormatMap() : 752 ui::SelectionFormatMap();
760 scoped_ptr<ui::SelectionFormatMap>();
761 } 753 }
762 754
763 void DesktopDragDropClientAuraX11::CompleteXdndPosition( 755 void DesktopDragDropClientAuraX11::CompleteXdndPosition(
764 ::Window source_window, 756 ::Window source_window,
765 const gfx::Point& screen_point) { 757 const gfx::Point& screen_point) {
766 int drag_operation = ui::DragDropTypes::DRAG_NONE; 758 int drag_operation = ui::DragDropTypes::DRAG_NONE;
767 scoped_ptr<ui::OSExchangeData> data; 759 scoped_ptr<ui::OSExchangeData> data;
768 scoped_ptr<ui::DropTargetEvent> drop_target_event; 760 scoped_ptr<ui::DropTargetEvent> drop_target_event;
769 DragDropDelegate* delegate = NULL; 761 DragDropDelegate* delegate = NULL;
770 DragTranslate(screen_point, &data, &drop_target_event, &delegate); 762 DragTranslate(screen_point, &data, &drop_target_event, &delegate);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 // GdkEvent about the failed drag. (And sending this message doesn't appear 899 // GdkEvent about the failed drag. (And sending this message doesn't appear
908 // to go through normal xlib machinery, but instead passes through the low 900 // to go through normal xlib machinery, but instead passes through the low
909 // level xProto (the x11 wire format) that I don't understand. 901 // level xProto (the x11 wire format) that I don't understand.
910 // 902 //
911 // I'm unsure if I have to jump through those hoops, or if XSendEvent is 903 // I'm unsure if I have to jump through those hoops, or if XSendEvent is
912 // sufficient. 904 // sufficient.
913 XSendEvent(xdisplay_, xid, False, 0, xev); 905 XSendEvent(xdisplay_, xid, False, 0, xev);
914 } 906 }
915 907
916 } // namespace views 908 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698