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/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