summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-08-05 10:19:41 +0200
committerFriedemann Kleint <Friedemann.Kleint@digia.com>2014-08-07 21:05:50 +0200
commit04ba6fbed900403ef8892820fa93925a8e21f7b1 (patch)
tree7dc054e2240108c69c6545c0ebf82ed6ec9c34f9
parent2f1ab7156ad50b1cd4c50708ae0f6e5529ce9974 (diff)
Windows/QGuiApplication::topLevelAt(): Skip mouse-transparent windows of other processes.
Search again when a non-Qt window with WS_EX_TRANSPARENT set is found. Task-number: QTBUG-40555 Change-Id: I3f53be626f52dc25429661ac8ea5e9f6bb163596 Reviewed-by: Björn Breitmeyer <bjoern.breitmeyer@kdab.com> Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r--src/plugins/platforms/windows/qplatformfunctions_wince.h5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp55
2 files changed, 42 insertions, 18 deletions
diff --git a/src/plugins/platforms/windows/qplatformfunctions_wince.h b/src/plugins/platforms/windows/qplatformfunctions_wince.h
index 47b03b29cc..17b13ced76 100644
--- a/src/plugins/platforms/windows/qplatformfunctions_wince.h
+++ b/src/plugins/platforms/windows/qplatformfunctions_wince.h
@@ -75,7 +75,6 @@
#ifndef CWP_SKIPINVISIBLE
#define CWP_SKIPINVISIBLE 0x0001
#define CWP_SKIPTRANSPARENT 0x0004
-#define findPlatformWindowAt(a, b, c) findPlatformWindowAt(a, b)
#endif
#ifndef CS_OWNDC
@@ -95,10 +94,6 @@
#define SW_SHOWMINIMIZED SW_MINIMIZE
#define SW_SHOWMINNOACTIVE SW_MINIMIZE
-#ifndef ChildWindowFromPointEx
-#define ChildWindowFromPointEx(a, b, c) ChildWindowFromPoint(a, b)
-#endif
-
#ifndef CF_DIBV5
#define CF_DIBV5 17
#endif
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 9706615047..dc861c963d 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -681,25 +681,54 @@ void QWindowsContext::clearWindowUnderMouse()
\a parent is the parent window, pass GetDesktopWindow() for top levels.
*/
+static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned cwexFlags,
+ const QWindowsContext *context,
+ HWND *hwnd, QWindowsWindow **result)
+{
+ POINT point = screenPoint;
+ ScreenToClient(*hwnd, &point);
+ // Returns parent if inside & none matched.
+#ifndef Q_OS_WINCE
+ const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
+#else
+ Q_UNUSED(cwexFlags)
+ const HWND child = ChildWindowFromPoint(*hwnd, point);
+#endif
+ if (!child || child == *hwnd)
+ return false;
+ if (QWindowsWindow *window = context->findPlatformWindow(child)) {
+ *result = window;
+ *hwnd = child;
+ return true;
+ }
+#ifndef Q_OS_WINCE // Does not have WS_EX_TRANSPARENT .
+ // QTBUG-40555: despite CWP_SKIPINVISIBLE, it is possible to hit on invisible
+ // full screen windows of other applications that have WS_EX_TRANSPARENT set
+ // (for example created by screen sharing applications). In that case, try to
+ // find a Qt window by searching again with CWP_SKIPTRANSPARENT.
+ // Note that Qt 5 uses WS_EX_TRANSPARENT for Qt::WindowTransparentForInput
+ // as well.
+ if (!(cwexFlags & CWP_SKIPTRANSPARENT)
+ && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) {
+ const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT);
+ if (QWindowsWindow *nonTransparentWindow = context->findPlatformWindow(nonTransparentChild)) {
+ *result = nonTransparentWindow;
+ *hwnd = nonTransparentChild;
+ return true;
+ }
+ }
+#endif // !Q_OS_WINCE
+ *hwnd = child;
+ return true;
+}
+
QWindowsWindow *QWindowsContext::findPlatformWindowAt(HWND parent,
const QPoint &screenPointIn,
unsigned cwex_flags) const
{
QWindowsWindow *result = 0;
const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
- while (true) {
- POINT point = screenPoint;
- ScreenToClient(parent, &point);
- // Returns parent if inside & none matched.
- const HWND child = ChildWindowFromPointEx(parent, point, cwex_flags);
- if (child && child != parent) {
- if (QWindowsWindow *window = findPlatformWindow(child))
- result = window;
- parent = child;
- } else {
- break;
- }
- }
+ while (findPlatformWindowHelper(screenPoint, cwex_flags, this, &parent, &result)) {}
return result;
}