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>
This commit is contained in:
parent
2f1ab7156a
commit
04ba6fbed9
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user