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

Side by Side Diff: ui/base/clipboard/clipboard_aurax11.cc

Issue 391593002: Process SelectionRequestor::PerformBlockingConvertSelection() requests one at a time (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | « no previous file | ui/base/x/selection_requestor.h » ('j') | ui/base/x/selection_requestor.h » ('J')
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/base/clipboard/clipboard.h" 5 #include "ui/base/clipboard/clipboard.h"
6 6
7 #include <X11/extensions/Xfixes.h> 7 #include <X11/extensions/Xfixes.h>
8 #include <X11/Xatom.h> 8 #include <X11/Xatom.h>
9 #include <list> 9 #include <list>
10 #include <set> 10 #include <set>
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 X11AtomCache* atom_cache() { return &atom_cache_; } 234 X11AtomCache* atom_cache() { return &atom_cache_; }
235 235
236 // Returns the X11 type that we pass to various XSelection functions for the 236 // Returns the X11 type that we pass to various XSelection functions for the
237 // given type. 237 // given type.
238 ::Atom LookupSelectionForClipboardType(ClipboardType type) const; 238 ::Atom LookupSelectionForClipboardType(ClipboardType type) const;
239 239
240 // Returns the X11 type that we pass to various XSelection functions for 240 // Returns the X11 type that we pass to various XSelection functions for
241 // CLIPBOARD_TYPE_COPY_PASTE. 241 // CLIPBOARD_TYPE_COPY_PASTE.
242 ::Atom GetCopyPasteSelection() const; 242 ::Atom GetCopyPasteSelection() const;
243 243
244 // Returns the object which is responsible for communication on |type|.
245 SelectionRequestor* GetSelectionRequestorForClipboardType(ClipboardType type);
246
247 // Finds the SelectionFormatMap for the incoming selection atom. 244 // Finds the SelectionFormatMap for the incoming selection atom.
248 const SelectionFormatMap& LookupStorageForAtom(::Atom atom); 245 const SelectionFormatMap& LookupStorageForAtom(::Atom atom);
249 246
250 // As we need to collect all the data types before we tell X11 that we own a 247 // As we need to collect all the data types before we tell X11 that we own a
251 // particular selection, we create a temporary clipboard mapping that 248 // particular selection, we create a temporary clipboard mapping that
252 // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection, 249 // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection,
253 // where we save it in one of the clipboard data slots. 250 // where we save it in one of the clipboard data slots.
254 void CreateNewClipboardData(); 251 void CreateNewClipboardData();
255 252
256 // Inserts a mapping into clipboard_data_. 253 // Inserts a mapping into clipboard_data_.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 295
299 // Our X11 state. 296 // Our X11 state.
300 Display* x_display_; 297 Display* x_display_;
301 ::Window x_root_window_; 298 ::Window x_root_window_;
302 299
303 // Input-only window used as a selection owner. 300 // Input-only window used as a selection owner.
304 ::Window x_window_; 301 ::Window x_window_;
305 302
306 X11AtomCache atom_cache_; 303 X11AtomCache atom_cache_;
307 304
308 // Objects which request and receive selection data. 305 // Object which requests and receives selection data.
309 SelectionRequestor clipboard_requestor_; 306 SelectionRequestor selection_requestor_;
310 SelectionRequestor primary_requestor_;
311 SelectionRequestor clipboard_manager_requestor_;
312 307
313 // Temporary target map that we write to during DispatchObects. 308 // Temporary target map that we write to during DispatchObects.
314 SelectionFormatMap clipboard_data_; 309 SelectionFormatMap clipboard_data_;
315 310
316 // Objects which offer selection data to other windows. 311 // Objects which offer selection data to other windows.
317 SelectionOwner clipboard_owner_; 312 SelectionOwner clipboard_owner_;
318 SelectionOwner primary_owner_; 313 SelectionOwner primary_owner_;
319 314
320 DISALLOW_COPY_AND_ASSIGN(AuraX11Details); 315 DISALLOW_COPY_AND_ASSIGN(AuraX11Details);
321 }; 316 };
322 317
323 Clipboard::AuraX11Details::AuraX11Details() 318 Clipboard::AuraX11Details::AuraX11Details()
324 : x_display_(gfx::GetXDisplay()), 319 : x_display_(gfx::GetXDisplay()),
325 x_root_window_(DefaultRootWindow(x_display_)), 320 x_root_window_(DefaultRootWindow(x_display_)),
326 x_window_(XCreateWindow( 321 x_window_(XCreateWindow(
327 x_display_, x_root_window_, 322 x_display_, x_root_window_,
328 -100, -100, 10, 10, // x, y, width, height 323 -100, -100, 10, 10, // x, y, width, height
329 0, // border width 324 0, // border width
330 CopyFromParent, // depth 325 CopyFromParent, // depth
331 InputOnly, 326 InputOnly,
332 CopyFromParent, // visual 327 CopyFromParent, // visual
333 0, 328 0,
334 NULL)), 329 NULL)),
335 atom_cache_(x_display_, kAtomsToCache), 330 atom_cache_(x_display_, kAtomsToCache),
336 clipboard_requestor_(x_display_, x_window_, 331 selection_requestor_(x_display_, x_window_, this),
337 atom_cache_.GetAtom(kClipboard), this),
338 primary_requestor_(x_display_, x_window_, XA_PRIMARY, this),
339 clipboard_manager_requestor_(x_display_, x_window_,
340 atom_cache_.GetAtom(kClipboardManager),
341 this),
342 clipboard_owner_(x_display_, x_window_, atom_cache_.GetAtom(kClipboard)), 332 clipboard_owner_(x_display_, x_window_, atom_cache_.GetAtom(kClipboard)),
343 primary_owner_(x_display_, x_window_, XA_PRIMARY) { 333 primary_owner_(x_display_, x_window_, XA_PRIMARY) {
344 // We don't know all possible MIME types at compile time. 334 // We don't know all possible MIME types at compile time.
345 atom_cache_.allow_uncached_atoms(); 335 atom_cache_.allow_uncached_atoms();
346 336
347 XStoreName(x_display_, x_window_, "Chromium clipboard"); 337 XStoreName(x_display_, x_window_, "Chromium clipboard");
348 XSelectInput(x_display_, x_window_, PropertyChangeMask); 338 XSelectInput(x_display_, x_window_, PropertyChangeMask);
349 339
350 if (PlatformEventSource::GetInstance()) 340 if (PlatformEventSource::GetInstance())
351 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 341 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
(...skipping 20 matching lines...) Expand all
372 362
373 const SelectionFormatMap& Clipboard::AuraX11Details::LookupStorageForAtom( 363 const SelectionFormatMap& Clipboard::AuraX11Details::LookupStorageForAtom(
374 ::Atom atom) { 364 ::Atom atom) {
375 if (atom == XA_PRIMARY) 365 if (atom == XA_PRIMARY)
376 return primary_owner_.selection_format_map(); 366 return primary_owner_.selection_format_map();
377 367
378 DCHECK_EQ(GetCopyPasteSelection(), atom); 368 DCHECK_EQ(GetCopyPasteSelection(), atom);
379 return clipboard_owner_.selection_format_map(); 369 return clipboard_owner_.selection_format_map();
380 } 370 }
381 371
382 ui::SelectionRequestor*
383 Clipboard::AuraX11Details::GetSelectionRequestorForClipboardType(
384 ClipboardType type) {
385 if (type == CLIPBOARD_TYPE_COPY_PASTE)
386 return &clipboard_requestor_;
387 else
388 return &primary_requestor_;
389 }
390
391 void Clipboard::AuraX11Details::CreateNewClipboardData() { 372 void Clipboard::AuraX11Details::CreateNewClipboardData() {
392 clipboard_data_ = SelectionFormatMap(); 373 clipboard_data_ = SelectionFormatMap();
393 } 374 }
394 375
395 void Clipboard::AuraX11Details::InsertMapping( 376 void Clipboard::AuraX11Details::InsertMapping(
396 const std::string& key, 377 const std::string& key,
397 const scoped_refptr<base::RefCountedMemory>& memory) { 378 const scoped_refptr<base::RefCountedMemory>& memory) {
398 ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); 379 ::Atom atom_key = atom_cache_.GetAtom(key.c_str());
399 clipboard_data_.Insert(atom_key, memory); 380 clipboard_data_.Insert(atom_key, memory);
400 } 381 }
(...skipping 15 matching lines...) Expand all
416 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); 397 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
417 398
418 for (std::vector< ::Atom>::const_iterator it = types.begin(); 399 for (std::vector< ::Atom>::const_iterator it = types.begin();
419 it != types.end(); ++it) { 400 it != types.end(); ++it) {
420 SelectionFormatMap::const_iterator format_map_it = format_map.find(*it); 401 SelectionFormatMap::const_iterator format_map_it = format_map.find(*it);
421 if (format_map_it != format_map.end()) 402 if (format_map_it != format_map.end())
422 return SelectionData(format_map_it->first, format_map_it->second); 403 return SelectionData(format_map_it->first, format_map_it->second);
423 } 404 }
424 } else { 405 } else {
425 TargetList targets = WaitAndGetTargetsList(type); 406 TargetList targets = WaitAndGetTargetsList(type);
426 SelectionRequestor* receiver = GetSelectionRequestorForClipboardType(type);
427 407
408 ::Atom selection_name = LookupSelectionForClipboardType(type);
Daniel Erat 2014/07/16 22:17:00 doesn't need to happen in this change, but these c
pkotwicz 2014/07/17 19:38:34 Acknowledged.
428 std::vector< ::Atom> intersection; 409 std::vector< ::Atom> intersection;
429 ui::GetAtomIntersection(types, targets.target_list(), &intersection); 410 ui::GetAtomIntersection(types, targets.target_list(), &intersection);
430 return receiver->RequestAndWaitForTypes(intersection); 411 return selection_requestor_.RequestAndWaitForTypes(selection_name,
412 intersection);
431 } 413 }
432 414
433 return SelectionData(); 415 return SelectionData();
434 } 416 }
435 417
436 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( 418 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList(
437 ClipboardType type) { 419 ClipboardType type) {
438 ::Atom selection_name = LookupSelectionForClipboardType(type); 420 ::Atom selection_name = LookupSelectionForClipboardType(type);
439 std::vector< ::Atom> out; 421 std::vector< ::Atom> out;
440 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { 422 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) {
441 // We can local fastpath and return the list of local targets. 423 // We can local fastpath and return the list of local targets.
442 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); 424 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
443 425
444 for (SelectionFormatMap::const_iterator it = format_map.begin(); 426 for (SelectionFormatMap::const_iterator it = format_map.begin();
445 it != format_map.end(); ++it) { 427 it != format_map.end(); ++it) {
446 out.push_back(it->first); 428 out.push_back(it->first);
447 } 429 }
448 } else { 430 } else {
449 scoped_refptr<base::RefCountedMemory> data; 431 scoped_refptr<base::RefCountedMemory> data;
450 size_t out_data_items = 0; 432 size_t out_data_items = 0;
451 ::Atom out_type = None; 433 ::Atom out_type = None;
452 434
453 SelectionRequestor* receiver = GetSelectionRequestorForClipboardType(type); 435 if (selection_requestor_.PerformBlockingConvertSelection(
454 if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), 436 selection_name,
455 &data, 437 atom_cache_.GetAtom(kTargets),
456 &out_data_items, 438 &data,
457 &out_type)) { 439 &out_data_items,
440 &out_type)) {
458 // Some apps return an |out_type| of "TARGETS". (crbug.com/377893) 441 // Some apps return an |out_type| of "TARGETS". (crbug.com/377893)
459 if (out_type == XA_ATOM || out_type == atom_cache_.GetAtom(kTargets)) { 442 if (out_type == XA_ATOM || out_type == atom_cache_.GetAtom(kTargets)) {
460 const ::Atom* atom_array = 443 const ::Atom* atom_array =
461 reinterpret_cast<const ::Atom*>(data->front()); 444 reinterpret_cast<const ::Atom*>(data->front());
462 for (size_t i = 0; i < out_data_items; ++i) 445 for (size_t i = 0; i < out_data_items; ++i)
463 out.push_back(atom_array[i]); 446 out.push_back(atom_array[i]);
464 } 447 }
465 } else { 448 } else {
466 // There was no target list. Most Java apps doesn't offer a TARGETS list, 449 // There was no target list. Most Java apps doesn't offer a TARGETS list,
467 // even though they AWT to. They will offer individual text types if you 450 // even though they AWT to. They will offer individual text types if you
468 // ask. If this is the case we attempt to make sense of the contents as 451 // ask. If this is the case we attempt to make sense of the contents as
469 // text. This is pretty unfortunate since it means we have to actually 452 // text. This is pretty unfortunate since it means we have to actually
470 // copy the data to see if it is available, but at least this path 453 // copy the data to see if it is available, but at least this path
471 // shouldn't be hit for conforming programs. 454 // shouldn't be hit for conforming programs.
472 std::vector< ::Atom> types = GetTextAtoms(); 455 std::vector< ::Atom> types = GetTextAtoms();
473 for (std::vector< ::Atom>::const_iterator it = types.begin(); 456 for (std::vector< ::Atom>::const_iterator it = types.begin();
474 it != types.end(); ++it) { 457 it != types.end(); ++it) {
475 ::Atom type = None; 458 ::Atom type = None;
476 if (receiver->PerformBlockingConvertSelection(*it, 459 if (selection_requestor_.PerformBlockingConvertSelection(selection_name,
477 NULL, 460 *it,
478 NULL, 461 NULL,
479 &type) && 462 NULL,
463 &type) &&
480 type == *it) { 464 type == *it) {
481 out.push_back(*it); 465 out.push_back(*it);
482 } 466 }
483 } 467 }
484 } 468 }
485 } 469 }
486 470
487 return TargetList(out, &atom_cache_); 471 return TargetList(out, &atom_cache_);
488 } 472 }
489 473
(...skipping 23 matching lines...) Expand all
513 ::Atom clipboard_manager_atom = atom_cache_.GetAtom(kClipboardManager); 497 ::Atom clipboard_manager_atom = atom_cache_.GetAtom(kClipboardManager);
514 if (XGetSelectionOwner(x_display_, clipboard_manager_atom) == None) 498 if (XGetSelectionOwner(x_display_, clipboard_manager_atom) == None)
515 return; 499 return;
516 500
517 const SelectionFormatMap& format_map = LookupStorageForAtom(selection); 501 const SelectionFormatMap& format_map = LookupStorageForAtom(selection);
518 if (format_map.size() == 0) 502 if (format_map.size() == 0)
519 return; 503 return;
520 std::vector<Atom> targets = format_map.GetTypes(); 504 std::vector<Atom> targets = format_map.GetTypes();
521 505
522 base::TimeTicks start = base::TimeTicks::Now(); 506 base::TimeTicks start = base::TimeTicks::Now();
523 clipboard_manager_requestor_.PerformBlockingConvertSelectionWithParameter( 507 selection_requestor_.PerformBlockingConvertSelectionWithParameter(
524 atom_cache_.GetAtom(kSaveTargets), targets); 508 atom_cache_.GetAtom(kClipboardManager),
509 atom_cache_.GetAtom(kSaveTargets),
510 targets);
525 UMA_HISTOGRAM_TIMES("Clipboard.X11StoreCopyPasteDuration", 511 UMA_HISTOGRAM_TIMES("Clipboard.X11StoreCopyPasteDuration",
526 base::TimeTicks::Now() - start); 512 base::TimeTicks::Now() - start);
527 } 513 }
528 514
529 bool Clipboard::AuraX11Details::CanDispatchEvent(const PlatformEvent& event) { 515 bool Clipboard::AuraX11Details::CanDispatchEvent(const PlatformEvent& event) {
530 return event->xany.window == x_window_; 516 return event->xany.window == x_window_;
531 } 517 }
532 518
533 uint32_t Clipboard::AuraX11Details::DispatchEvent(const PlatformEvent& xev) { 519 uint32_t Clipboard::AuraX11Details::DispatchEvent(const PlatformEvent& xev) {
534 switch (xev->type) { 520 switch (xev->type) {
535 case SelectionRequest: { 521 case SelectionRequest: {
536 if (xev->xselectionrequest.selection == XA_PRIMARY) { 522 if (xev->xselectionrequest.selection == XA_PRIMARY) {
537 primary_owner_.OnSelectionRequest(xev->xselectionrequest); 523 primary_owner_.OnSelectionRequest(xev->xselectionrequest);
538 } else { 524 } else {
539 // We should not get requests for the CLIPBOARD_MANAGER selection 525 // We should not get requests for the CLIPBOARD_MANAGER selection
540 // because we never take ownership of it. 526 // because we never take ownership of it.
541 DCHECK_EQ(GetCopyPasteSelection(), xev->xselectionrequest.selection); 527 DCHECK_EQ(GetCopyPasteSelection(), xev->xselectionrequest.selection);
542 clipboard_owner_.OnSelectionRequest(xev->xselectionrequest); 528 clipboard_owner_.OnSelectionRequest(xev->xselectionrequest);
543 } 529 }
544 break; 530 break;
545 } 531 }
546 case SelectionNotify: { 532 case SelectionNotify:
547 ::Atom selection = xev->xselection.selection; 533 selection_requestor_.OnSelectionNotify(*xev);
548 if (selection == XA_PRIMARY)
549 primary_requestor_.OnSelectionNotify(*xev);
550 else if (selection == GetCopyPasteSelection())
551 clipboard_requestor_.OnSelectionNotify(*xev);
552 else if (selection == atom_cache_.GetAtom(kClipboardManager))
553 clipboard_manager_requestor_.OnSelectionNotify(*xev);
554 break; 534 break;
555 }
556 case SelectionClear: { 535 case SelectionClear: {
557 if (xev->xselectionclear.selection == XA_PRIMARY) { 536 if (xev->xselectionclear.selection == XA_PRIMARY) {
558 primary_owner_.OnSelectionClear(xev->xselectionclear); 537 primary_owner_.OnSelectionClear(xev->xselectionclear);
559 } else { 538 } else {
560 // We should not get requests for the CLIPBOARD_MANAGER selection 539 // We should not get requests for the CLIPBOARD_MANAGER selection
561 // because we never take ownership of it. 540 // because we never take ownership of it.
562 DCHECK_EQ(GetCopyPasteSelection(), xev->xselection.selection); 541 DCHECK_EQ(GetCopyPasteSelection(), xev->xselection.selection);
563 clipboard_owner_.OnSelectionClear(xev->xselectionclear); 542 clipboard_owner_.OnSelectionClear(xev->xselectionclear);
564 } 543 }
565 break; 544 break;
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 return type; 893 return type;
915 } 894 }
916 895
917 // static 896 // static
918 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { 897 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
919 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); 898 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
920 return type; 899 return type;
921 } 900 }
922 901
923 } // namespace ui 902 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | ui/base/x/selection_requestor.h » ('j') | ui/base/x/selection_requestor.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698