diff options
author | Kai Uwe Broulik <kde@privat.broulik.de> | 2023-08-04 13:40:46 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-08-07 18:41:59 +0000 |
commit | 5ce881747afa23e3fc57b2e531b1f6d8c87bb519 (patch) | |
tree | f21d5e9b962c381048613d1ec5036eece74636f0 /src | |
parent | 524055fb9dca41f5315bc181632e7df3c14e8c76 (diff) |
QWaylandWindow: Support Qt::WindowTransparentForInput
This is achieved by setting an explicitly empty input
region (as opposed to a "null" region) on the window.
Unlike set_opaque_region, where a null region means an
empty region, in set_input_region it means an
infinite region.
Change-Id: I018d53196bc816b5eaea7dd3b24626a9738c9f47
Reviewed-by: David Edmundson <davidedmundson@kde.org>
(cherry picked from commit 604db6b5499f5de1d700f19c03bc43fe2f59380d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/client/qwaylandwindow.cpp | 42 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 6 |
2 files changed, 39 insertions, 9 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index acc698f07..aea2cfff9 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -451,6 +451,32 @@ void QWaylandWindow::setGeometry(const QRect &r) setOpaqueArea(QRect(QPoint(0, 0), rect.size())); } +void QWaylandWindow::updateInputRegion() +{ + if (!mSurface) + return; + + const bool transparentInputRegion = mFlags.testFlag(Qt::WindowTransparentForInput); + + QRegion inputRegion; + if (!transparentInputRegion) + inputRegion = mMask; + + if (mInputRegion == inputRegion && mTransparentInputRegion == transparentInputRegion) + return; + + mInputRegion = inputRegion; + mTransparentInputRegion = transparentInputRegion; + + if (mInputRegion.isEmpty() && !mTransparentInputRegion) { + mSurface->set_input_region(nullptr); + } else { + struct ::wl_region *region = mDisplay->createRegion(mInputRegion); + mSurface->set_input_region(region); + wl_region_destroy(region); + } +} + void QWaylandWindow::updateViewport() { if (!surfaceSize().isEmpty()) @@ -561,17 +587,12 @@ void QWaylandWindow::setMask(const QRegion &mask) mMask = mask; - if (mMask.isEmpty()) { - mSurface->set_input_region(nullptr); + updateInputRegion(); - if (isOpaque()) + if (isOpaque()) { + if (mMask.isEmpty()) setOpaqueArea(QRect(QPoint(0, 0), geometry().size())); - } else { - struct ::wl_region *region = mDisplay->createRegion(mMask); - mSurface->set_input_region(region); - wl_region_destroy(region); - - if (isOpaque()) + } else { setOpaqueArea(mMask); } @@ -986,6 +1007,9 @@ void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) mFlags = flags; createDecoration(); + + QReadLocker locker(&mSurfaceLock); + updateInputRegion(); } bool QWaylandWindow::createDecoration() diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 17140c52e..fbf629066 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -312,6 +312,11 @@ protected: Qt::WindowFlags mFlags; QRegion mMask; + + // Empty QRegion maps to "infinite" input region, needs a dedicated "deliberately empty" state. + QRegion mInputRegion; + bool mTransparentInputRegion = false; + QRegion mOpaqueArea; Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState; ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState; @@ -337,6 +342,7 @@ private: QPlatformScreen *calculateScreenFromSurfaceEvents() const; void setOpaqueArea(const QRegion &opaqueArea); bool isOpaque() const; + void updateInputRegion(); void updateViewport(); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); |