summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbdrag.cpp
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals@canonical.com>2012-02-22 10:33:09 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-01 19:00:15 +0100
commite51e7b851f6452ed19ae960179963559ab0b78ea (patch)
tree1c42e9b4deb00e6931a988f4b32e7cf26c81f5bc /src/plugins/platforms/xcb/qxcbdrag.cpp
parent4494ddfec7e4a74ae1192eed25edf8e3ee294755 (diff)
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>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbdrag.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp40
1 files changed, 24 insertions, 16 deletions
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;
}