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.

Pick-to: 6.6
Change-Id: I018d53196bc816b5eaea7dd3b24626a9738c9f47
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Kai Uwe Broulik 2023-08-04 13:40:46 +02:00
parent 75249a77b6
commit 349cb9eb7d
2 changed files with 39 additions and 9 deletions

View File

@ -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()

View File

@ -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);