From 651016020f9ac996f2aac50e2d30505bdffe2331 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 7 Feb 2012 15:48:51 +0100 Subject: Take into account shaping in findRealWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Uli Schlachter Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbdrag.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/xcb/qxcbdrag.cpp') 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; -- cgit v1.2.3