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.
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_
8 #include <X11/extensions/shape.h>
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/geometry/insets.h"
20 #include "ui/gfx/geometry/rect.h"
21 #include "ui/gfx/geometry/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"
36 class DesktopDragDropClientAuraX11
;
37 class DesktopDispatcherClient
;
38 class DesktopWindowTreeHostObserverX11
;
39 class X11DesktopWindowMoveClient
;
40 class X11WindowEventFilter
;
42 class VIEWS_EXPORT DesktopWindowTreeHostX11
43 : public DesktopWindowTreeHost
,
44 public aura::WindowTreeHost
,
45 public ui::EventSource
,
46 public ui::PlatformEventDispatcher
{
48 DesktopWindowTreeHostX11(
49 internal::NativeWidgetDelegate
* native_widget_delegate
,
50 DesktopNativeWidgetAura
* desktop_native_widget_aura
);
51 ~DesktopWindowTreeHostX11() override
;
53 // A way of converting an X11 |xid| host window into a |content_window_|.
54 static aura::Window
* GetContentWindowForXID(XID xid
);
56 // A way of converting an X11 |xid| host window into this object.
57 static DesktopWindowTreeHostX11
* GetHostForXID(XID xid
);
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();
64 // Returns the current bounds in terms of the X11 Root Window.
65 gfx::Rect
GetX11RootWindowBounds() const;
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;
71 // Returns the window shape if the window is not rectangular. Returns NULL
73 ::Region
GetWindowShape() const;
75 // Called by X11DesktopHandler to notify us that the native windowing system
76 // has changed our activation.
77 void HandleNativeWidgetActivationChanged(bool active
);
79 void AddObserver(views::DesktopWindowTreeHostObserverX11
* observer
);
80 void RemoveObserver(views::DesktopWindowTreeHostObserverX11
* observer
);
82 // Swaps the current handler for events in the non client view with |handler|.
83 void SwapNonClientEventHandler(scoped_ptr
<ui::EventHandler
> handler
);
85 // Deallocates the internal list of open windows.
86 static void CleanUpWindowList();
89 // Overridden from DesktopWindowTreeHost:
90 void Init(aura::Window
* content_window
,
91 const Widget::InitParams
& params
) override
;
92 void OnNativeWidgetCreated(const Widget::InitParams
& params
) override
;
93 scoped_ptr
<corewm::Tooltip
> CreateTooltip() override
;
94 scoped_ptr
<aura::client::DragDropClient
> CreateDragDropClient(
95 DesktopNativeCursorManager
* cursor_manager
) override
;
96 void Close() override
;
97 void CloseNow() override
;
98 aura::WindowTreeHost
* AsWindowTreeHost() override
;
99 void ShowWindowWithState(ui::WindowShowState show_state
) override
;
100 void ShowMaximizedWithBounds(const gfx::Rect
& restored_bounds
) override
;
101 bool IsVisible() const override
;
102 void SetSize(const gfx::Size
& requested_size
) override
;
103 void StackAtTop() override
;
104 void CenterWindow(const gfx::Size
& size
) override
;
105 void GetWindowPlacement(gfx::Rect
* bounds
,
106 ui::WindowShowState
* show_state
) const override
;
107 gfx::Rect
GetWindowBoundsInScreen() const override
;
108 gfx::Rect
GetClientAreaBoundsInScreen() const override
;
109 gfx::Rect
GetRestoredBounds() const override
;
110 gfx::Rect
GetWorkAreaBoundsInScreen() const override
;
111 void SetShape(gfx::NativeRegion native_region
) override
;
112 void Activate() override
;
113 void Deactivate() override
;
114 bool IsActive() const override
;
115 void Maximize() override
;
116 void Minimize() override
;
117 void Restore() override
;
118 bool IsMaximized() const override
;
119 bool IsMinimized() const override
;
120 bool HasCapture() const override
;
121 void SetAlwaysOnTop(bool always_on_top
) override
;
122 bool IsAlwaysOnTop() const override
;
123 void SetVisibleOnAllWorkspaces(bool always_visible
) override
;
124 bool SetWindowTitle(const base::string16
& title
) override
;
125 void ClearNativeFocus() override
;
126 Widget::MoveLoopResult
RunMoveLoop(
127 const gfx::Vector2d
& drag_offset
,
128 Widget::MoveLoopSource source
,
129 Widget::MoveLoopEscapeBehavior escape_behavior
) override
;
130 void EndMoveLoop() override
;
131 void SetVisibilityChangedAnimationsEnabled(bool value
) override
;
132 bool ShouldUseNativeFrame() const override
;
133 bool ShouldWindowContentsBeTransparent() const override
;
134 void FrameTypeChanged() override
;
135 void SetFullscreen(bool fullscreen
) override
;
136 bool IsFullscreen() const override
;
137 void SetOpacity(unsigned char opacity
) override
;
138 void SetWindowIcons(const gfx::ImageSkia
& window_icon
,
139 const gfx::ImageSkia
& app_icon
) override
;
140 void InitModalType(ui::ModalType modal_type
) override
;
141 void FlashFrame(bool flash_frame
) override
;
142 void OnRootViewLayout() override
;
143 void OnNativeWidgetFocus() override
;
144 void OnNativeWidgetBlur() override
;
145 bool IsAnimatingClosed() const override
;
146 bool IsTranslucentWindowOpacitySupported() const override
;
147 void SizeConstraintsChanged() override
;
149 // Overridden from aura::WindowTreeHost:
150 gfx::Transform
GetRootTransform() const override
;
151 ui::EventSource
* GetEventSource() override
;
152 gfx::AcceleratedWidget
GetAcceleratedWidget() override
;
153 void Show() override
;
154 void Hide() override
;
155 gfx::Rect
GetBounds() const override
;
156 void SetBounds(const gfx::Rect
& requested_bounds_in_pixels
) override
;
157 gfx::Point
GetLocationOnNativeScreen() const override
;
158 void SetCapture() override
;
159 void ReleaseCapture() override
;
160 void SetCursorNative(gfx::NativeCursor cursor
) override
;
161 void MoveCursorToNative(const gfx::Point
& location
) override
;
162 void OnCursorVisibilityChangedNative(bool show
) override
;
164 // Overridden frm ui::EventSource
165 ui::EventProcessor
* GetEventProcessor() override
;
168 friend class DesktopWindowTreeHostX11HighDPITest
;
169 // Initializes our X11 surface to draw on. This method performs all
170 // initialization related to talking to the X11 server.
171 void InitX11Window(const Widget::InitParams
& params
);
173 // Creates an aura::WindowEventDispatcher to contain the |content_window|,
174 // along with all aura client objects that direct behavior.
175 aura::WindowEventDispatcher
* InitDispatcher(const Widget::InitParams
& params
);
177 // Adjusts |requested_size| to avoid the WM "feature" where setting the
178 // window size to the monitor size causes the WM to set the EWMH for
180 gfx::Size
AdjustSize(const gfx::Size
& requested_size
);
182 // Called when |xwindow_|'s _NET_WM_STATE property is updated.
183 void OnWMStateUpdated();
185 // Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
186 void OnFrameExtentsUpdated();
188 // Updates |xwindow_|'s minimum and maximum size.
189 void UpdateMinAndMaxSize();
191 // Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
192 void UpdateWMUserTime(const ui::PlatformEvent
& event
);
194 // Sends a message to the x11 window manager, enabling or disabling the
195 // states |state1| and |state2|.
196 void SetWMSpecState(bool enabled
, ::Atom state1
, ::Atom state2
);
198 // Checks if the window manager has set a specific state.
199 bool HasWMSpecProperty(const char* property
) const;
201 // Sets whether the window's borders are provided by the window manager.
202 void SetUseNativeFrame(bool use_native_frame
);
204 // Dispatches a mouse event, taking mouse capture into account. If a
205 // different host has capture, we translate the event to its coordinate space
206 // and dispatch it to that host instead.
207 void DispatchMouseEvent(ui::MouseEvent
* event
);
209 // Dispatches a touch event, taking capture into account. If a different host
210 // has capture, then touch-press events are translated to its coordinate space
211 // and dispatched to that host instead.
212 void DispatchTouchEvent(ui::TouchEvent
* event
);
214 // Updates the location of |located_event| to be in |host|'s coordinate system
215 // so that it can be dispatched to |host|.
216 void ConvertEventToDifferentHost(ui::LocatedEvent
* located_event
,
217 DesktopWindowTreeHostX11
* host
);
219 // Resets the window region for the current widget bounds if necessary.
220 void ResetWindowRegion();
222 // Serializes an image to the format used by _NET_WM_ICON.
223 void SerializeImageRepresentation(const gfx::ImageSkiaRep
& rep
,
224 std::vector
<unsigned long>* data
);
226 // Returns an 8888 ARGB visual. Can return NULL if there is no matching
227 // visual on this display.
228 Visual
* GetARGBVisual();
230 // See comment for variable open_windows_.
231 static std::list
<XID
>& open_windows();
233 // Map the window (shows it) taking into account the given |show_state|.
234 void MapWindow(ui::WindowShowState show_state
);
236 void SetWindowTransparency();
238 // Relayout the widget's client and non-client views.
241 // ui::PlatformEventDispatcher:
242 bool CanDispatchEvent(const ui::PlatformEvent
& event
) override
;
243 uint32_t DispatchEvent(const ui::PlatformEvent
& event
) override
;
245 void DelayedResize(const gfx::Size
& size_in_pixels
);
247 gfx::Rect
GetWorkAreaBoundsInPixels() const;
248 gfx::Rect
ToDIPRect(const gfx::Rect
& rect_in_pixels
) const;
249 gfx::Rect
ToPixelRect(const gfx::Rect
& rect_in_dip
) const;
252 // The display and the native X window hosting the root window.
256 // The native root window.
257 ::Window x_root_window_
;
259 ui::X11AtomCache atom_cache_
;
261 // Is the window mapped to the screen?
264 // The bounds of |xwindow_|.
265 gfx::Rect bounds_in_pixels_
;
267 // Whenever the bounds are set, we keep the previous set of bounds around so
268 // we can have a better chance of getting the real
269 // |restored_bounds_in_pixels_|. Window managers tend to send a Configure
270 // message with the maximized bounds, and then set the window maximized
271 // property. (We don't rely on this for when we request that the window be
272 // maximized, only when we detect that some other process has requested that
273 // we become the maximized window.)
274 gfx::Rect previous_bounds_in_pixels_
;
276 // The bounds of our window before we were maximized.
277 gfx::Rect restored_bounds_in_pixels_
;
279 // |xwindow_|'s minimum size.
280 gfx::Size min_size_in_pixels_
;
282 // |xwindow_|'s maximum size.
283 gfx::Size max_size_in_pixels_
;
285 // The window manager state bits.
286 std::set
< ::Atom
> window_properties_
;
288 // Whether |xwindow_| was requested to be fullscreen via SetFullscreen().
291 // True if the window should stay on top of most other windows.
292 bool is_always_on_top_
;
294 // True if the window has title-bar / borders provided by the window manager.
295 bool use_native_frame_
;
297 // True if a Maximize() call should be done after mapping the window.
298 bool should_maximize_after_map_
;
300 // Whether we used an ARGB visual for our window.
301 bool use_argb_visual_
;
303 DesktopDragDropClientAuraX11
* drag_drop_client_
;
305 scoped_ptr
<ui::EventHandler
> x11_non_client_event_filter_
;
306 scoped_ptr
<X11DesktopWindowMoveClient
> x11_window_move_client_
;
308 // TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
309 // instead of providing this route back to Widget.
310 internal::NativeWidgetDelegate
* native_widget_delegate_
;
312 DesktopNativeWidgetAura
* desktop_native_widget_aura_
;
314 aura::Window
* content_window_
;
316 // We can optionally have a parent which can order us to close, or own
317 // children who we're responsible for closing when we CloseNow().
318 DesktopWindowTreeHostX11
* window_parent_
;
319 std::set
<DesktopWindowTreeHostX11
*> window_children_
;
321 ObserverList
<DesktopWindowTreeHostObserverX11
> observer_list_
;
323 // The window shape if the window is non-rectangular.
324 ::Region window_shape_
;
326 // Whether |window_shape_| was set via SetShape().
327 bool custom_window_shape_
;
329 // The size of the window manager provided borders (if any).
330 gfx::Insets native_window_frame_borders_in_pixels_
;
332 // The current DesktopWindowTreeHostX11 which has capture. Set synchronously
333 // when capture is requested via SetCapture().
334 static DesktopWindowTreeHostX11
* g_current_capture
;
336 // A list of all (top-level) windows that have been created but not yet
338 static std::list
<XID
>* open_windows_
;
340 base::string16 window_title_
;
342 // Whether we currently are flashing our frame. This feature is implemented
343 // by setting the urgency hint with the window manager, which can draw
344 // attention to the window or completely ignore the hint. We stop flashing
345 // the frame when |xwindow_| gains focus or handles a mouse button event.
346 bool urgency_hint_set_
;
348 base::CancelableCallback
<void()> delayed_resize_task_
;
350 base::WeakPtrFactory
<DesktopWindowTreeHostX11
> close_widget_factory_
;
352 DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11
);
357 #endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_