summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals@canonical.com>2012-05-08 16:41:33 -0700
committerQt by Nokia <qt-info@nokia.com>2012-05-10 13:50:35 +0200
commit07f3c1e26aa6dcd07a9705e7b2ea02ace9ea7c5d (patch)
tree96495e802823e7cea4a69bc0707b2a3231afd4f3
parent3b6b8a0f749bb20d8e83762060ac87d2ec207562 (diff)
XShaping drag and drop fixes
No shaping rectangles means no interaction with the window The shaping rectangles are based on the window coords, so need to substract the window coords when checking for the point Change-Id: Ic9004a8ec0f447cddcd1b4324d9fd60a94787cb9 Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h2
2 files changed, 13 insertions, 9 deletions
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 3aeaaba2d8..42c240ef8e 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -218,12 +218,11 @@ translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int
static
bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, xcb_shape_sk_t shapeType)
{
- bool interacts = true;
+ bool interacts = false;
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);
@@ -235,7 +234,7 @@ bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & po
return interacts;
}
-xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md)
+xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md, bool ignoreNonXdndAwareWindows)
{
if (w == shapedPixmapWindow()->handle()->winId())
return 0;
@@ -252,7 +251,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;
+ bool windowContainsMouse = !ignoreNonXdndAwareWindows;
{
xcb_get_property_cookie_t cookie =
Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware),
@@ -262,12 +261,15 @@ 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) {
+ const QPoint relPos = pos - QPoint(greply->x, greply->y);
// When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we
// need to check both here so that in the case one is set and the other is not we still get the correct result.
if (connection()->hasInputShape())
- windowContainsMouse = windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_INPUT);
+ windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_INPUT);
if (windowContainsMouse && connection()->hasXShape())
- windowContainsMouse = windowInteractsWithPosition(xcb_connection(), pos, w, XCB_SHAPE_SK_BOUNDING);
+ windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_BOUNDING);
+ if (!connection()->hasInputShape() && !connection()->hasXShape())
+ windowContainsMouse = true;
if (windowContainsMouse)
return w;
}
@@ -283,7 +285,7 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
xcb_window_t r = 0;
for (uint i = nc; !r && i--;)
- r = findRealWindow(pos - QPoint(greply->x, greply->y), c[i], md-1);
+ r = findRealWindow(pos - QPoint(greply->x, greply->y), c[i], md-1, ignoreNonXdndAwareWindows);
free(reply);
if (r)
@@ -382,7 +384,9 @@ void QXcbDrag::move(const QMouseEvent *me)
if (!target || target == shapedPixmapWindow()->handle()->winId()) {
DNDDEBUG << "need to find real window";
- target = findRealWindow(globalPos, rootwin, 6);
+ target = findRealWindow(globalPos, rootwin, 6, true);
+ if (target == 0)
+ target = findRealWindow(globalPos, rootwin, 6, false);
DNDDEBUG << "real window found" << target;
}
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 2f74b3eaf7..595018458f 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -158,7 +158,7 @@ private:
void restartDropExpiryTimer();
int findTransactionByWindow(xcb_window_t window);
int findTransactionByTime(xcb_timestamp_t timestamp);
- xcb_window_t findRealWindow(const QPoint & pos, xcb_window_t w, int md);
+ xcb_window_t findRealWindow(const QPoint & pos, xcb_window_t w, int md, bool ignoreNonXdndAwareWindows);
};
QT_END_NAMESPACE