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
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())
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;
}