Take into account input shaping in findRealWindow

In previous commits we took into account bound shaping, but X also
supports input shaping, so make sure it's inside both input and bounding
shaping to consider the position as inside a window

My tests show that when unset Bound Shaping and Input Shaping return the
rectangle of the window itself, so we need to be inside both of the
rectangle sets to consider the position as a dragabble position for the
window

Change-Id: I77973e51168d2a6d274d166f29f32e1bc02c32c3
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Albert Astals Cid 2012-02-22 10:33:09 +01:00 committed by Qt by Nokia
parent 4494ddfec7
commit e51e7b851f
3 changed files with 27 additions and 19 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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