Home | History | Annotate | Download | only in desktop_aura
      1 // Copyright (c) 2013 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 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_X11_WHOLE_SCREEN_MOVE_LOOP_H_
      6 #define UI_VIEWS_WIDGET_DESKTOP_AURA_X11_WHOLE_SCREEN_MOVE_LOOP_H_
      7 
      8 #include "base/callback.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/memory/weak_ptr.h"
     11 #include "ui/events/platform/platform_event_dispatcher.h"
     12 #include "ui/gfx/image/image_skia.h"
     13 #include "ui/gfx/native_widget_types.h"
     14 #include "ui/gfx/vector2d_f.h"
     15 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop_delegate.h"
     16 
     17 typedef struct _XDisplay XDisplay;
     18 
     19 namespace aura {
     20 class Window;
     21 }
     22 
     23 namespace ui {
     24 class ScopedEventDispatcher;
     25 }
     26 
     27 namespace views {
     28 
     29 class Widget;
     30 
     31 // Runs a nested message loop and grabs the mouse. This is used to implement
     32 // dragging.
     33 class X11WholeScreenMoveLoop : public ui::PlatformEventDispatcher {
     34  public:
     35   explicit X11WholeScreenMoveLoop(X11WholeScreenMoveLoopDelegate* delegate);
     36   virtual ~X11WholeScreenMoveLoop();
     37 
     38   // ui:::PlatformEventDispatcher:
     39   virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
     40   virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
     41 
     42   // Runs the nested message loop. While the mouse is grabbed, use |cursor| as
     43   // the mouse cursor. Returns true if the move-loop is completed successfully.
     44   // If the pointer-grab fails, or the move-loop is canceled by the user (e.g.
     45   // by pressing escape), then returns false.
     46   bool RunMoveLoop(aura::Window* window, gfx::NativeCursor cursor);
     47 
     48   // Updates the cursor while the move loop is running.
     49   void UpdateCursor(gfx::NativeCursor cursor);
     50 
     51   // Ends the RunMoveLoop() that's currently in progress.
     52   void EndMoveLoop();
     53 
     54   // Sets an image to be used during the drag.
     55   void SetDragImage(const gfx::ImageSkia& image, gfx::Vector2dF offset);
     56 
     57  private:
     58   // Grabs the pointer and keyboard, setting the mouse cursor to |cursor|.
     59   // Returns true if the grab was successful.
     60   bool GrabPointerAndKeyboard(gfx::NativeCursor cursor);
     61 
     62   // Creates an input-only window to be used during the drag.
     63   Window CreateDragInputWindow(XDisplay* display);
     64 
     65   // Creates a window to show the drag image during the drag.
     66   void CreateDragImageWindow();
     67 
     68   // Checks to see if |in_image| is an image that has any visible regions
     69   // (defined as having a pixel with alpha > 32). If so, return true.
     70   bool CheckIfIconValid();
     71 
     72   // Dispatch mouse movement event to |delegate_| in a posted task.
     73   void DispatchMouseMovement();
     74 
     75   X11WholeScreenMoveLoopDelegate* delegate_;
     76 
     77   // Are we running a nested message loop from RunMoveLoop()?
     78   bool in_move_loop_;
     79   scoped_ptr<ui::ScopedEventDispatcher> nested_dispatcher_;
     80 
     81   bool should_reset_mouse_flags_;
     82 
     83   // An invisible InputOnly window . We create this window so we can track the
     84   // cursor wherever it goes on screen during a drag, since normal windows
     85   // don't receive pointer motion events outside of their bounds.
     86   ::Window grab_input_window_;
     87 
     88   base::Closure quit_closure_;
     89 
     90   // Keeps track of whether the move-loop is cancled by the user (e.g. by
     91   // pressing escape).
     92   bool canceled_;
     93 
     94   // Keeps track of whether we still have a pointer grab at the end of the loop.
     95   bool has_grab_;
     96 
     97   // A Widget is created during the drag if there is an image available to be
     98   // used during the drag.
     99   scoped_ptr<Widget> drag_widget_;
    100   gfx::ImageSkia drag_image_;
    101   gfx::Vector2dF drag_offset_;
    102   XMotionEvent last_xmotion_;
    103   base::WeakPtrFactory<X11WholeScreenMoveLoop> weak_factory_;
    104 
    105   DISALLOW_COPY_AND_ASSIGN(X11WholeScreenMoveLoop);
    106 };
    107 
    108 }  // namespace views
    109 
    110 #endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_X11_WHOLE_SCREEN_MOVE_LOOP_H_
    111