Index: ui/base/x/x11_util.cc |
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
index c71740cd0f4efd67baab29622a4ad5b680379d9c..d8bb407bd7dd5d3143e0ddbd4adc8f057eeef7d8 100644 |
--- a/ui/base/x/x11_util.cc |
+++ b/ui/base/x/x11_util.cc |
@@ -1067,6 +1067,18 @@ bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, |
if (depth > max_depth) |
return false; |
+ std::vector<XID> windows; |
+ std::vector<XID>::iterator iter; |
+ if (depth == 0) { |
+ XMenuList::GetInstance()->InsertMenuWindowXIDs(&windows); |
+ // Enumerate the menus first. |
+ for (iter = windows.begin(); iter != windows.end(); iter++) { |
+ if (delegate->ShouldStopIterating(*iter)) |
+ return true; |
+ } |
+ windows.clear(); |
+ } |
+ |
XID root, parent, *children; |
unsigned int num_children; |
int status = XQueryTree(gfx::GetXDisplay(), window, &root, &parent, &children, |
@@ -1074,7 +1086,6 @@ bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, |
if (status == 0) |
return false; |
- std::vector<XID> windows; |
for (int i = static_cast<int>(num_children) - 1; i >= 0; i--) |
windows.push_back(children[i]); |
@@ -1082,7 +1093,6 @@ bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, |
// 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::vector<XID>::iterator iter; |
for (iter = windows.begin(); iter != windows.end(); iter++) { |
if (IsWindowNamed(*iter) && delegate->ShouldStopIterating(*iter)) |
return true; |
@@ -1118,6 +1128,7 @@ void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) { |
ui::EnumerateAllWindows(delegate, kMaxSearchDepth); |
return; |
} |
+ XMenuList::GetInstance()->InsertMenuWindowXIDs(&stack); |
std::vector<XID>::iterator iter; |
for (iter = stack.begin(); iter != stack.end(); iter++) { |
@@ -1466,6 +1477,42 @@ void XScopedCursor::reset(::Cursor cursor) { |
cursor_ = cursor; |
} |
+// static |
+XMenuList* XMenuList::GetInstance() { |
+ return Singleton<XMenuList>::get(); |
+} |
+ |
+XMenuList::XMenuList() |
+ : menu_type_atom_(GetAtom("_NET_WM_WINDOW_TYPE_MENU")) { |
+} |
+ |
+XMenuList::~XMenuList() { |
+ menus_.clear(); |
+} |
+ |
+void XMenuList::MaybeRegisterMenu(XID menu) { |
+ int value = 0; |
+ if (!GetIntProperty(menu, "_NET_WM_WINDOW_TYPE", &value) || |
+ static_cast<Atom>(value) != menu_type_atom_) { |
+ return; |
+ } |
+ menus_.push_back(menu); |
+} |
+ |
+void XMenuList::MaybeUnregisterMenu(XID menu) { |
+ std::vector<XID>::iterator iter = std::find(menus_.begin(), menus_.end(), |
+ menu); |
+ if (iter == menus_.end()) |
+ return; |
+ menus_.erase(iter); |
+} |
+ |
+void XMenuList::InsertMenuWindowXIDs(std::vector<XID>* stack) { |
+ std::vector<XID>::iterator iter; |
+ for (iter = menus_.begin(); iter != menus_.end(); ++iter) |
+ stack->insert(stack->begin(), *iter); |
+} |
+ |
// ---------------------------------------------------------------------------- |
// These functions are declared in x11_util_internal.h because they require |
// XLib.h to be included, and it conflicts with many other headers. |