summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInho Lee <inho.lee@qt.io>2021-09-20 20:00:49 +0200
committerInho Lee <inho.lee@qt.io>2022-02-09 12:19:06 +0100
commita889c23742fa74cf4722442352b1245a2a061362 (patch)
tree77f2135785a6125325a4b69e4c18a7503cef3f03
parent389a0a54ea3774cd07a2265ea71fcae92e7b3894 (diff)
Do not delete window decorations before next update
When window decorations are turned on/off, a timing issue might happen with accessing deleted decorations. A boolean value, mWindowDecorationEnabled, will be used instead of mWindowDecoration. Pick-to: 6.3 6.2 Fixes: QTBUG-59627 Change-Id: I5514a408d89340fdbf481721ea2dc4bf62078852 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/client/qwaylandwindow.cpp41
-rw-r--r--src/client/qwaylandwindow_p.h1
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp18
3 files changed, 34 insertions, 26 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 29e6ef671..e1c645e15 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -327,7 +327,7 @@ void QWaylandWindow::setWindowTitle(const QString &title)
mShellSurface->setTitle(truncated.toString());
}
- if (mWindowDecoration && window()->isVisible())
+ if (mWindowDecorationEnabled && window()->isVisible())
mWindowDecoration->update();
}
@@ -335,7 +335,7 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon)
{
mWindowIcon = icon;
- if (mWindowDecoration && window()->isVisible())
+ if (mWindowDecorationEnabled && window()->isVisible())
mWindowDecoration->update();
}
@@ -369,7 +369,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
setGeometry_helper(rect);
if (window()->isVisible() && rect.isValid()) {
- if (mWindowDecoration)
+ if (mWindowDecorationEnabled)
mWindowDecoration->update();
if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize)
@@ -429,7 +429,7 @@ void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, cons
// 2) Following resizeFromApplyConfigure() calls should have sizeWithMargins equal to
// windowContentGeometry() which excludes shadows, therefore in this case we have to
// exclude them too in order not to accidentally apply smaller size to the window.
- if (mWindowDecoration && (sizeWithMargins != surfaceSize()))
+ if (mWindowDecorationEnabled && (sizeWithMargins != surfaceSize()))
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
@@ -751,7 +751,7 @@ bool QWaylandWindow::waitForFrameSync(int timeout)
QMargins QWaylandWindow::frameMargins() const
{
- if (mWindowDecoration)
+ if (mWindowDecorationEnabled)
return mWindowDecoration->margins();
else if (mShellSurface)
return mShellSurface->serverSideFrameMargins();
@@ -761,7 +761,7 @@ QMargins QWaylandWindow::frameMargins() const
QMargins QWaylandWindow::clientSideMargins() const
{
- return mWindowDecoration ? mWindowDecoration->margins() : QMargins{};
+ return mWindowDecorationEnabled ? mWindowDecoration->margins() : QMargins{};
}
/*!
@@ -780,7 +780,7 @@ QRect QWaylandWindow::windowContentGeometry() const
{
QMargins shadowMargins;
- if (mWindowDecoration)
+ if (mWindowDecorationEnabled)
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
@@ -904,9 +904,14 @@ bool QWaylandWindow::createDecoration()
if (!mShellSurface || !mShellSurface->wantsDecorations())
decoration = false;
- bool hadDecoration = mWindowDecoration;
+ bool hadDecoration = mWindowDecorationEnabled;
if (decoration && !decorationPluginFailed) {
- if (!mWindowDecoration) {
+ if (!mWindowDecorationEnabled) {
+ if (mWindowDecoration) {
+ delete mWindowDecoration;
+ mWindowDecoration = nullptr;
+ }
+
QStringList decorations = QWaylandDecorationFactory::keys();
if (decorations.empty()) {
qWarning() << "No decoration plugins available. Running with no decorations.";
@@ -935,13 +940,13 @@ bool QWaylandWindow::createDecoration()
return false;
}
mWindowDecoration->setWaylandWindow(this);
+ mWindowDecorationEnabled = true;
}
} else {
- delete mWindowDecoration;
- mWindowDecoration = nullptr;
+ mWindowDecorationEnabled = false;
}
- if (hadDecoration != (bool)mWindowDecoration) {
+ if (hadDecoration != mWindowDecorationEnabled) {
for (QWaylandSubSurface *subsurf : qAsConst(mChildren)) {
QPoint pos = subsurf->window()->geometry().topLeft();
QMargins m = frameMargins();
@@ -962,7 +967,7 @@ bool QWaylandWindow::createDecoration()
QWaylandAbstractDecoration *QWaylandWindow::decoration() const
{
- return mWindowDecoration;
+ return mWindowDecorationEnabled ? mWindowDecoration : nullptr;
}
static QWaylandWindow *closestShellSurfaceWindow(QWindow *window)
@@ -993,7 +998,7 @@ QWaylandWindow *QWaylandWindow::transientParent() const
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
{
if (e.type == QEvent::Leave) {
- if (mWindowDecoration) {
+ if (mWindowDecorationEnabled) {
if (mMouseEventsInContentArea)
QWindowSystemInterface::handleLeaveEvent(window());
} else {
@@ -1005,7 +1010,7 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan
return;
}
- if (mWindowDecoration) {
+ if (mWindowDecorationEnabled) {
handleMouseEventWithDecoration(inputDevice, e);
} else {
switch (e.type) {
@@ -1045,7 +1050,7 @@ void QWaylandWindow::handleSwipeGesture(QWaylandInputDevice *inputDevice,
if (mGestureState != GestureNotActive)
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
- if (mWindowDecoration && !mMouseEventsInContentArea) {
+ if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
// whole gesture sequence will be ignored
mGestureState = GestureActiveInDecoration;
return;
@@ -1100,7 +1105,7 @@ void QWaylandWindow::handlePinchGesture(QWaylandInputDevice *inputDevice,
if (mGestureState != GestureNotActive)
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
- if (mWindowDecoration && !mMouseEventsInContentArea) {
+ if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
// whole gesture sequence will be ignored
mGestureState = GestureActiveInDecoration;
return;
@@ -1165,7 +1170,7 @@ void QWaylandWindow::handlePinchGesture(QWaylandInputDevice *inputDevice,
bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods)
{
- if (!mWindowDecoration)
+ if (!mWindowDecorationEnabled)
return false;
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
}
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 6eb8053bf..70d878f44 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -257,6 +257,7 @@ protected:
QList<QWaylandSubSurface *> mChildren;
QWaylandAbstractDecoration *mWindowDecoration = nullptr;
+ bool mWindowDecorationEnabled = false;
bool mMouseEventsInContentArea = false;
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
index e9b290a76..d8efeb4a2 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
@@ -199,14 +199,16 @@ public:
glViewport(0, 0, surfaceSize.width() * scale, surfaceSize.height() * scale);
//Draw Decoration
- m_blitProgram->setAttributeBuffer(0, GL_FLOAT, m_inverseSquareVerticesOffset, 2);
- QImage decorationImage = window->decoration()->contentImage();
- cache->bindTexture(m_context->context(), decorationImage);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_textureWrap);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_textureWrap);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ if (auto *decoration = window->decoration()) {
+ m_blitProgram->setAttributeBuffer(0, GL_FLOAT, m_inverseSquareVerticesOffset, 2);
+ QImage decorationImage = decoration->contentImage();
+ cache->bindTexture(m_context->context(), decorationImage);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_textureWrap);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_textureWrap);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
//Draw Content
m_blitProgram->setAttributeBuffer(0, GL_FLOAT, m_squareVerticesOffset, 2);