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 #include "chrome/browser/fullscreen.h"
13 #include "base/basictypes.h"
14 #include "ui/base/x/x11_util.h"
15 #include "ui/gfx/rect.h"
19 // TODO (jianli): Merge with ui::EnumerateTopLevelWindows.
20 void EnumerateAllChildWindows(ui::EnumerateWindowsDelegate
* delegate
,
22 std::vector
<XID
> windows
;
24 if (!ui::GetXWindowStack(window
, &windows
)) {
25 // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back
26 // to old school enumeration of all X windows.
27 XID root
, parent
, *children
;
28 unsigned int num_children
;
29 int status
= XQueryTree(gfx::GetXDisplay(), window
, &root
, &parent
,
30 &children
, &num_children
);
32 for (long i
= static_cast<long>(num_children
) - 1; i
>= 0; i
--)
33 windows
.push_back(children
[i
]);
38 std::vector
<XID
>::iterator iter
;
39 for (iter
= windows
.begin(); iter
!= windows
.end(); iter
++) {
40 if (delegate
->ShouldStopIterating(*iter
))
45 // To find the top-most window:
46 // 1) Enumerate all top-level windows from the top to the bottom.
47 // 2) For each window:
48 // 2.1) If it is hidden, continue the iteration.
49 // 2.2) If it is managed by the Window Manager (has a WM_STATE property).
50 // Return this window as the top-most window.
51 // 2.3) Enumerate all its child windows. If there is a child window that is
52 // managed by the Window Manager (has a WM_STATE property). Return this
53 // child window as the top-most window.
54 // 2.4) Otherwise, continue the iteration.
56 class WindowManagerWindowFinder
: public ui::EnumerateWindowsDelegate
{
58 WindowManagerWindowFinder() : window_(None
) { }
60 XID
window() const { return window_
; }
63 virtual bool ShouldStopIterating(XID window
) OVERRIDE
{
64 if (ui::PropertyExists(window
, "WM_STATE")) {
74 DISALLOW_COPY_AND_ASSIGN(WindowManagerWindowFinder
);
77 class TopMostWindowFinder
: public ui::EnumerateWindowsDelegate
{
80 : top_most_window_(None
) {}
82 XID
top_most_window() const { return top_most_window_
; }
85 virtual bool ShouldStopIterating(XID window
) OVERRIDE
{
86 if (!ui::IsWindowVisible(window
))
88 if (ui::PropertyExists(window
, "WM_STATE")) {
89 top_most_window_
= window
;
92 WindowManagerWindowFinder child_finder
;
93 EnumerateAllChildWindows(&child_finder
, window
);
94 XID child_window
= child_finder
.window();
95 if (child_window
== None
)
97 top_most_window_
= child_window
;
102 XID top_most_window_
;
104 DISALLOW_COPY_AND_ASSIGN(TopMostWindowFinder
);
107 bool IsTopMostWindowFullScreen() {
108 // Find the topmost window.
109 TopMostWindowFinder finder
;
110 EnumerateAllChildWindows(&finder
, ui::GetX11RootWindow());
111 XID window
= finder
.top_most_window();
115 // Make sure it is not the desktop window.
116 static Atom desktop_atom
= gdk_x11_get_xatom_by_name_for_display(
117 gdk_display_get_default(), "_NET_WM_WINDOW_TYPE_DESKTOP");
119 std::vector
<Atom
> atom_properties
;
120 if (ui::GetAtomArrayProperty(window
,
121 "_NET_WM_WINDOW_TYPE",
123 std::find(atom_properties
.begin(), atom_properties
.end(), desktop_atom
)
124 != atom_properties
.end())
127 // If it is a GDK window, check it using gdk function.
128 GdkWindow
* gwindow
= gdk_window_lookup(window
);
129 if (gwindow
&& window
!= GDK_ROOT_WINDOW())
130 return gdk_window_get_state(gwindow
) == GDK_WINDOW_STATE_FULLSCREEN
;
132 // Otherwise, do the check via xlib function.
133 return ui::IsX11WindowFullScreen(window
);
138 bool IsFullScreenMode() {
139 gdk_error_trap_push();
140 bool result
= IsTopMostWindowFullScreen();
141 bool got_error
= gdk_error_trap_pop();
142 return result
&& !got_error
;