From a1f9db4caa39cb2d9b3024410373b51e27fe79cf Mon Sep 17 00:00:00 2001 From: "oshima@google.com" Date: Fri, 23 Sep 2011 17:17:16 +0000 Subject: Aura-fied ui_controls, fullscreen, display_utils and background_mode_manager exclude extension_input_ui_api that is chromeos specific BUG=97131 TEST=none Review URL: http://codereview.chromium.org/7966024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102516 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/fullscreen_gtk.cc | 144 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 chrome/browser/fullscreen_gtk.cc (limited to 'chrome/browser/fullscreen_gtk.cc') diff --git a/chrome/browser/fullscreen_gtk.cc b/chrome/browser/fullscreen_gtk.cc new file mode 100644 index 0000000..da69642 --- /dev/null +++ b/chrome/browser/fullscreen_gtk.cc @@ -0,0 +1,144 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/fullscreen.h" + +#include +#include + +#include +#include + +#include "base/basictypes.h" +#include "chrome/browser/ui/gtk/gtk_util.h" +#include "ui/base/x/x11_util.h" +#include "ui/gfx/rect.h" + +namespace { + +// TODO (jianli): Merge with gtk_util::EnumerateTopLevelWindows. +void EnumerateAllChildWindows(ui::EnumerateWindowsDelegate* delegate, + XID window) { + std::vector windows; + + if (!ui::GetXWindowStack(window, &windows)) { + // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back + // to old school enumeration of all X windows. + XID root, parent, *children; + unsigned int num_children; + int status = XQueryTree(ui::GetXDisplay(), window, &root, &parent, + &children, &num_children); + if (status) { + for (long i = static_cast(num_children) - 1; i >= 0; i--) + windows.push_back(children[i]); + XFree(children); + } + } + + std::vector::iterator iter; + for (iter = windows.begin(); iter != windows.end(); iter++) { + if (delegate->ShouldStopIterating(*iter)) + return; + } +} + +// To find the top-most window: +// 1) Enumerate all top-level windows from the top to the bottom. +// 2) For each window: +// 2.1) If it is hidden, continue the iteration. +// 2.2) If it is managed by the Window Manager (has a WM_STATE property). +// Return this window as the top-most window. +// 2.3) Enumerate all its child windows. If there is a child window that is +// managed by the Window Manager (has a WM_STATE property). Return this +// child window as the top-most window. +// 2.4) Otherwise, continue the iteration. + +class WindowManagerWindowFinder : public ui::EnumerateWindowsDelegate { + public: + WindowManagerWindowFinder() : window_(None) { } + + XID window() const { return window_; } + + protected: + virtual bool ShouldStopIterating(XID window) { + if (ui::PropertyExists(window, "WM_STATE")) { + window_ = window; + return true; + } + return false; + } + + private: + XID window_; + + DISALLOW_COPY_AND_ASSIGN(WindowManagerWindowFinder); +}; + +class TopMostWindowFinder : public ui::EnumerateWindowsDelegate { + public: + TopMostWindowFinder() + : top_most_window_(None) {} + + XID top_most_window() const { return top_most_window_; } + + protected: + virtual bool ShouldStopIterating(XID window) { + if (!ui::IsWindowVisible(window)) + return false; + if (ui::PropertyExists(window, "WM_STATE")) { + top_most_window_ = window; + return true; + } + WindowManagerWindowFinder child_finder; + EnumerateAllChildWindows(&child_finder, window); + XID child_window = child_finder.window(); + if (child_window == None) + return false; + top_most_window_ = child_window; + return true; + } + + private: + XID top_most_window_; + + DISALLOW_COPY_AND_ASSIGN(TopMostWindowFinder); +}; + +bool IsTopMostWindowFullScreen() { + // Find the topmost window. + TopMostWindowFinder finder; + EnumerateAllChildWindows(&finder, ui::GetX11RootWindow()); + XID window = finder.top_most_window(); + if (window == None) + return false; + + // Make sure it is not the desktop window. + static Atom desktop_atom = gdk_x11_get_xatom_by_name_for_display( + gdk_display_get_default(), "_NET_WM_WINDOW_TYPE_DESKTOP"); + + std::vector atom_properties; + if (ui::GetAtomArrayProperty(window, + "_NET_WM_WINDOW_TYPE", + &atom_properties) && + std::find(atom_properties.begin(), atom_properties.end(), desktop_atom) + != atom_properties.end()) + return false; + + // If it is a GDK window, check it using gdk function. + GdkWindow* gwindow = gdk_window_lookup(window); + if (gwindow && window != GDK_ROOT_WINDOW()) + return gdk_window_get_state(gwindow) == GDK_WINDOW_STATE_FULLSCREEN; + + // Otherwise, do the check via xlib function. + return ui::IsX11WindowFullScreen(window); +} + +} + +bool IsFullScreenMode() { + gdk_error_trap_push(); + bool result = IsTopMostWindowFullScreen(); + bool got_error = gdk_error_trap_pop(); + return result && !got_error; +} -- cgit v1.1