diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index acc698f079e..aea2cfff920 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/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/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 17140c52e9f..fbf629066e3 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/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);