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

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

Issue 443773003: Revert of Fix flakiness of DesktopDragDropClientAuraX11Tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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
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/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "ui/aura/window.h" 12 #include "ui/aura/window.h"
13 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
14 #include "ui/base/clipboard/clipboard.h" 14 #include "ui/base/clipboard/clipboard.h"
15 #include "ui/base/dragdrop/drop_target_event.h" 15 #include "ui/base/dragdrop/drop_target_event.h"
16 #include "ui/base/dragdrop/os_exchange_data.h" 16 #include "ui/base/dragdrop/os_exchange_data.h"
17 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" 17 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h"
18 #include "ui/base/x/selection_utils.h" 18 #include "ui/base/x/selection_utils.h"
19 #include "ui/base/x/x11_foreign_window_manager.h" 19 #include "ui/base/x/x11_foreign_window_manager.h"
20 #include "ui/base/x/x11_util.h" 20 #include "ui/base/x/x11_util.h"
21 #include "ui/events/event.h" 21 #include "ui/events/event.h"
22 #include "ui/events/platform/platform_event_source.h" 22 #include "ui/events/platform/platform_event_source.h"
23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" 23 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
24 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" 24 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
25 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
26 #include "ui/wm/public/drag_drop_client.h" 25 #include "ui/wm/public/drag_drop_client.h"
27 #include "ui/wm/public/drag_drop_delegate.h" 26 #include "ui/wm/public/drag_drop_delegate.h"
28 27
29 using aura::client::DragDropDelegate; 28 using aura::client::DragDropDelegate;
30 using ui::OSExchangeData; 29 using ui::OSExchangeData;
31 30
32 namespace { 31 namespace {
33 32
34 const int kMinXdndVersion = 5; 33 const int kMinXdndVersion = 5;
35 34
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 return ui::POST_DISPATCH_NONE; 354 return ui::POST_DISPATCH_NONE;
356 } 355 }
357 356
358 /////////////////////////////////////////////////////////////////////////////// 357 ///////////////////////////////////////////////////////////////////////////////
359 358
360 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11( 359 DesktopDragDropClientAuraX11::DesktopDragDropClientAuraX11(
361 aura::Window* root_window, 360 aura::Window* root_window,
362 views::DesktopNativeCursorManager* cursor_manager, 361 views::DesktopNativeCursorManager* cursor_manager,
363 Display* xdisplay, 362 Display* xdisplay,
364 ::Window xwindow) 363 ::Window xwindow)
365 : root_window_(root_window), 364 : move_loop_(this),
365 root_window_(root_window),
366 xdisplay_(xdisplay), 366 xdisplay_(xdisplay),
367 xwindow_(xwindow), 367 xwindow_(xwindow),
368 atom_cache_(xdisplay_, kAtomsToCache), 368 atom_cache_(xdisplay_, kAtomsToCache),
369 target_window_(NULL), 369 target_window_(NULL),
370 waiting_on_status_(false), 370 waiting_on_status_(false),
371 status_received_since_enter_(false), 371 status_received_since_enter_(false),
372 source_provider_(NULL), 372 source_provider_(NULL),
373 source_current_window_(None), 373 source_current_window_(None),
374 source_state_(SOURCE_STATE_OTHER), 374 source_state_(SOURCE_STATE_OTHER),
375 drag_operation_(0), 375 drag_operation_(0),
(...skipping 24 matching lines...) Expand all
400 // static 400 // static
401 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow( 401 DesktopDragDropClientAuraX11* DesktopDragDropClientAuraX11::GetForWindow(
402 ::Window window) { 402 ::Window window) {
403 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it = 403 std::map< ::Window, DesktopDragDropClientAuraX11*>::const_iterator it =
404 g_live_client_map.Get().find(window); 404 g_live_client_map.Get().find(window);
405 if (it == g_live_client_map.Get().end()) 405 if (it == g_live_client_map.Get().end())
406 return NULL; 406 return NULL;
407 return it->second; 407 return it->second;
408 } 408 }
409 409
410 void DesktopDragDropClientAuraX11::Init() {
411 move_loop_ = CreateMoveLoop(this);
412 }
413
414 void DesktopDragDropClientAuraX11::OnXdndEnter( 410 void DesktopDragDropClientAuraX11::OnXdndEnter(
415 const XClientMessageEvent& event) { 411 const XClientMessageEvent& event) {
416 DVLOG(1) << "XdndEnter"; 412 DVLOG(1) << "XdndEnter";
417 413
418 int version = (event.data.l[1] & 0xff000000) >> 24; 414 int version = (event.data.l[1] & 0xff000000) >> 24;
419 if (version < 3) { 415 if (version < 3) {
420 LOG(ERROR) << "Received old XdndEnter message."; 416 LOG(ERROR) << "Received old XdndEnter message.";
421 return; 417 return;
422 } 418 }
423 419
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 if (event.data.l[1] & 1) { 476 if (event.data.l[1] & 1) {
481 ::Atom atom_operation = event.data.l[4]; 477 ::Atom atom_operation = event.data.l[4];
482 negotiated_operation_ = AtomToDragOperation(atom_operation); 478 negotiated_operation_ = AtomToDragOperation(atom_operation);
483 } else { 479 } else {
484 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; 480 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
485 } 481 }
486 482
487 if (source_state_ == SOURCE_STATE_PENDING_DROP) { 483 if (source_state_ == SOURCE_STATE_PENDING_DROP) {
488 // We were waiting on the status message so we could send the XdndDrop. 484 // We were waiting on the status message so we could send the XdndDrop.
489 if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) { 485 if (negotiated_operation_ == ui::DragDropTypes::DRAG_NONE) {
490 move_loop_->EndMoveLoop(); 486 move_loop_.EndMoveLoop();
491 return; 487 return;
492 } 488 }
493 source_state_ = SOURCE_STATE_DROPPED; 489 source_state_ = SOURCE_STATE_DROPPED;
494 SendXdndDrop(source_window); 490 SendXdndDrop(source_window);
495 return; 491 return;
496 } 492 }
497 493
498 switch (negotiated_operation_) { 494 switch (negotiated_operation_) {
499 case ui::DragDropTypes::DRAG_COPY: 495 case ui::DragDropTypes::DRAG_COPY:
500 move_loop_->UpdateCursor(copy_grab_cursor_); 496 move_loop_.UpdateCursor(copy_grab_cursor_);
501 break; 497 break;
502 case ui::DragDropTypes::DRAG_MOVE: 498 case ui::DragDropTypes::DRAG_MOVE:
503 move_loop_->UpdateCursor(move_grab_cursor_); 499 move_loop_.UpdateCursor(move_grab_cursor_);
504 break; 500 break;
505 default: 501 default:
506 move_loop_->UpdateCursor(grab_cursor_); 502 move_loop_.UpdateCursor(grab_cursor_);
507 break; 503 break;
508 } 504 }
509 505
510 // Note: event.data.[2,3] specify a rectangle. It is a request by the other 506 // Note: event.data.[2,3] specify a rectangle. It is a request by the other
511 // window to not send further XdndPosition messages while the cursor is 507 // window to not send further XdndPosition messages while the cursor is
512 // within it. However, it is considered advisory and (at least according to 508 // within it. However, it is considered advisory and (at least according to
513 // the spec) the other side must handle further position messages within 509 // the spec) the other side must handle further position messages within
514 // it. GTK+ doesn't bother with this, so neither should we. 510 // it. GTK+ doesn't bother with this, so neither should we.
515 511
516 if (next_position_message_.get()) { 512 if (next_position_message_.get()) {
(...skipping 14 matching lines...) Expand all
531 if (source_current_window_ != source_window) 527 if (source_current_window_ != source_window)
532 return; 528 return;
533 529
534 // Clear |negotiated_operation_| if the drag was rejected. 530 // Clear |negotiated_operation_| if the drag was rejected.
535 if ((event.data.l[1] & 1) == 0) 531 if ((event.data.l[1] & 1) == 0)
536 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE; 532 negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
537 533
538 // Clear |source_current_window_| to avoid sending XdndLeave upon ending the 534 // Clear |source_current_window_| to avoid sending XdndLeave upon ending the
539 // move loop. 535 // move loop.
540 source_current_window_ = None; 536 source_current_window_ = None;
541 move_loop_->EndMoveLoop(); 537 move_loop_.EndMoveLoop();
542 } 538 }
543 539
544 void DesktopDragDropClientAuraX11::OnXdndDrop( 540 void DesktopDragDropClientAuraX11::OnXdndDrop(
545 const XClientMessageEvent& event) { 541 const XClientMessageEvent& event) {
546 DVLOG(1) << "XdndDrop"; 542 DVLOG(1) << "XdndDrop";
547 543
548 unsigned long source_window = event.data.l[0]; 544 unsigned long source_window = event.data.l[0];
549 545
550 int drag_operation = ui::DragDropTypes::DRAG_NONE; 546 int drag_operation = ui::DragDropTypes::DRAG_NONE;
551 if (target_window_) { 547 if (target_window_) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 620
625 // It is possible for the DesktopWindowTreeHostX11 to be destroyed during the 621 // It is possible for the DesktopWindowTreeHostX11 to be destroyed during the
626 // move loop, which would also destroy this drag-client. So keep track of 622 // move loop, which would also destroy this drag-client. So keep track of
627 // whether it is alive after the drag ends. 623 // whether it is alive after the drag ends.
628 base::WeakPtr<DesktopDragDropClientAuraX11> alive( 624 base::WeakPtr<DesktopDragDropClientAuraX11> alive(
629 weak_ptr_factory_.GetWeakPtr()); 625 weak_ptr_factory_.GetWeakPtr());
630 626
631 // Windows has a specific method, DoDragDrop(), which performs the entire 627 // Windows has a specific method, DoDragDrop(), which performs the entire
632 // drag. We have to emulate this, so we spin off a nested runloop which will 628 // drag. We have to emulate this, so we spin off a nested runloop which will
633 // track all cursor movement and reroute events to a specific handler. 629 // track all cursor movement and reroute events to a specific handler.
634 move_loop_->SetDragImage(source_provider_->GetDragImage(), 630 move_loop_.SetDragImage(source_provider_->GetDragImage(),
635 source_provider_->GetDragImageOffset()); 631 source_provider_->GetDragImageOffset());
636 move_loop_->RunMoveLoop(source_window, grab_cursor_); 632 move_loop_.RunMoveLoop(source_window, grab_cursor_);
637 633
638 if (alive) { 634 if (alive) {
639 move_loop_->SetDragImage(gfx::ImageSkia(), gfx::Vector2dF()); 635 move_loop_.SetDragImage(gfx::ImageSkia(), gfx::Vector2dF());
640 636
641 source_provider_ = NULL; 637 source_provider_ = NULL;
642 g_current_drag_drop_client = NULL; 638 g_current_drag_drop_client = NULL;
643 drag_operation_ = 0; 639 drag_operation_ = 0;
644 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndActionList")); 640 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("XdndActionList"));
645 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom(kXdndDirectSave0)); 641 XDeleteProperty(xdisplay_, xwindow_, atom_cache_.GetAtom(kXdndDirectSave0));
646 642
647 return negotiated_operation_; 643 return negotiated_operation_;
648 } 644 }
649 return ui::DragDropTypes::DRAG_NONE; 645 return ui::DragDropTypes::DRAG_NONE;
650 } 646 }
651 647
652 void DesktopDragDropClientAuraX11::DragUpdate(aura::Window* target, 648 void DesktopDragDropClientAuraX11::DragUpdate(aura::Window* target,
653 const ui::LocatedEvent& event) { 649 const ui::LocatedEvent& event) {
654 NOTIMPLEMENTED(); 650 NOTIMPLEMENTED();
655 } 651 }
656 652
657 void DesktopDragDropClientAuraX11::Drop(aura::Window* target, 653 void DesktopDragDropClientAuraX11::Drop(aura::Window* target,
658 const ui::LocatedEvent& event) { 654 const ui::LocatedEvent& event) {
659 NOTIMPLEMENTED(); 655 NOTIMPLEMENTED();
660 } 656 }
661 657
662 void DesktopDragDropClientAuraX11::DragCancel() { 658 void DesktopDragDropClientAuraX11::DragCancel() {
663 move_loop_->EndMoveLoop(); 659 move_loop_.EndMoveLoop();
664 } 660 }
665 661
666 bool DesktopDragDropClientAuraX11::IsDragDropInProgress() { 662 bool DesktopDragDropClientAuraX11::IsDragDropInProgress() {
667 return !!g_current_drag_drop_client; 663 return !!g_current_drag_drop_client;
668 } 664 }
669 665
670 void DesktopDragDropClientAuraX11::OnWindowDestroyed(aura::Window* window) { 666 void DesktopDragDropClientAuraX11::OnWindowDestroyed(aura::Window* window) {
671 DCHECK_EQ(target_window_, window); 667 DCHECK_EQ(target_window_, window);
672 target_window_ = NULL; 668 target_window_ = NULL;
673 } 669 }
674 670
675 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) { 671 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) {
676 repeat_mouse_move_timer_.Stop(); 672 repeat_mouse_move_timer_.Stop();
677 ProcessMouseMove(gfx::Point(event->x_root, event->y_root), event->time); 673 ProcessMouseMove(gfx::Point(event->x_root, event->y_root), event->time);
678 } 674 }
679 675
680 void DesktopDragDropClientAuraX11::OnMouseReleased() { 676 void DesktopDragDropClientAuraX11::OnMouseReleased() {
681 repeat_mouse_move_timer_.Stop(); 677 repeat_mouse_move_timer_.Stop();
682 678
683 if (source_state_ != SOURCE_STATE_OTHER) { 679 if (source_state_ != SOURCE_STATE_OTHER) {
684 // The user has previously released the mouse and is clicking in 680 // The user has previously released the mouse and is clicking in
685 // frustration. 681 // frustration.
686 move_loop_->EndMoveLoop(); 682 move_loop_.EndMoveLoop();
687 return; 683 return;
688 } 684 }
689 685
690 if (source_current_window_ != None) { 686 if (source_current_window_ != None) {
691 if (waiting_on_status_) { 687 if (waiting_on_status_) {
692 if (status_received_since_enter_) { 688 if (status_received_since_enter_) {
693 // If we are waiting for an XdndStatus message, we need to wait for it 689 // If we are waiting for an XdndStatus message, we need to wait for it
694 // to complete. 690 // to complete.
695 source_state_ = SOURCE_STATE_PENDING_DROP; 691 source_state_ = SOURCE_STATE_PENDING_DROP;
696 692
697 // Start timer to end the move loop if the target takes too long to send 693 // Start timer to end the move loop if the target takes too long to send
698 // the XdndStatus and XdndFinished messages. 694 // the XdndStatus and XdndFinished messages.
699 StartEndMoveLoopTimer(); 695 StartEndMoveLoopTimer();
700 return; 696 return;
701 } 697 }
702 698
703 move_loop_->EndMoveLoop(); 699 move_loop_.EndMoveLoop();
704 return; 700 return;
705 } 701 }
706 702
707 if (negotiated_operation_ != ui::DragDropTypes::DRAG_NONE) { 703 if (negotiated_operation_ != ui::DragDropTypes::DRAG_NONE) {
708 // Start timer to end the move loop if the target takes too long to send 704 // Start timer to end the move loop if the target takes too long to send
709 // an XdndFinished message. It is important that StartEndMoveLoopTimer() 705 // an XdndFinished message. It is important that StartEndMoveLoopTimer()
710 // is called before SendXdndDrop() because SendXdndDrop() 706 // is called before SendXdndDrop() because SendXdndDrop()
711 // sends XdndFinished synchronously if the drop target is a Chrome 707 // sends XdndFinished synchronously if the drop target is a Chrome
712 // window. 708 // window.
713 StartEndMoveLoopTimer(); 709 StartEndMoveLoopTimer();
714 710
715 // We have negotiated an action with the other end. 711 // We have negotiated an action with the other end.
716 source_state_ = SOURCE_STATE_DROPPED; 712 source_state_ = SOURCE_STATE_DROPPED;
717 SendXdndDrop(source_current_window_); 713 SendXdndDrop(source_current_window_);
718 return; 714 return;
719 } 715 }
720 } 716 }
721 717
722 move_loop_->EndMoveLoop(); 718 move_loop_.EndMoveLoop();
723 } 719 }
724 720
725 void DesktopDragDropClientAuraX11::OnMoveLoopEnded() { 721 void DesktopDragDropClientAuraX11::OnMoveLoopEnded() {
726 if (source_current_window_ != None) { 722 if (source_current_window_ != None) {
727 SendXdndLeave(source_current_window_); 723 SendXdndLeave(source_current_window_);
728 source_current_window_ = None; 724 source_current_window_ = None;
729 } 725 }
730 target_current_context_.reset(); 726 target_current_context_.reset();
731 repeat_mouse_move_timer_.Stop(); 727 repeat_mouse_move_timer_.Stop();
732 end_move_loop_timer_.Stop(); 728 end_move_loop_timer_.Stop();
733 } 729 }
734 730
735 scoped_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop(
736 X11MoveLoopDelegate* delegate) {
737 return scoped_ptr<X11MoveLoop>(new X11WholeScreenMoveLoop(this));
738 }
739
740 XID DesktopDragDropClientAuraX11::FindWindowFor( 731 XID DesktopDragDropClientAuraX11::FindWindowFor(
741 const gfx::Point& screen_point) { 732 const gfx::Point& screen_point) {
742 views::X11TopmostWindowFinder finder; 733 views::X11TopmostWindowFinder finder;
743 ::Window target = finder.FindWindowAt(screen_point); 734 ::Window target = finder.FindWindowAt(screen_point);
744 735
745 if (target == None) 736 if (target == None)
746 return None; 737 return None;
747 738
748 // Figure out which window we should test as XdndAware. If |target| has 739 // Figure out which window we should test as XdndAware. If |target| has
749 // XdndProxy, it will set that proxy on target, and if not, |target|'s 740 // XdndProxy, it will set that proxy on target, and if not, |target|'s
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 825
835 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() { 826 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() {
836 end_move_loop_timer_.Start(FROM_HERE, 827 end_move_loop_timer_.Start(FROM_HERE,
837 base::TimeDelta::FromMilliseconds( 828 base::TimeDelta::FromMilliseconds(
838 kEndMoveLoopTimeoutMs), 829 kEndMoveLoopTimeoutMs),
839 this, 830 this,
840 &DesktopDragDropClientAuraX11::EndMoveLoop); 831 &DesktopDragDropClientAuraX11::EndMoveLoop);
841 } 832 }
842 833
843 void DesktopDragDropClientAuraX11::EndMoveLoop() { 834 void DesktopDragDropClientAuraX11::EndMoveLoop() {
844 move_loop_->EndMoveLoop(); 835 move_loop_.EndMoveLoop();
845 } 836 }
846 837
847 void DesktopDragDropClientAuraX11::DragTranslate( 838 void DesktopDragDropClientAuraX11::DragTranslate(
848 const gfx::Point& root_window_location, 839 const gfx::Point& root_window_location,
849 scoped_ptr<ui::OSExchangeData>* data, 840 scoped_ptr<ui::OSExchangeData>* data,
850 scoped_ptr<ui::DropTargetEvent>* event, 841 scoped_ptr<ui::DropTargetEvent>* event,
851 aura::client::DragDropDelegate** delegate) { 842 aura::client::DragDropDelegate** delegate) {
852 gfx::Point root_location = root_window_location; 843 gfx::Point root_location = root_window_location;
853 root_window_->GetHost()->ConvertPointFromNativeScreen(&root_location); 844 root_window_->GetHost()->ConvertPointFromNativeScreen(&root_location);
854 aura::Window* target_window = 845 aura::Window* target_window =
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 xev.xclient.window = dest_window; 1039 xev.xclient.window = dest_window;
1049 xev.xclient.data.l[0] = xwindow_; 1040 xev.xclient.data.l[0] = xwindow_;
1050 xev.xclient.data.l[1] = 0; 1041 xev.xclient.data.l[1] = 0;
1051 xev.xclient.data.l[2] = CurrentTime; 1042 xev.xclient.data.l[2] = CurrentTime;
1052 xev.xclient.data.l[3] = None; 1043 xev.xclient.data.l[3] = None;
1053 xev.xclient.data.l[4] = None; 1044 xev.xclient.data.l[4] = None;
1054 SendXClientEvent(dest_window, &xev); 1045 SendXClientEvent(dest_window, &xev);
1055 } 1046 }
1056 1047
1057 } // namespace views 1048 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698