diff options
author | Albert Astals Cid <aacid@kde.org> | 2012-02-02 16:44:38 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-03 14:25:17 (GMT) |
commit | 21713e04160ee285c831fedd1f3c7b8ce0aba681 (patch) | |
tree | 476e719f27ab0023b03df879af4330539bb38f07 /src/gui/kernel | |
parent | f5ddeeca80983ad7579e0b7ba116f0250debdfcd (diff) | |
download | Qt-21713e04160ee285c831fedd1f3c7b8ce0aba681.zip Qt-21713e04160ee285c831fedd1f3c7b8ce0aba681.tar.gz Qt-21713e04160ee285c831fedd1f3c7b8ce0aba681.tar.bz2 |
Take into account shaping in findRealWindow
It can happen that there is a window covering all the screen but it is shaped
to only take part of the screen. If that happens, besides the condition of
QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)
we also need to query the server for its region rectangles and make
sure the cursor is inside one of those rectangles. If that does not happen
we have to return 0 so the hierarchical XQueryTree search continues
Change-Id: Icb2204a50197e4a5e02e75601c67287525b290b0
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_x11.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qdnd_x11.cpp | 32 | ||||
-rw-r--r-- | src/gui/kernel/qt_x11_p.h | 6 |
3 files changed, 38 insertions, 3 deletions
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index ff039fa..d4782f9 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2062,6 +2062,9 @@ void qt_init(QApplicationPrivate *priv, int, X11->ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion); X11->ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName); X11->ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput); + X11->ptrXFixesCreateRegionFromWindow = XFIXES_LOAD_V2(XFixesCreateRegionFromWindow); + X11->ptrXFixesFetchRegion = XFIXES_LOAD_V2(XFixesFetchRegion); + X11->ptrXFixesDestroyRegion = XFIXES_LOAD_V2(XFixesDestroyRegion); if(X11->ptrXFixesQueryExtension && X11->ptrXFixesQueryVersion && X11->ptrXFixesQueryExtension(X11->display, &X11->xfixes_eventbase, diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index 031cc74..2b14743 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -71,6 +71,10 @@ #include "qwidget_p.h" #include "qcursor_p.h" +#ifndef QT_NO_XFIXES +#include <X11/extensions/Xfixes.h> +#endif + QT_BEGIN_NAMESPACE // #define DND_DEBUG @@ -1432,6 +1436,7 @@ Window findRealWindow(const QPoint & pos, Window w, int md) if (attr.map_state == IsViewable && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) { + bool windowContainsMouse = true; { Atom type = XNone; int f; @@ -1441,8 +1446,26 @@ Window findRealWindow(const QPoint & pos, Window w, int md) XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False, AnyPropertyType, &type, &f,&n,&a,&data); if (data) XFree(data); - if (type) - return w; + if (type) { +#ifndef QT_NO_XFIXES + if (X11->use_xfixes && X11->ptrXFixesCreateRegionFromWindow && X11->ptrXFixesFetchRegion && X11->ptrXFixesDestroyRegion) { + XserverRegion region = X11->ptrXFixesCreateRegionFromWindow(X11->display, w, WindowRegionBounding); + int nrectanglesRet; + XRectangle *rectangles = X11->ptrXFixesFetchRegion(X11->display, region, &nrectanglesRet); + if (rectangles) { + windowContainsMouse = false; + for (int i = 0; !windowContainsMouse && i < nrectanglesRet; ++i) + windowContainsMouse = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos); + XFree(rectangles); + } + X11->ptrXFixesDestroyRegion(X11->display, region); + + if (windowContainsMouse) + return w; + } else +#endif + return w; + } } Window r, p; @@ -1463,7 +1486,10 @@ Window findRealWindow(const QPoint & pos, Window w, int md) } // No children! - return w; + if (!windowContainsMouse) + return 0; + else + return w; } } return 0; diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index ed7c146..579a2b3 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -209,6 +209,9 @@ typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *); typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *); typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name); typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask); +typedef void (*PtrXFixesDestroyRegion)(Display *dpy, /*XserverRegion*/ XID region); +typedef /*XserverRegion*/ XID (*PtrXFixesCreateRegionFromWindow)(Display *dpy, Window window, int kind); +typedef XRectangle *(*PtrXFixesFetchRegion)(Display *dpy, /*XserverRegion*/ XID region, int *nrectanglesRet); #endif // QT_NO_XFIXES #ifndef QT_NO_XCURSOR @@ -419,6 +422,9 @@ struct QX11Data PtrXFixesQueryVersion ptrXFixesQueryVersion; PtrXFixesSetCursorName ptrXFixesSetCursorName; PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput; + PtrXFixesDestroyRegion ptrXFixesDestroyRegion; + PtrXFixesCreateRegionFromWindow ptrXFixesCreateRegionFromWindow; + PtrXFixesFetchRegion ptrXFixesFetchRegion; #endif #ifndef QT_NO_XINPUT |