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());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -257,6 +257,7 @@ protected:
|
||||
QList<QWaylandSubSurface *> mChildren;
|
||||
|
||||
QWaylandAbstractDecoration *mWindowDecoration = nullptr;
|
||||
bool mWindowDecorationEnabled = false;
|
||||
bool mMouseEventsInContentArea = false;
|
||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user