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/size.h"
     22 #include "ui/gfx/x/x11_atom_cache.h"
     23 #include "ui/views/views_export.h"
     24 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
     25 
     26 namespace gfx {
     27 class ImageSkia;
     28 class ImageSkiaRep;
     29 }
     30 
     31 namespace ui {
     32 class EventHandler;
     33 }
     34 
     35 namespace views {
     36 class DesktopDragDropClientAuraX11;
     37 class DesktopDispatcherClient;
     38 class DesktopWindowTreeHostObserverX11;
     39 class X11DesktopWindowMoveClient;
     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& requested_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() OVERRIDE;
    145   virtual void OnNativeWidgetFocus() OVERRIDE;
    146   virtual void OnNativeWidgetBlur() OVERRIDE;
    147   virtual bool IsAnimatingClosed() const OVERRIDE;
    148   virtual bool IsTranslucentWindowOpacitySupported() const OVERRIDE;
    149   virtual void SizeConstraintsChanged() OVERRIDE;
    150 
    151   // Overridden from aura::WindowTreeHost:
    152   virtual ui::EventSource* GetEventSource() OVERRIDE;
    153   virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
    154   virtual void Show() OVERRIDE;
    155   virtual void Hide() OVERRIDE;
    156   virtual gfx::Rect GetBounds() const OVERRIDE;
    157   virtual void SetBounds(const gfx::Rect& requested_bounds) OVERRIDE;
    158   virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
    159   virtual void SetCapture() OVERRIDE;
    160   virtual void ReleaseCapture() OVERRIDE;
    161   virtual void PostNativeEvent(const base::NativeEvent& native_event) 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   // Adjusts |requested_size| to avoid the WM "feature" where setting the
    179   // window size to the monitor size causes the WM to set the EWMH for
    180   // fullscreen.
    181   gfx::Size AdjustSize(const gfx::Size& requested_size);
    182 
    183   // Called when |xwindow_|'s _NET_WM_STATE property is updated.
    184   void OnWMStateUpdated();
    185 
    186   // Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
    187   void OnFrameExtentsUpdated();
    188 
    189   // Updates |xwindow_|'s minimum and maximum size.
    190   void UpdateMinAndMaxSize();
    191 
    192   // Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
    193   void UpdateWMUserTime(const ui::PlatformEvent& event);
    194 
    195   // Sends a message to the x11 window manager, enabling or disabling the
    196   // states |state1| and |state2|.
    197   void SetWMSpecState(bool enabled, ::Atom state1, ::Atom state2);
    198 
    199   // Checks if the window manager has set a specific state.
    200   bool HasWMSpecProperty(const char* property) const;
    201 
    202   // Sets whether the window's borders are provided by the window manager.
    203   void SetUseNativeFrame(bool use_native_frame);
    204 
    205   // Dispatches a mouse event, taking mouse capture into account. If a
    206   // different host has capture, we translate the event to its coordinate space
    207   // and dispatch it to that host instead.
    208   void DispatchMouseEvent(ui::MouseEvent* event);
    209 
    210   // Dispatches a touch event, taking capture into account. If a different host
    211   // has capture, then touch-press events are translated to its coordinate space
    212   // and dispatched to that host instead.
    213   void DispatchTouchEvent(ui::TouchEvent* event);
    214 
    215   // Resets the window region for the current widget bounds if necessary.
    216   void ResetWindowRegion();
    217 
    218   // Serializes an image to the format used by _NET_WM_ICON.
    219   void SerializeImageRepresentation(const gfx::ImageSkiaRep& rep,
    220                                     std::vector<unsigned long>* data);
    221 
    222   // Returns an 8888 ARGB visual. Can return NULL if there is no matching
    223   // visual on this display.
    224   Visual* GetARGBVisual();
    225 
    226   // See comment for variable open_windows_.
    227   static std::list<XID>& open_windows();
    228 
    229   // Map the window (shows it) taking into account the given |show_state|.
    230   void MapWindow(ui::WindowShowState show_state);
    231 
    232   void SetWindowTransparency();
    233 
    234   // Relayout the widget's client and non-client views.
    235   void Relayout();
    236 
    237   // ui::PlatformEventDispatcher:
    238   virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
    239   virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
    240 
    241   void DelayedResize(const gfx::Size& size);
    242 
    243   // X11 things
    244   // The display and the native X window hosting the root window.
    245   XDisplay* xdisplay_;
    246   ::Window xwindow_;
    247 
    248   // The native root window.
    249   ::Window x_root_window_;
    250 
    251   ui::X11AtomCache atom_cache_;
    252 
    253   // Is the window mapped to the screen?
    254   bool window_mapped_;
    255 
    256   // The bounds of |xwindow_|.
    257   gfx::Rect bounds_;
    258 
    259   // Whenever the bounds are set, we keep the previous set of bounds around so
    260   // we can have a better chance of getting the real |restored_bounds_|. Window
    261   // managers tend to send a Configure message with the maximized bounds, and
    262   // then set the window maximized property. (We don't rely on this for when we
    263   // request that the window be maximized, only when we detect that some other
    264   // process has requested that we become the maximized window.)
    265   gfx::Rect previous_bounds_;
    266 
    267   // The bounds of our window before we were maximized.
    268   gfx::Rect restored_bounds_;
    269 
    270   // |xwindow_|'s minimum size.
    271   gfx::Size min_size_;
    272 
    273   // |xwindow_|'s maximum size.
    274   gfx::Size max_size_;
    275 
    276   // The window manager state bits.
    277   std::set< ::Atom> window_properties_;
    278 
    279   // Whether |xwindow_| was requested to be fullscreen via SetFullscreen().
    280   bool is_fullscreen_;
    281 
    282   // True if the window should stay on top of most other windows.
    283   bool is_always_on_top_;
    284 
    285   // True if the window has title-bar / borders provided by the window manager.
    286   bool use_native_frame_;
    287 
    288   // True if a Maximize() call should be done after mapping the window.
    289   bool should_maximize_after_map_;
    290 
    291   // Whether we used an ARGB visual for our window.
    292   bool use_argb_visual_;
    293 
    294   DesktopDragDropClientAuraX11* drag_drop_client_;
    295 
    296   scoped_ptr<ui::EventHandler> x11_non_client_event_filter_;
    297   scoped_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
    298 
    299   // TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
    300   //             instead of providing this route back to Widget.
    301   internal::NativeWidgetDelegate* native_widget_delegate_;
    302 
    303   DesktopNativeWidgetAura* desktop_native_widget_aura_;
    304 
    305   aura::Window* content_window_;
    306 
    307   // We can optionally have a parent which can order us to close, or own
    308   // children who we're responsible for closing when we CloseNow().
    309   DesktopWindowTreeHostX11* window_parent_;
    310   std::set<DesktopWindowTreeHostX11*> window_children_;
    311 
    312   ObserverList<DesktopWindowTreeHostObserverX11> observer_list_;
    313 
    314   // The window shape if the window is non-rectangular.
    315   ::Region window_shape_;
    316 
    317   // Whether |window_shape_| was set via SetShape().
    318   bool custom_window_shape_;
    319 
    320   // The size of the window manager provided borders (if any).
    321   gfx::Insets native_window_frame_borders_;
    322 
    323   // The current DesktopWindowTreeHostX11 which has capture. Set synchronously
    324   // when capture is requested via SetCapture().
    325   static DesktopWindowTreeHostX11* g_current_capture;
    326 
    327   // A list of all (top-level) windows that have been created but not yet
    328   // destroyed.
    329   static std::list<XID>* open_windows_;
    330 
    331   base::string16 window_title_;
    332 
    333   // Whether we currently are flashing our frame. This feature is implemented
    334   // by setting the urgency hint with the window manager, which can draw
    335   // attention to the window or completely ignore the hint. We stop flashing
    336   // the frame when |xwindow_| gains focus or handles a mouse button event.
    337   bool urgency_hint_set_;
    338 
    339   base::CancelableCallback<void()> delayed_resize_task_;
    340 
    341   base::WeakPtrFactory<DesktopWindowTreeHostX11> close_widget_factory_;
    342 
    343   DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11);
    344 };
    345 
    346 }  // namespace views
    347 
    348 #endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_
    349