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>
This commit is contained in:
parent
699770b7c7
commit
0bbff7ff60
@ -327,7 +327,7 @@ void QWaylandWindow::setWindowTitle(const QString &title)
|
|||||||
mShellSurface->setTitle(truncated.toString());
|
mShellSurface->setTitle(truncated.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindowDecoration && window()->isVisible())
|
if (mWindowDecorationEnabled && window()->isVisible())
|
||||||
mWindowDecoration->update();
|
mWindowDecoration->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +335,7 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon)
|
|||||||
{
|
{
|
||||||
mWindowIcon = icon;
|
mWindowIcon = icon;
|
||||||
|
|
||||||
if (mWindowDecoration && window()->isVisible())
|
if (mWindowDecorationEnabled && window()->isVisible())
|
||||||
mWindowDecoration->update();
|
mWindowDecoration->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
|||||||
setGeometry_helper(rect);
|
setGeometry_helper(rect);
|
||||||
|
|
||||||
if (window()->isVisible() && rect.isValid()) {
|
if (window()->isVisible() && rect.isValid()) {
|
||||||
if (mWindowDecoration)
|
if (mWindowDecorationEnabled)
|
||||||
mWindowDecoration->update();
|
mWindowDecoration->update();
|
||||||
|
|
||||||
if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize)
|
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
|
// 2) Following resizeFromApplyConfigure() calls should have sizeWithMargins equal to
|
||||||
// windowContentGeometry() which excludes shadows, therefore in this case we have 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.
|
// 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);
|
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
||||||
|
|
||||||
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||||
@ -751,7 +751,7 @@ bool QWaylandWindow::waitForFrameSync(int timeout)
|
|||||||
|
|
||||||
QMargins QWaylandWindow::frameMargins() const
|
QMargins QWaylandWindow::frameMargins() const
|
||||||
{
|
{
|
||||||
if (mWindowDecoration)
|
if (mWindowDecorationEnabled)
|
||||||
return mWindowDecoration->margins();
|
return mWindowDecoration->margins();
|
||||||
else if (mShellSurface)
|
else if (mShellSurface)
|
||||||
return mShellSurface->serverSideFrameMargins();
|
return mShellSurface->serverSideFrameMargins();
|
||||||
@ -761,7 +761,7 @@ QMargins QWaylandWindow::frameMargins() const
|
|||||||
|
|
||||||
QMargins QWaylandWindow::clientSideMargins() 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;
|
QMargins shadowMargins;
|
||||||
|
|
||||||
if (mWindowDecoration)
|
if (mWindowDecorationEnabled)
|
||||||
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
||||||
|
|
||||||
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
||||||
@ -904,9 +904,14 @@ bool QWaylandWindow::createDecoration()
|
|||||||
if (!mShellSurface || !mShellSurface->wantsDecorations())
|
if (!mShellSurface || !mShellSurface->wantsDecorations())
|
||||||
decoration = false;
|
decoration = false;
|
||||||
|
|
||||||
bool hadDecoration = mWindowDecoration;
|
bool hadDecoration = mWindowDecorationEnabled;
|
||||||
if (decoration && !decorationPluginFailed) {
|
if (decoration && !decorationPluginFailed) {
|
||||||
if (!mWindowDecoration) {
|
if (!mWindowDecorationEnabled) {
|
||||||
|
if (mWindowDecoration) {
|
||||||
|
delete mWindowDecoration;
|
||||||
|
mWindowDecoration = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList decorations = QWaylandDecorationFactory::keys();
|
QStringList decorations = QWaylandDecorationFactory::keys();
|
||||||
if (decorations.empty()) {
|
if (decorations.empty()) {
|
||||||
qWarning() << "No decoration plugins available. Running with no decorations.";
|
qWarning() << "No decoration plugins available. Running with no decorations.";
|
||||||
@ -935,13 +940,13 @@ bool QWaylandWindow::createDecoration()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mWindowDecoration->setWaylandWindow(this);
|
mWindowDecoration->setWaylandWindow(this);
|
||||||
|
mWindowDecorationEnabled = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete mWindowDecoration;
|
mWindowDecorationEnabled = false;
|
||||||
mWindowDecoration = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hadDecoration != (bool)mWindowDecoration) {
|
if (hadDecoration != mWindowDecorationEnabled) {
|
||||||
for (QWaylandSubSurface *subsurf : qAsConst(mChildren)) {
|
for (QWaylandSubSurface *subsurf : qAsConst(mChildren)) {
|
||||||
QPoint pos = subsurf->window()->geometry().topLeft();
|
QPoint pos = subsurf->window()->geometry().topLeft();
|
||||||
QMargins m = frameMargins();
|
QMargins m = frameMargins();
|
||||||
@ -962,7 +967,7 @@ bool QWaylandWindow::createDecoration()
|
|||||||
|
|
||||||
QWaylandAbstractDecoration *QWaylandWindow::decoration() const
|
QWaylandAbstractDecoration *QWaylandWindow::decoration() const
|
||||||
{
|
{
|
||||||
return mWindowDecoration;
|
return mWindowDecorationEnabled ? mWindowDecoration : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QWaylandWindow *closestShellSurfaceWindow(QWindow *window)
|
static QWaylandWindow *closestShellSurfaceWindow(QWindow *window)
|
||||||
@ -993,7 +998,7 @@ QWaylandWindow *QWaylandWindow::transientParent() const
|
|||||||
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
|
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
|
||||||
{
|
{
|
||||||
if (e.type == QEvent::Leave) {
|
if (e.type == QEvent::Leave) {
|
||||||
if (mWindowDecoration) {
|
if (mWindowDecorationEnabled) {
|
||||||
if (mMouseEventsInContentArea)
|
if (mMouseEventsInContentArea)
|
||||||
QWindowSystemInterface::handleLeaveEvent(window());
|
QWindowSystemInterface::handleLeaveEvent(window());
|
||||||
} else {
|
} else {
|
||||||
@ -1005,7 +1010,7 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindowDecoration) {
|
if (mWindowDecorationEnabled) {
|
||||||
handleMouseEventWithDecoration(inputDevice, e);
|
handleMouseEventWithDecoration(inputDevice, e);
|
||||||
} else {
|
} else {
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
@ -1045,7 +1050,7 @@ void QWaylandWindow::handleSwipeGesture(QWaylandInputDevice *inputDevice,
|
|||||||
if (mGestureState != GestureNotActive)
|
if (mGestureState != GestureNotActive)
|
||||||
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
|
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
|
||||||
|
|
||||||
if (mWindowDecoration && !mMouseEventsInContentArea) {
|
if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
|
||||||
// whole gesture sequence will be ignored
|
// whole gesture sequence will be ignored
|
||||||
mGestureState = GestureActiveInDecoration;
|
mGestureState = GestureActiveInDecoration;
|
||||||
return;
|
return;
|
||||||
@ -1100,7 +1105,7 @@ void QWaylandWindow::handlePinchGesture(QWaylandInputDevice *inputDevice,
|
|||||||
if (mGestureState != GestureNotActive)
|
if (mGestureState != GestureNotActive)
|
||||||
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
|
qCWarning(lcQpaWaylandInput) << "Unexpected GestureStarted while already active";
|
||||||
|
|
||||||
if (mWindowDecoration && !mMouseEventsInContentArea) {
|
if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
|
||||||
// whole gesture sequence will be ignored
|
// whole gesture sequence will be ignored
|
||||||
mGestureState = GestureActiveInDecoration;
|
mGestureState = GestureActiveInDecoration;
|
||||||
return;
|
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)
|
bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods)
|
||||||
{
|
{
|
||||||
if (!mWindowDecoration)
|
if (!mWindowDecorationEnabled)
|
||||||
return false;
|
return false;
|
||||||
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
|
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
|
||||||
}
|
}
|
||||||
|
@ -257,6 +257,7 @@ protected:
|
|||||||
QList<QWaylandSubSurface *> mChildren;
|
QList<QWaylandSubSurface *> mChildren;
|
||||||
|
|
||||||
QWaylandAbstractDecoration *mWindowDecoration = nullptr;
|
QWaylandAbstractDecoration *mWindowDecoration = nullptr;
|
||||||
|
bool mWindowDecorationEnabled = false;
|
||||||
bool mMouseEventsInContentArea = false;
|
bool mMouseEventsInContentArea = false;
|
||||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user