Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: ui/base/x/x11_util.cc

Issue 196213004: Allows menu host windows to be enumerated in DragTargetWindowFinder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implements menu XID caching and dispatches mouse drags in a posted task (test) Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file defines utility functions for X11 (Linux only). This code has been 5 // This file defines utility functions for X11 (Linux only). This code has been
6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support
7 // remains woefully incomplete. 7 // remains woefully incomplete.
8 8
9 #include "ui/base/x/x11_util.h" 9 #include "ui/base/x/x11_util.h"
10 10
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 1060
1061 XFree(prop.value); 1061 XFree(prop.value);
1062 return true; 1062 return true;
1063 } 1063 }
1064 1064
1065 bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, 1065 bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window,
1066 const int max_depth, int depth) { 1066 const int max_depth, int depth) {
1067 if (depth > max_depth) 1067 if (depth > max_depth)
1068 return false; 1068 return false;
1069 1069
1070 std::vector<XID> windows;
1071 std::vector<XID>::iterator iter;
1072 if (depth == 0) {
1073 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
1074 // Enumerate the menus first.
1075 for (iter = windows.begin(); iter != windows.end(); iter++) {
1076 if (delegate->ShouldStopIterating(*iter))
1077 return true;
1078 }
1079 windows.clear();
1080 }
1081
1070 XID root, parent, *children; 1082 XID root, parent, *children;
1071 unsigned int num_children; 1083 unsigned int num_children;
1072 int status = XQueryTree(gfx::GetXDisplay(), window, &root, &parent, &children, 1084 int status = XQueryTree(gfx::GetXDisplay(), window, &root, &parent, &children,
1073 &num_children); 1085 &num_children);
1074 if (status == 0) 1086 if (status == 0)
1075 return false; 1087 return false;
1076 1088
1077 std::vector<XID> windows;
1078 for (int i = static_cast<int>(num_children) - 1; i >= 0; i--) 1089 for (int i = static_cast<int>(num_children) - 1; i >= 0; i--)
1079 windows.push_back(children[i]); 1090 windows.push_back(children[i]);
1080 1091
1081 XFree(children); 1092 XFree(children);
1082 1093
1083 // XQueryTree returns the children of |window| in bottom-to-top order, so 1094 // XQueryTree returns the children of |window| in bottom-to-top order, so
1084 // reverse-iterate the list to check the windows from top-to-bottom. 1095 // reverse-iterate the list to check the windows from top-to-bottom.
1085 std::vector<XID>::iterator iter;
1086 for (iter = windows.begin(); iter != windows.end(); iter++) { 1096 for (iter = windows.begin(); iter != windows.end(); iter++) {
1087 if (IsWindowNamed(*iter) && delegate->ShouldStopIterating(*iter)) 1097 if (IsWindowNamed(*iter) && delegate->ShouldStopIterating(*iter))
1088 return true; 1098 return true;
1089 } 1099 }
1090 1100
1091 // If we're at this point, we didn't find the window we're looking for at the 1101 // If we're at this point, we didn't find the window we're looking for at the
1092 // current level, so we need to recurse to the next level. We use a second 1102 // current level, so we need to recurse to the next level. We use a second
1093 // loop because the recursion and call to XQueryTree are expensive and is only 1103 // loop because the recursion and call to XQueryTree are expensive and is only
1094 // needed for a small number of cases. 1104 // needed for a small number of cases.
1095 if (++depth <= max_depth) { 1105 if (++depth <= max_depth) {
(...skipping 15 matching lines...) Expand all
1111 std::vector<XID> stack; 1121 std::vector<XID> stack;
1112 if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) { 1122 if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) {
1113 // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back 1123 // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back
1114 // to old school enumeration of all X windows. Some WMs parent 'top-level' 1124 // to old school enumeration of all X windows. Some WMs parent 'top-level'
1115 // windows in unnamed actual top-level windows (ion WM), so extend the 1125 // windows in unnamed actual top-level windows (ion WM), so extend the
1116 // search depth to all children of top-level windows. 1126 // search depth to all children of top-level windows.
1117 const int kMaxSearchDepth = 1; 1127 const int kMaxSearchDepth = 1;
1118 ui::EnumerateAllWindows(delegate, kMaxSearchDepth); 1128 ui::EnumerateAllWindows(delegate, kMaxSearchDepth);
1119 return; 1129 return;
1120 } 1130 }
1131 XMenuList::GetInstance()->InsertMenuWindowXIDs(&stack);
1121 1132
1122 std::vector<XID>::iterator iter; 1133 std::vector<XID>::iterator iter;
1123 for (iter = stack.begin(); iter != stack.end(); iter++) { 1134 for (iter = stack.begin(); iter != stack.end(); iter++) {
1124 if (delegate->ShouldStopIterating(*iter)) 1135 if (delegate->ShouldStopIterating(*iter))
1125 return; 1136 return;
1126 } 1137 }
1127 } 1138 }
1128 1139
1129 bool GetXWindowStack(Window window, std::vector<XID>* windows) { 1140 bool GetXWindowStack(Window window, std::vector<XID>* windows) {
1130 windows->clear(); 1141 windows->clear();
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 ::Cursor XScopedCursor::get() const { 1470 ::Cursor XScopedCursor::get() const {
1460 return cursor_; 1471 return cursor_;
1461 } 1472 }
1462 1473
1463 void XScopedCursor::reset(::Cursor cursor) { 1474 void XScopedCursor::reset(::Cursor cursor) {
1464 if (cursor_) 1475 if (cursor_)
1465 XFreeCursor(display_, cursor_); 1476 XFreeCursor(display_, cursor_);
1466 cursor_ = cursor; 1477 cursor_ = cursor;
1467 } 1478 }
1468 1479
1480 // static
1481 XMenuList* XMenuList::GetInstance() {
1482 return Singleton<XMenuList>::get();
1483 }
1484
1485 XMenuList::XMenuList()
1486 : menu_type_atom_(GetAtom("_NET_WM_WINDOW_TYPE_MENU")) {
1487 }
1488
1489 XMenuList::~XMenuList() {
1490 menus_.clear();
1491 }
1492
1493 void XMenuList::MaybeRegisterMenu(XID menu) {
1494 int value = 0;
1495 if (!GetIntProperty(menu, "_NET_WM_WINDOW_TYPE", &value) ||
1496 static_cast<Atom>(value) != menu_type_atom_) {
1497 return;
1498 }
1499 menus_.push_back(menu);
1500 }
1501
1502 void XMenuList::MaybeUnregisterMenu(XID menu) {
1503 std::vector<XID>::iterator iter = std::find(menus_.begin(), menus_.end(),
1504 menu);
1505 if (iter == menus_.end())
1506 return;
1507 menus_.erase(iter);
1508 }
1509
1510 void XMenuList::InsertMenuWindowXIDs(std::vector<XID>* stack) {
1511 std::vector<XID>::iterator iter;
1512 for (iter = menus_.begin(); iter != menus_.end(); ++iter)
1513 stack->insert(stack->begin(), *iter);
1514 }
1515
1469 // ---------------------------------------------------------------------------- 1516 // ----------------------------------------------------------------------------
1470 // These functions are declared in x11_util_internal.h because they require 1517 // These functions are declared in x11_util_internal.h because they require
1471 // XLib.h to be included, and it conflicts with many other headers. 1518 // XLib.h to be included, and it conflicts with many other headers.
1472 XRenderPictFormat* GetRenderARGB32Format(XDisplay* dpy) { 1519 XRenderPictFormat* GetRenderARGB32Format(XDisplay* dpy) {
1473 static XRenderPictFormat* pictformat = NULL; 1520 static XRenderPictFormat* pictformat = NULL;
1474 if (pictformat) 1521 if (pictformat)
1475 return pictformat; 1522 return pictformat;
1476 1523
1477 // First look for a 32-bit format which ignores the alpha value 1524 // First look for a 32-bit format which ignores the alpha value
1478 XRenderPictFormat templ; 1525 XRenderPictFormat templ;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 << "request_code " << static_cast<int>(error_event.request_code) << ", " 1636 << "request_code " << static_cast<int>(error_event.request_code) << ", "
1590 << "minor_code " << static_cast<int>(error_event.minor_code) 1637 << "minor_code " << static_cast<int>(error_event.minor_code)
1591 << " (" << request_str << ")"; 1638 << " (" << request_str << ")";
1592 } 1639 }
1593 1640
1594 // ---------------------------------------------------------------------------- 1641 // ----------------------------------------------------------------------------
1595 // End of x11_util_internal.h 1642 // End of x11_util_internal.h
1596 1643
1597 1644
1598 } // namespace ui 1645 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698