diff options
Diffstat (limited to 'ui/base/x/x11_util.cc')
-rw-r--r-- | ui/base/x/x11_util.cc | 192 |
1 files changed, 118 insertions, 74 deletions
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 2b5863a..fda637c 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc @@ -16,7 +16,7 @@ #include <sys/shm.h> #include <list> -#include <set> +#include <vector> #include "base/command_line.h" #include "base/logging.h" @@ -66,6 +66,28 @@ int DefaultX11IOErrorHandler(Display* d) { _exit(1); } +// Note: The caller should free the resulting value data. +bool GetProperty(XID window, const std::string& property_name, long max_length, + Atom* type, int* format, unsigned long* num_items, + unsigned char** property) { + Atom property_atom = gdk_x11_get_xatom_by_name_for_display( + gdk_display_get_default(), property_name.c_str()); + + unsigned long remaining_bytes = 0; + return XGetWindowProperty(GetXDisplay(), + window, + property_atom, + 0, // offset into property data to read + max_length, // max length to get + False, // deleted + AnyPropertyType, + type, + format, + num_items, + &remaining_bytes, + property); +} + } // namespace bool XDisplayExists() { @@ -221,27 +243,29 @@ bool GetWindowRect(XID window, gfx::Rect* rect) { return true; } -bool GetIntProperty(XID window, const std::string& property_name, int* value) { - Atom property_atom = gdk_x11_get_xatom_by_name_for_display( - gdk_display_get_default(), property_name.c_str()); +bool PropertyExists(XID window, const std::string& property_name) { + Atom type = None; + int format = 0; // size in bits of each item in 'property' + long unsigned int num_items = 0; + unsigned char* property = NULL; + + int result = GetProperty(window, property_name, 1, + &type, &format, &num_items, &property); + if (result != Success) + return false; + + XFree(property); + return num_items > 0; +} +bool GetIntProperty(XID window, const std::string& property_name, int* value) { Atom type = None; int format = 0; // size in bits of each item in 'property' - long unsigned int num_items = 0, remaining_bytes = 0; + long unsigned int num_items = 0; unsigned char* property = NULL; - int result = XGetWindowProperty(GetXDisplay(), - window, - property_atom, - 0, // offset into property data to read - 1, // max length to get - False, // deleted - AnyPropertyType, - &type, - &format, - &num_items, - &remaining_bytes, - &property); + int result = GetProperty(window, property_name, 1, + &type, &format, &num_items, &property); if (result != Success) return false; @@ -258,26 +282,14 @@ bool GetIntProperty(XID window, const std::string& property_name, int* value) { bool GetIntArrayProperty(XID window, const std::string& property_name, std::vector<int>* value) { - Atom property_atom = gdk_x11_get_xatom_by_name_for_display( - gdk_display_get_default(), property_name.c_str()); - Atom type = None; int format = 0; // size in bits of each item in 'property' - long unsigned int num_items = 0, remaining_bytes = 0; + long unsigned int num_items = 0; unsigned char* properties = NULL; - int result = XGetWindowProperty(GetXDisplay(), - window, - property_atom, - 0, // offset into property data to read - (~0L), // max length to get (all of them) - False, // deleted - AnyPropertyType, - &type, - &format, - &num_items, - &remaining_bytes, - &properties); + int result = GetProperty(window, property_name, + (~0L), // (all of them) + &type, &format, &num_items, &properties); if (result != Success) return false; @@ -293,28 +305,41 @@ bool GetIntArrayProperty(XID window, return true; } +bool GetAtomArrayProperty(XID window, + const std::string& property_name, + std::vector<Atom>* value) { + Atom type = None; + int format = 0; // size in bits of each item in 'property' + long unsigned int num_items = 0; + unsigned char* properties = NULL; + + int result = GetProperty(window, property_name, + (~0L), // (all of them) + &type, &format, &num_items, &properties); + if (result != Success) + return false; + + if (type != XA_ATOM) { + XFree(properties); + return false; + } + + Atom* atom_properties = reinterpret_cast<Atom*>(properties); + value->clear(); + value->insert(value->begin(), atom_properties, atom_properties + num_items); + XFree(properties); + return true; +} + bool GetStringProperty( XID window, const std::string& property_name, std::string* value) { - Atom property_atom = gdk_x11_get_xatom_by_name_for_display( - gdk_display_get_default(), property_name.c_str()); - Atom type = None; int format = 0; // size in bits of each item in 'property' - long unsigned int num_items = 0, remaining_bytes = 0; + long unsigned int num_items = 0; unsigned char* property = NULL; - int result = XGetWindowProperty(GetXDisplay(), - window, - property_atom, - 0, // offset into property data to read - 1024, // max length to get - False, // deleted - AnyPropertyType, - &type, - &format, - &num_items, - &remaining_bytes, - &property); + int result = GetProperty(window, property_name, 1024, + &type, &format, &num_items, &property); if (result != Success) return false; @@ -376,16 +401,16 @@ bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, if (status == 0) return false; - std::set<XID> windows; - for (unsigned int i = 0; i < num_children; i++) - windows.insert(children[i]); + std::vector<XID> windows; + for (int i = static_cast<int>(num_children) - 1; i >= 0; i--) + windows.push_back(children[i]); XFree(children); // XQueryTree returns the children of |window| in bottom-to-top order, so // reverse-iterate the list to check the windows from top-to-bottom. - std::set<XID>::reverse_iterator iter; - for (iter = windows.rbegin(); iter != windows.rend(); iter++) { + std::vector<XID>::iterator iter; + for (iter = windows.begin(); iter != windows.end(); iter++) { if (IsWindowNamed(*iter) && delegate->ShouldStopIterating(*iter)) return true; } @@ -395,7 +420,7 @@ bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, // loop because the recursion and call to XQueryTree are expensive and is only // needed for a small number of cases. if (++depth <= max_depth) { - for (iter = windows.rbegin(); iter != windows.rend(); iter++) { + for (iter = windows.begin(); iter != windows.end(); iter++) { if (EnumerateChildren(delegate, *iter, max_depth, depth)) return true; } @@ -409,29 +434,20 @@ bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, int max_depth) { return EnumerateChildren(delegate, root, max_depth, 0); } -bool GetXWindowStack(std::vector<XID>* windows) { +bool GetXWindowStack(Window window, std::vector<XID>* windows) { windows->clear(); - static Atom atom = XInternAtom(GetXDisplay(), - "_NET_CLIENT_LIST_STACKING", False); - Atom type; int format; unsigned long count; - unsigned long bytes_after; unsigned char *data = NULL; - if (XGetWindowProperty(GetXDisplay(), - GetX11RootWindow(), - atom, - 0, // offset - ~0L, // length - False, // delete - AnyPropertyType, // requested type - &type, - &format, - &count, - &bytes_after, - &data) != Success) { + if (!GetProperty(window, + "_NET_CLIENT_LIST_STACKING", + ~0L, + &type, + &format, + &count, + &data)) { return false; } @@ -439,8 +455,8 @@ bool GetXWindowStack(std::vector<XID>* windows) { if (type == XA_WINDOW && format == 32 && data && count > 0) { result = true; XID* stack = reinterpret_cast<XID*>(data); - for (unsigned long i = 0; i < count; i++) - windows->insert(windows->begin(), stack[i]); + for (long i = static_cast<long>(count) - 1; i >= 0; i--) + windows->push_back(stack[i]); } if (data) @@ -752,6 +768,34 @@ void SetDefaultX11ErrorHandlers() { SetX11ErrorHandlers(NULL, NULL); } +bool IsX11WindowFullScreen(XID window) { + // First check if _NET_WM_STATE property contains _NET_WM_STATE_FULLSCREEN. + static Atom atom = gdk_x11_get_xatom_by_name_for_display( + gdk_display_get_default(), "_NET_WM_STATE_FULLSCREEN"); + + std::vector<Atom> atom_properties; + if (GetAtomArrayProperty(window, + "_NET_WM_STATE", + &atom_properties) && + std::find(atom_properties.begin(), atom_properties.end(), atom) + != atom_properties.end()) + return true; + + // As the last resort, check if the window size is as large as the main + // screen. + GdkRectangle monitor_rect; + gdk_screen_get_monitor_geometry(gdk_screen_get_default(), 0, &monitor_rect); + + gfx::Rect window_rect; + if (!ui::GetWindowRect(window, &window_rect)) + return false; + + return monitor_rect.x == window_rect.x() && + monitor_rect.y == window_rect.y() && + monitor_rect.width == window_rect.width() && + monitor_rect.height == window_rect.height(); +} + // ---------------------------------------------------------------------------- // These functions are declared in x11_util_internal.h because they require // XLib.h to be included, and it conflicts with many other headers. |