diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README index ab802ced27..17e8bb53eb 100644 --- a/src/plugins/platforms/xcb/README +++ b/src/plugins/platforms/xcb/README @@ -1,6 +1,6 @@ Required packages: -libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev +libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available: -libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev +libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev The packages for xcb-render-util can be installed manually from http://packages.ubuntu.com/natty/libxcb-render-util0 and http://packages.ubuntu.com/natty/libxcb-render-util0-dev diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 0e3807cd7b..a0736d81f1 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -215,6 +215,26 @@ translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0); } +static +bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, int shapeType) +{ + bool interacts = true; + xcb_shape_get_rectangles_reply_t *reply = xcb_shape_get_rectangles_reply(connection, xcb_shape_get_rectangles(connection, w, shapeType), NULL); + if (reply) { + xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply); + if (rectangles) { + interacts = false; + const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply); + for (int i = 0; !interacts && i < nRectangles; ++i) { + interacts = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos); + } + } + free(reply); + } + + return interacts; +} + xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md) { if (w == shapedPixmapWindow()->handle()->winId()) @@ -242,22 +262,10 @@ 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) { - 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); - + // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we + // need an && here so that in the case one is set and the other is not we still get the correct result. + windowContainsMouse = windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_INPUT) && + windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_BOUNDING); if (windowContainsMouse) return w; } diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index 7bad2b4dad..d220766be0 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -94,7 +94,7 @@ contains(DEFINES, XCB_USE_DRI2) { } } -LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes +LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shape DEFINES += $$QMAKE_DEFINES_XCB LIBS += $$QMAKE_LIBS_XCB