Chromium Code Reviews| Index: ui/base/x/x11_util.cc |
| diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
| index 007157c821d4316345a90bd458bcd1bd06db226b..b2dbf7b8402058059cd7ea4c6fdf8b648c48c170 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); |
|
sadrul
2014/03/26 18:01:07
Is this necessary when XQueryTree is used?
varkha
2014/03/27 04:48:13
Yes (I think). We call IsWindowNamed(*iter) on the
|
| + // 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. |