summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbdrag.cpp
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2012-02-07 15:48:51 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-09 10:50:20 +0100
commit651016020f9ac996f2aac50e2d30505bdffe2331 (patch)
tree05c5cdce2afe4300a609a11c0abb9ca424be669c /src/plugins/platforms/xcb/qxcbdrag.cpp
parent5cd73e508886c38ce52e883294484f1ab58a519e (diff)
Take into account shaping in findRealWindow
It can happen that there is a window covering all the screen but it is shaped to only take part of the screen. If that happens, besides the condition of QRect(attr.x,attr.y,attr.width,attr.height).contains(pos) we also need to query the server for its region rectangles and make sure the cursor is inside one of those rectangles. If that does not happen we have to return 0 so the hierarchical xcb_query_tree_children xcb_query_tree_childrenntinues Change-Id: I67327672e3d854d064190b55a07bd56ade4dfddb Reviewed-by: Lars Knoll <lars.knoll@nokia.com> Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbdrag.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index a05fc780bc..e928fe2d0a 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -234,6 +234,7 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w);
xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0);
if (reply && QRect(greply->x, greply->y, greply->width, greply->height).contains(pos)) {
+ bool windowContainsMouse = true;
{
xcb_get_property_cookie_t cookie =
Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware),
@@ -242,8 +243,26 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
bool isAware = reply && reply->type != XCB_NONE;
free(reply);
- if (isAware)
- return w;
+ if (isAware) {
+ xcb_xfixes_region_t region = xcb_generate_id(xcb_connection());
+ xcb_xfixes_create_region_from_window(xcb_connection(), region, w, XCB_SHAPE_SK_BOUNDING);
+ xcb_xfixes_fetch_region_reply_t *reply = xcb_xfixes_fetch_region_reply(xcb_connection(), xcb_xfixes_fetch_region(xcb_connection(), region), NULL);
+ if (reply) {
+ xcb_rectangle_t *rectangles = xcb_xfixes_fetch_region_rectangles(reply);
+ if (rectangles) {
+ windowContainsMouse = false;
+ const int nRectangles = xcb_xfixes_fetch_region_rectangles_length(reply);
+ for (int i = 0; !windowContainsMouse && i < nRectangles; ++i) {
+ windowContainsMouse = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos);
+ }
+ }
+ free(reply);
+ }
+ xcb_xfixes_destroy_region(xcb_connection(), region);
+
+ if (windowContainsMouse)
+ return w;
+ }
}
xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w);
@@ -266,7 +285,10 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
// innermost window.
// No children!
- return w;
+ if (!windowContainsMouse)
+ return 0;
+ else
+ return w;
}
}
return 0;