Home | History | Annotate | Download | only in desktop_aura
      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 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_
      6 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_
      7 
      8 #include <X11/extensions/shape.h>
      9 #include <X11/Xlib.h>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/cancelable_callback.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/observer_list.h"
     15 #include "ui/aura/window_tree_host.h"
     16 #include "ui/base/cursor/cursor_loader_x11.h"
     17 #include "ui/events/event_source.h"
     18 #include "ui/events/platform/platform_event_dispatcher.h"
     19 #include "ui/gfx/insets.h"
     20 #include "ui/gfx/rect.h"
     21 #include "ui/gfx/x/x11_atom_cache.h"
     22 #include "ui/views/views_export.h"
     23 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
     24 
     25 namespace gfx {
     26 class ImageSkia;
     27 class ImageSkiaRep;
     28 }
     29 
     30 namespace ui {
     31 class EventHandler;
     32 }
     33 
     34 namespace views {
     35 class DesktopDragDropClientAuraX11;
     36 class DesktopDispatcherClient;
     37 class DesktopWindowTreeHostObserverX11;
     38 class X11DesktopWindowMoveClient;
     39 class X11ScopedCapture;
     40 class X11WindowEventFilter;
     41 
     42 class VIEWS_EXPORT DesktopWindowTreeHostX11
     43     : public DesktopWindowTreeHost,
     44       public aura::WindowTreeHost,
     45       public ui::EventSource,
     46       public ui::PlatformEventDispatcher {
     47  public:
     48   DesktopWindowTreeHostX11(
     49       internal::NativeWidgetDelegate* native_widget_delegate,
     50       DesktopNativeWidgetAura* desktop_native_widget_aura);
     51   virtual ~DesktopWindowTreeHostX11();
     52 
     53   // A way of converting an X11 |xid| host window into a |content_window_|.
     54   static aura::Window* GetContentWindowForXID(XID xid);
     55 
     56   // A way of converting an X11 |xid| host window into this object.
     57   static DesktopWindowTreeHostX11* GetHostForXID(XID xid);
     58 
     59   // Get all open top-level windows. This includes windows that may not be
     60   // visible. This list is sorted in their stacking order, i.e. the first window
     61   // is the topmost window.
     62   static std::vector<aura::Window*> GetAllOpenWindows();
     63 
     64   // Returns the current bounds in terms of the X11 Root Window.
     65   gfx::Rect GetX11RootWindowBounds() const;
     66 
     67   // Returns the current bounds in terms of the X11 Root Window including the
     68   // borders provided by the window manager (if any).
     69   gfx::Rect GetX11RootWindowOuterBounds() const;
     70 
     71   // Returns the window shape if the window is not rectangular. Returns NULL
     72   // otherwise.
     73   ::Region GetWindowShape() const;
     74 
     75   // Called by X11DesktopHandler to notify us that the native windowing system
     76   // has changed our activation.
     77   void HandleNativeWidgetActivationChanged(bool active);
     78 
     79   void AddObserver(views::DesktopWindowTreeHostObserverX11* observer);
     80   void RemoveObserver(views::DesktopWindowTreeHostObserverX11* observer);
     81 
     82   // Swaps the current handler for events in the non client view with |handler|.
     83   void SwapNonClientEventHandler(scoped_ptr<ui::EventHandler> handler);
     84 
     85   // Deallocates the internal list of open windows.
     86   static void CleanUpWindowList();
     87 
     88  protected:
     89   // Overridden from DesktopWindowTreeHost:
     90   virtual void Init(aura::Window* content_window,
     91                     const Widget::InitParams& params) OVERRIDE;
     92   virtual void OnNativeWidgetCreated(const Widget::InitParams& params) OVERRIDE;
     93   virtual scoped_ptr<corewm::Tooltip> CreateTooltip() OVERRIDE;
     94   virtual scoped_ptr<aura::client::DragDropClient>
     95       CreateDragDropClient(DesktopNativeCursorManager* cursor_manager) OVERRIDE;
     96   virtual void Close() OVERRIDE;
     97   virtual void CloseNow() OVERRIDE;
     98   virtual aura::WindowTreeHost* AsWindowTreeHost() OVERRIDE;
     99   virtual void ShowWindowWithState(ui::WindowShowState show_state) OVERRIDE;
    100   virtual void ShowMaximizedWithBounds(
    101       const gfx::Rect& restored_bounds) OVERRIDE;
    102   virtual bool IsVisible() const OVERRIDE;
    103   virtual void SetSize(const gfx::Size& size) OVERRIDE;
    104   virtual void StackAtTop() OVERRIDE;
    105   virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
    106   virtual void GetWindowPlacement(
    107       gfx::Rect* bounds,
    108       ui::WindowShowState* show_state) const OVERRIDE;
    109   virtual gfx::Rect GetWindowBoundsInScreen() const OVERRIDE;
    110   virtual gfx::Rect GetClientAreaBoundsInScreen() const OVERRIDE;
    111   virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
    112   virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
    113   virtual void SetShape(gfx::NativeRegion native_region) OVERRIDE;
    114   virtual void Activate() OVERRIDE;
    115   virtual void Deactivate() OVERRIDE;
    116   virtual bool IsActive() const OVERRIDE;
    117   virtual void Maximize() OVERRIDE;
    118   virtual void Minimize() OVERRIDE;
    119   virtual void Restore() OVERRIDE;
    120   virtual bool IsMaximized() const OVERRIDE;
    121   virtual bool IsMinimized() const OVERRIDE;
    122   virtual bool HasCapture() const OVERRIDE;
    123   virtual void SetAlwaysOnTop(bool always_on_top) OVERRIDE;
    124   virtual bool IsAlwaysOnTop() const OVERRIDE;
    125   virtual void SetVisibleOnAllWorkspaces(bool always_visible) OVERRIDE;
    126   virtual bool SetWindowTitle(const base::string16& title) OVERRIDE;
    127   virtual void ClearNativeFocus() OVERRIDE;
    128   virtual Widget::MoveLoopResult RunMoveLoop(
    129       const gfx::Vector2d& drag_offset,
    130       Widget::MoveLoopSource source,
    131       Widget::MoveLoopEscapeBehavior escape_behavior) OVERRIDE;
    132   virtual void EndMoveLoop() OVERRIDE;
    133   virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
    134   virtual bool ShouldUseNativeFrame() const OVERRIDE;
    135   virtual bool ShouldWindowContentsBeTransparent() const OVERRIDE;
    136   virtual void FrameTypeChanged() OVERRIDE;
    137   virtual void SetFullscreen(bool fullscreen) OVERRIDE;
    138   virtual bool IsFullscreen() const OVERRIDE;
    139   virtual void SetOpacity(unsigned char opacity) OVERRIDE;
    140   virtual void SetWindowIcons(const gfx::ImageSkia& window_icon,
    141                               const gfx::ImageSkia& app_icon) OVERRIDE;
    142   virtual void InitModalType(ui::ModalType modal_type) OVERRIDE;
    143   virtual void FlashFrame(bool flash_frame) OVERRIDE;
    144   virtual void OnRootViewLayout() const OVERRIDE;
    145   virtual void OnNativeWidgetFocus() OVERRIDE;
    146   virtual void OnNativeWidgetBlur() OVERRIDE;
    147   virtual bool IsAnimatingClosed() const OVERRIDE;
    148   virtual bool IsTranslucentWindowOpacitySupported() const OVERRIDE;
    149 
    150   // Overridden from aura::WindowTreeHost:
    151   virtual ui::EventSource* GetEventSource() OVERRIDE;
    152   virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
    153   virtual void Show() OVERRIDE;
    154   virtual void Hide() OVERRIDE;
    155   virtual gfx::Rect GetBounds() const OVERRIDE;
    156   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
    157   virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
    158   virtual void SetCapture() OVERRIDE;
    159   virtual void ReleaseCapture() OVERRIDE;
    160   virtual void PostNativeEvent(const base::NativeEvent& native_event) OVERRIDE;
    161   virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
    162   virtual void SetCursorNative(gfx::NativeCursor cursor) OVERRIDE;
    163   virtual void MoveCursorToNative(const gfx::Point& location) OVERRIDE;
    164   virtual void OnCursorVisibilityChangedNative(bool show) OVERRIDE;
    165 
    166   // Overridden frm ui::EventSource
    167   virtual ui::EventProcessor* GetEventProcessor() OVERRIDE;
    168 
    169  private:
    170   // Initializes our X11 surface to draw on. This method performs all
    171   // initialization related to talking to the X11 server.
    172   void InitX11Window(const Widget::InitParams& params);
    173 
    174   // Creates an aura::WindowEventDispatcher to contain the |content_window|,
    175   // along with all aura client objects that direct behavior.
    176   aura::WindowEventDispatcher* InitDispatcher(const Widget::InitParams& params);
    177 
    178   // Called when |xwindow_|'s _NET_WM_STATE property is updated.
    179   void OnWMStateUpdated();
    180 
    181   // Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
    182   void OnFrameExtentsUpdated();
    183 
    184   // Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
    185   void UpdateWMUserTime(const ui::PlatformEvent& event);
    186 
    187   // Sends a message to the x11 window manager, enabling or disabling the
    188   // states |state1| and |state2|.
    189   void SetWMSpecState(bool enabled, ::Atom state1, ::Atom state2);
    190 
    191   // Checks if the window manager has set a specific state.
    192   bool HasWMSpecProperty(const char* property) const;
    193 
    194   // Sets whether the window's borders are provided by the window manager.
    195   void SetUseNativeFrame(bool use_native_frame);
    196 
    197   // Called when another DRWHL takes capture, or when capture is released
    198   // entirely.
    199   void OnCaptureReleased();
    200 
    201   // Dispatches a mouse event, taking mouse capture into account. If a
    202   // different host has capture, we translate the event to its coordinate space
    203   // and dispatch it to that host instead.
    204   void DispatchMouseEvent(ui::MouseEvent* event);
    205 
    206   // Dispatches a touch event, taking capture into account. If a different host
    207   // has capture, then touch-press events are translated to its coordinate space
    208   // and dispatched to that host instead.
    209   void DispatchTouchEvent(ui::TouchEvent* event);
    210 
    211   // Resets the window region for the current widget bounds if necessary.
    212   void ResetWindowRegion();
    213 
    214   // Serializes an image to the format used by _NET_WM_ICON.
    215   void SerializeImageRepresentation(const gfx::ImageSkiaRep& rep,
    216                                     std::vector<unsigned long>* data);
    217 
    218   // Returns an 8888 ARGB visual. Can return NULL if there is no matching
    219   // visual on this display.
    220   Visual* GetARGBVisual();
    221 
    222   // See comment for variable open_windows_.
    223   static std::list<XID>& open_windows();
    224 
    225   // Map the window (shows it) taking into account the given |show_state|.
    226   void MapWindow(ui::WindowShowState show_state);
    227 
    228   void SetWindowTransparency();
    229 
    230   // Relayout the widget's client and non-client views.
    231   void Relayout();
    232 
    233   // ui::PlatformEventDispatcher:
    234   virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
    235   virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
    236 
    237   void DelayedResize(const gfx::Size& size);
    238 
    239   base::WeakPtrFactory<DesktopWindowTreeHostX11> close_widget_factory_;
    240 
    241   // X11 things
    242   // The display and the native X window hosting the root window.
    243   XDisplay* xdisplay_;
    244   ::Window xwindow_;
    245 
    246   // The native root window.
    247   ::Window x_root_window_;
    248 
    249   ui::X11AtomCache atom_cache_;
    250 
    251   // Is the window mapped to the screen?
    252   bool window_mapped_;
    253 
    254   // The bounds of |xwindow_|.
    255   gfx::Rect bounds_;
    256 
    257   // Whenever the bounds are set, we keep the previous set of bounds around so
    258   // we can have a better chance of getting the real |restored_bounds_|. Window
    259   // managers tend to send a Configure message with the maximized bounds, and
    260   // then set the window maximized property. (We don't rely on this for when we
    261   // request that the window be maximized, only when we detect that some other
    262   // process has requested that we become the maximized window.)
    263   gfx::Rect previous_bounds_;
    264 
    265   // The bounds of our window before we were maximized.
    266   gfx::Rect restored_bounds_;
    267 
    268   // The window manager state bits.
    269   std::set< ::Atom> window_properties_;
    270 
    271   // Whether |xwindow_| was requested to be fullscreen via SetFullscreen().
    272   bool is_fullscreen_;
    273 
    274   // True if the window should stay on top of most other windows.
    275   bool is_always_on_top_;
    276 
    277   // True if the window has title-bar / borders provided by the window manager.
    278   bool use_native_frame_;
    279 
    280   // Whether we used an ARGB visual for our window.
    281   bool use_argb_visual_;
    282 
    283   scoped_ptr<DesktopDispatcherClient> dispatcher_client_;
    284 
    285   DesktopDragDropClientAuraX11* drag_drop_client_;
    286 
    287   // Current Aura cursor.
    288   gfx::NativeCursor current_cursor_;
    289 
    290   scoped_ptr<ui::EventHandler> x11_non_client_event_filter_;
    291   scoped_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
    292 
    293   // TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
    294   //             instead of providing this route back to Widget.
    295   internal::NativeWidgetDelegate* native_widget_delegate_;
    296 
    297   DesktopNativeWidgetAura* desktop_native_widget_aura_;
    298 
    299   aura::Window* content_window_;
    300 
    301   // We can optionally have a parent which can order us to close, or own
    302   // children who we're responsible for closing when we CloseNow().
    303   DesktopWindowTreeHostX11* window_parent_;
    304   std::set<DesktopWindowTreeHostX11*> window_children_;
    305 
    306   ObserverList<DesktopWindowTreeHostObserverX11> observer_list_;
    307 
    308   // The window shape if the window is non-rectangular.
    309   ::Region window_shape_;
    310 
    311   // Whether |window_shape_| was set via SetShape().
    312   bool custom_window_shape_;
    313 
    314   // The size of the window manager provided borders (if any).
    315   gfx::Insets native_window_frame_borders_;
    316 
    317   // The current root window host that has capture. While X11 has something
    318   // like Windows SetCapture()/ReleaseCapture(), it is entirely implicit and
    319   // there are no notifications when this changes. We need to track this so we
    320   // can notify widgets when they have lost capture, which controls a bunch of
    321   // things in views like hiding menus.
    322   static DesktopWindowTreeHostX11* g_current_capture;
    323 
    324   // A list of all (top-level) windows that have been created but not yet
    325   // destroyed.
    326   static std::list<XID>* open_windows_;
    327 
    328   scoped_ptr<X11ScopedCapture> x11_capture_;
    329 
    330   base::string16 window_title_;
    331 
    332   // Whether we currently are flashing our frame. This feature is implemented
    333   // by setting the urgency hint with the window manager, which can draw
    334   // attention to the window or completely ignore the hint. We stop flashing
    335   // the frame when |xwindow_| gains focus or handles a mouse button event.
    336   bool urgency_hint_set_;
    337 
    338   base::CancelableCallback<void()> delayed_resize_task_;
    339 
    340   DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11);
    341 };
    342 
    343 }  // namespace views
    344 
    345 #endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_
    346