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>
10 #include <X11/Xutil.h>
12 #include "base/basictypes.h"
13 #include "base/cancelable_callback.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "ui/aura/window_tree_host.h"
17 #include "ui/base/cursor/cursor_loader_x11.h"
18 #include "ui/events/event_source.h"
19 #include "ui/events/platform/platform_event_dispatcher.h"
20 #include "ui/gfx/geometry/insets.h"
21 #include "ui/gfx/geometry/rect.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "ui/gfx/x/x11_atom_cache.h"
24 #include "ui/views/views_export.h"
25 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
37 class DesktopDragDropClientAuraX11
;
38 class DesktopDispatcherClient
;
39 class DesktopWindowTreeHostObserverX11
;
40 class X11DesktopWindowMoveClient
;
41 class X11WindowEventFilter
;
43 class VIEWS_EXPORT DesktopWindowTreeHostX11
44 : public DesktopWindowTreeHost
,
45 public aura::WindowTreeHost
,
46 public ui::EventSource
,
47 public ui::PlatformEventDispatcher
{
49 DesktopWindowTreeHostX11(
50 internal::NativeWidgetDelegate
* native_widget_delegate
,
51 DesktopNativeWidgetAura
* desktop_native_widget_aura
);
52 ~DesktopWindowTreeHostX11() override
;
54 // A way of converting an X11 |xid| host window into a |content_window_|.
55 static aura::Window
* GetContentWindowForXID(XID xid
);
57 // A way of converting an X11 |xid| host window into this object.
58 static DesktopWindowTreeHostX11
* GetHostForXID(XID xid
);
60 // Get all open top-level windows. This includes windows that may not be
61 // visible. This list is sorted in their stacking order, i.e. the first window
62 // is the topmost window.
63 static std::vector
<aura::Window
*> GetAllOpenWindows();
65 // Returns the current bounds in terms of the X11 Root Window.
66 gfx::Rect
GetX11RootWindowBounds() const;
68 // Returns the current bounds in terms of the X11 Root Window including the
69 // borders provided by the window manager (if any).
70 gfx::Rect
GetX11RootWindowOuterBounds() const;
72 // Returns the window shape if the window is not rectangular. Returns NULL
74 ::Region
GetWindowShape() const;
76 // Called by X11DesktopHandler to notify us that the native windowing system
77 // has changed our activation.
78 void HandleNativeWidgetActivationChanged(bool active
);
80 void AddObserver(views::DesktopWindowTreeHostObserverX11
* observer
);
81 void RemoveObserver(views::DesktopWindowTreeHostObserverX11
* observer
);
83 // Swaps the current handler for events in the non client view with |handler|.
84 void SwapNonClientEventHandler(scoped_ptr
<ui::EventHandler
> handler
);
86 // Deallocates the internal list of open windows.
87 static void CleanUpWindowList();
90 // Overridden from DesktopWindowTreeHost:
91 void Init(aura::Window
* content_window
,
92 const Widget::InitParams
& params
) override
;
93 void OnNativeWidgetCreated(const Widget::InitParams
& params
) override
;
94 scoped_ptr
<corewm::Tooltip
> CreateTooltip() override
;
95 scoped_ptr
<aura::client::DragDropClient
> CreateDragDropClient(
96 DesktopNativeCursorManager
* cursor_manager
) override
;
97 void Close() override
;
98 void CloseNow() override
;
99 aura::WindowTreeHost
* AsWindowTreeHost() override
;
100 void ShowWindowWithState(ui::WindowShowState show_state
) override
;
101 void ShowMaximizedWithBounds(const gfx::Rect
& restored_bounds
) override
;
102 bool IsVisible() const override
;
103 void SetSize(const gfx::Size
& requested_size
) override
;
104 void StackAtTop() override
;
105 void CenterWindow(const gfx::Size
& size
) override
;
106 void GetWindowPlacement(gfx::Rect
* bounds
,
107 ui::WindowShowState
* show_state
) const override
;
108 gfx::Rect
GetWindowBoundsInScreen() const override
;
109 gfx::Rect
GetClientAreaBoundsInScreen() const override
;
110 gfx::Rect
GetRestoredBounds() const override
;
111 gfx::Rect
GetWorkAreaBoundsInScreen() const override
;
112 void SetShape(gfx::NativeRegion native_region
) override
;
113 void Activate() override
;
114 void Deactivate() override
;
115 bool IsActive() const override
;
116 void Maximize() override
;
117 void Minimize() override
;
118 void Restore() override
;
119 bool IsMaximized() const override
;
120 bool IsMinimized() const override
;
121 bool HasCapture() const override
;
122 void SetAlwaysOnTop(bool always_on_top
) override
;
123 bool IsAlwaysOnTop() const override
;
124 void SetVisibleOnAllWorkspaces(bool always_visible
) override
;
125 bool SetWindowTitle(const base::string16
& title
) override
;
126 void ClearNativeFocus() override
;
127 Widget::MoveLoopResult
RunMoveLoop(
128 const gfx::Vector2d
& drag_offset
,
129 Widget::MoveLoopSource source
,
130 Widget::MoveLoopEscapeBehavior escape_behavior
) override
;
131 void EndMoveLoop() override
;
132 void SetVisibilityChangedAnimationsEnabled(bool value
) override
;
133 bool ShouldUseNativeFrame() const override
;
134 bool ShouldWindowContentsBeTransparent() const override
;
135 void FrameTypeChanged() override
;
136 void SetFullscreen(bool fullscreen
) override
;
137 bool IsFullscreen() const override
;
138 void SetOpacity(unsigned char opacity
) override
;
139 void SetWindowIcons(const gfx::ImageSkia
& window_icon
,
140 const gfx::ImageSkia
& app_icon
) override
;
141 void InitModalType(ui::ModalType modal_type
) override
;
142 void FlashFrame(bool flash_frame
) override
;
143 void OnRootViewLayout() override
;
144 void OnNativeWidgetFocus() override
;
145 void OnNativeWidgetBlur() override
;
146 bool IsAnimatingClosed() const override
;
147 bool IsTranslucentWindowOpacitySupported() const override
;
148 void SizeConstraintsChanged() override
;
150 // Overridden from aura::WindowTreeHost:
151 gfx::Transform
GetRootTransform() const override
;
152 ui::EventSource
* GetEventSource() override
;
153 gfx::AcceleratedWidget
GetAcceleratedWidget() override
;
154 void Show() override
;
155 void Hide() override
;
156 gfx::Rect
GetBounds() const override
;
157 void SetBounds(const gfx::Rect
& requested_bounds_in_pixels
) override
;
158 gfx::Point
GetLocationOnNativeScreen() const override
;
159 void SetCapture() override
;
160 void ReleaseCapture() override
;
161 void SetCursorNative(gfx::NativeCursor cursor
) override
;
162 void MoveCursorToNative(const gfx::Point
& location
) override
;
163 void OnCursorVisibilityChangedNative(bool show
) override
;
165 // Overridden frm ui::EventSource
166 ui::EventProcessor
* GetEventProcessor() override
;
169 friend class DesktopWindowTreeHostX11HighDPITest
;
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
);
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
);
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
181 gfx::Size
AdjustSize(const gfx::Size
& requested_size
);
183 // Called when |xwindow_|'s _NET_WM_STATE property is updated.
184 void OnWMStateUpdated();
186 // Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
187 void OnFrameExtentsUpdated();
189 // Updates |xwindow_|'s minimum and maximum size.
190 void UpdateMinAndMaxSize();
192 // Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
193 void UpdateWMUserTime(const ui::PlatformEvent
& event
);
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
);
199 // Checks if the window manager has set a specific state.
200 bool HasWMSpecProperty(const char* property
) const;
202 // Sets whether the window's borders are provided by the window manager.
203 void SetUseNativeFrame(bool use_native_frame
);
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
);
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
);
215 // Updates the location of |located_event| to be in |host|'s coordinate system
216 // so that it can be dispatched to |host|.
217 void ConvertEventToDifferentHost(ui::LocatedEvent
* located_event
,
218 DesktopWindowTreeHostX11
* host
);
220 // Resets the window region for the current widget bounds if necessary.
221 void ResetWindowRegion();
223 // Serializes an image to the format used by _NET_WM_ICON.
224 void SerializeImageRepresentation(const gfx::ImageSkiaRep
& rep
,
225 std::vector
<unsigned long>* data
);
227 // Returns an 8888 ARGB visual. Can return NULL if there is no matching
228 // visual on this display.
229 Visual
* GetARGBVisual();
231 // See comment for variable open_windows_.
232 static std::list
<XID
>& open_windows();
234 // Map the window (shows it) taking into account the given |show_state|.
235 void MapWindow(ui::WindowShowState show_state
);
237 void SetWindowTransparency();
239 // Relayout the widget's client and non-client views.
242 // ui::PlatformEventDispatcher:
243 bool CanDispatchEvent(const ui::PlatformEvent
& event
) override
;
244 uint32_t DispatchEvent(const ui::PlatformEvent
& event
) override
;
246 void DelayedResize(const gfx::Size
& size_in_pixels
);
248 gfx::Rect
GetWorkAreaBoundsInPixels() const;
249 gfx::Rect
ToDIPRect(const gfx::Rect
& rect_in_pixels
) const;
250 gfx::Rect
ToPixelRect(const gfx::Rect
& rect_in_dip
) const;
253 // The display and the native X window hosting the root window.
257 // The native root window.
258 ::Window x_root_window_
;
260 ui::X11AtomCache atom_cache_
;
262 // Is the window mapped to the screen?
265 // The bounds of |xwindow_|.
266 gfx::Rect bounds_in_pixels_
;
268 // Whenever the bounds are set, we keep the previous set of bounds around so
269 // we can have a better chance of getting the real
270 // |restored_bounds_in_pixels_|. Window managers tend to send a Configure
271 // message with the maximized bounds, and then set the window maximized
272 // property. (We don't rely on this for when we request that the window be
273 // maximized, only when we detect that some other process has requested that
274 // we become the maximized window.)
275 gfx::Rect previous_bounds_in_pixels_
;
277 // The bounds of our window before we were maximized.
278 gfx::Rect restored_bounds_in_pixels_
;
280 // |xwindow_|'s minimum size.
281 gfx::Size min_size_in_pixels_
;
283 // |xwindow_|'s maximum size.
284 gfx::Size max_size_in_pixels_
;
286 // The window manager state bits.
287 std::set
< ::Atom
> window_properties_
;
289 // Whether |xwindow_| was requested to be fullscreen via SetFullscreen().
292 // True if the window should stay on top of most other windows.
293 bool is_always_on_top_
;
295 // True if the window has title-bar / borders provided by the window manager.
296 bool use_native_frame_
;
298 // True if a Maximize() call should be done after mapping the window.
299 bool should_maximize_after_map_
;
301 // Whether we used an ARGB visual for our window.
302 bool use_argb_visual_
;
304 DesktopDragDropClientAuraX11
* drag_drop_client_
;
306 scoped_ptr
<ui::EventHandler
> x11_non_client_event_filter_
;
307 scoped_ptr
<X11DesktopWindowMoveClient
> x11_window_move_client_
;
309 // TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
310 // instead of providing this route back to Widget.
311 internal::NativeWidgetDelegate
* native_widget_delegate_
;
313 DesktopNativeWidgetAura
* desktop_native_widget_aura_
;
315 aura::Window
* content_window_
;
317 // We can optionally have a parent which can order us to close, or own
318 // children who we're responsible for closing when we CloseNow().
319 DesktopWindowTreeHostX11
* window_parent_
;
320 std::set
<DesktopWindowTreeHostX11
*> window_children_
;
322 ObserverList
<DesktopWindowTreeHostObserverX11
> observer_list_
;
324 // The window shape if the window is non-rectangular.
325 gfx::XScopedPtr
<_XRegion
, gfx::XObjectDeleter
<_XRegion
, int, XDestroyRegion
>>
328 // Whether |window_shape_| was set via SetShape().
329 bool custom_window_shape_
;
331 // The size of the window manager provided borders (if any).
332 gfx::Insets native_window_frame_borders_in_pixels_
;
334 // The current DesktopWindowTreeHostX11 which has capture. Set synchronously
335 // when capture is requested via SetCapture().
336 static DesktopWindowTreeHostX11
* g_current_capture
;
338 // A list of all (top-level) windows that have been created but not yet
340 static std::list
<XID
>* open_windows_
;
342 base::string16 window_title_
;
344 // Whether we currently are flashing our frame. This feature is implemented
345 // by setting the urgency hint with the window manager, which can draw
346 // attention to the window or completely ignore the hint. We stop flashing
347 // the frame when |xwindow_| gains focus or handles a mouse button event.
348 bool urgency_hint_set_
;
350 base::CancelableCallback
<void()> delayed_resize_task_
;
352 base::WeakPtrFactory
<DesktopWindowTreeHostX11
> close_widget_factory_
;
354 DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11
);
359 #endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_X11_H_