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