summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowscontext.cpp
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 /src/plugins/platforms/windows/qwindowscontext.cpp
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>
Diffstat (limited to 'src/plugins/platforms/windows/qwindowscontext.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp55
1 files changed, 42 insertions, 13 deletions
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;
}