Home | History | Annotate | Download | only in drag_drop
      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 
     18 namespace ash {
     19 namespace {
     20 
     21 // An activation delegate which disables activating the drag and drop window.
     22 class 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.
     39 aura::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 
     58 DragDropTracker::DragDropTracker(aura::Window* context_root,
     59                                  aura::WindowDelegate* delegate)
     60     : capture_window_(CreateCaptureWindow(context_root, delegate)) {
     61 }
     62 
     63 DragDropTracker::~DragDropTracker()  {
     64   capture_window_->ReleaseCapture();
     65 }
     66 
     67 void DragDropTracker::TakeCapture() {
     68   capture_window_->SetCapture();
     69 }
     70 
     71 aura::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 
     82 ui::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