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. 4 5 #include "ash/drag_drop/drag_drop_tracker.h" 6 7 #include "ash/shell.h" 8 #include "ash/shell_window_ids.h" 9 #include "ash/wm/coordinate_conversion.h" 10 #include "ui/aura/client/window_tree_client.h" 11 #include "ui/aura/window.h" 12 #include "ui/aura/window_event_dispatcher.h" 13 #include "ui/events/event.h" 14 #include "ui/gfx/screen.h" 15 #include "ui/wm/public/activation_delegate.h" 16 17 namespace ash { 18 namespace { 19 20 // An activation delegate which disables activating the drag and drop window. 21 class CaptureWindowActivationDelegate 22 : public aura::client::ActivationDelegate { 23 public: 24 CaptureWindowActivationDelegate() {} 25 virtual ~CaptureWindowActivationDelegate() {} 26 27 // aura::client::ActivationDelegate overrides: 28 virtual bool ShouldActivate() const OVERRIDE { 29 return false; 30 } 31 32 private: 33 34 DISALLOW_COPY_AND_ASSIGN(CaptureWindowActivationDelegate); 35 }; 36 37 // Creates a window for capturing drag events. 38 aura::Window* CreateCaptureWindow(aura::Window* context_root, 39 aura::WindowDelegate* delegate) { 40 static CaptureWindowActivationDelegate* activation_delegate_instance = NULL; 41 if (!activation_delegate_instance) 42 activation_delegate_instance = new CaptureWindowActivationDelegate; 43 aura::Window* window = new aura::Window(delegate); 44 window->SetType(ui::wm::WINDOW_TYPE_NORMAL); 45 window->Init(aura::WINDOW_LAYER_NOT_DRAWN); 46 aura::client::ParentWindowWithContext(window, context_root, gfx::Rect()); 47 aura::client::SetActivationDelegate(window, activation_delegate_instance); 48 window->Show(); 49 DCHECK(window->bounds().size().IsEmpty()); 50 return window; 51 } 52 53 } // namespace 54 55 DragDropTracker::DragDropTracker(aura::Window* context_root, 56 aura::WindowDelegate* delegate) 57 : capture_window_(CreateCaptureWindow(context_root, delegate)) { 58 } 59 60 DragDropTracker::~DragDropTracker() { 61 capture_window_->ReleaseCapture(); 62 } 63 64 void DragDropTracker::TakeCapture() { 65 capture_window_->SetCapture(); 66 } 67 68 aura::Window* DragDropTracker::GetTarget(const ui::LocatedEvent& event) { 69 DCHECK(capture_window_.get()); 70 gfx::Point location_in_screen = event.location(); 71 wm::ConvertPointToScreen(capture_window_.get(), 72 &location_in_screen); 73 aura::Window* root_window_at_point = 74 wm::GetRootWindowAt(location_in_screen); 75 gfx::Point location_in_root = location_in_screen; 76 wm::ConvertPointFromScreen(root_window_at_point, &location_in_root); 77 return root_window_at_point->GetEventHandlerForPoint(location_in_root); 78 } 79 80 ui::LocatedEvent* DragDropTracker::ConvertEvent( 81 aura::Window* target, 82 const ui::LocatedEvent& event) { 83 DCHECK(capture_window_.get()); 84 gfx::Point target_location = event.location(); 85 aura::Window::ConvertPointToTarget(capture_window_.get(), target, 86 &target_location); 87 gfx::Point location_in_screen = event.location(); 88 ash::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen); 89 gfx::Point target_root_location = event.root_location(); 90 aura::Window::ConvertPointToTarget( 91 capture_window_->GetRootWindow(), 92 ash::wm::GetRootWindowAt(location_in_screen), 93 &target_root_location); 94 return new ui::MouseEvent(event.type(), 95 target_location, 96 target_root_location, 97 event.flags(), 98 static_cast<const ui::MouseEvent&>(event). 99 changed_button_flags()); 100 } 101 102 } // namespace ash 103