diff --git a/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch b/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch index 1ded3fe664..cbfaaddbf7 100644 --- a/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch +++ b/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch @@ -12,34 +12,34 @@ index b65b994d6c..15a8cd6878 100644 } } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp -index 9899c9274e..272b85069f 100644 +index e57cdd8278..94613598af 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp -@@ -1160,8 +1160,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta +@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta void QObjectWrapper::destroyObject(bool lastCall) { Heap::QObjectWrapper *h = d(); - if (!h->internalClass) - return; // destroyObject already got called + Q_ASSERT(h->internalClass); - + if (h->object()) { QQmlData *ddata = QQmlData::get(h->object(), false); -@@ -1191,7 +1190,7 @@ void QObjectWrapper::destroyObject(bool lastCall) +@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall) } } - + - h->~Data(); + h->destroy(); } - - + + diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 06caf04e5a..da149a67c4 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt - + if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) { for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) { - if (!it.value().isNullOrUndefined()) @@ -47,6 +47,36 @@ index 06caf04e5a..da149a67c4 100644 it = multiplyWrappedQObjects->erase(it); else ++it; +diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp +index 175de8b936..a6ba4b8cb3 100644 +--- a/src/qml/qml/qqmltypewrapper.cpp ++++ b/src/qml/qml/qqmltypewrapper.cpp +@@ -419,8 +419,10 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const + return Encode(false); + + QQmlRefPointer td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); +- ExecutableCompilationUnit *cu = td->compilationUnit(); +- myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId); ++ if (ExecutableCompilationUnit *cu = td->compilationUnit()) ++ myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId); ++ else ++ return Encode(false); // It seems myQmlType has some errors, so we could not compile it. + } else { + myQmlType = qenginepriv->metaObjectForType(myTypeId); + } +diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp +index 29ed62cd39..aba930dfe1 100644 +--- a/src/qml/types/qqmlconnections.cpp ++++ b/src/qml/types/qqmlconnections.cpp +@@ -338,7 +338,7 @@ void QQmlConnections::connectSignalsToMethods() + && propName.at(2).isUpper()) { + qmlWarning(this) << tr("Detected function \"%1\" in Connections element. " + "This is probably intended to be a signal handler but no " +- "signal of the target matches the name.").arg(propName); ++ "signal of the \"%2\" target matches the name.").arg(propName).arg(target->metaObject()->className()); + } + } + } diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 2079a8ed04..a577cb2351 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp @@ -80,7 +110,7 @@ index 2079a8ed04..a577cb2351 100644 @@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved( } } - + +void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end) +{ + Q_D(QQmlDelegateModel); @@ -140,10 +170,10 @@ index 85719fdc80..78e2ab302c 100644 #include "QtQuick/qquicktextdocument.h" +#include "QtQuick/qquickrendercontrol.h" QT_BEGIN_NAMESPACE - + #if QT_CONFIG(accessibility) @@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item) - + QWindow *QAccessibleQuickItem::window() const { - return item()->window(); @@ -161,7 +191,7 @@ index 85719fdc80..78e2ab302c 100644 + + return window; } - + int QAccessibleQuickItem::childCount() const @@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const QAccessibleInterface *QAccessibleQuickItem::parent() const @@ -173,7 +203,7 @@ index 85719fdc80..78e2ab302c 100644 + QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr; while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci) parent = parent->parentItem(); - + if (parent) { if (parent == ci) { - // Jump out to the scene widget if the parent is the root item. @@ -190,7 +220,7 @@ index 85719fdc80..78e2ab302c 100644 @@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const QRect viewRect_ = viewRect(); QRect itemRect = rect(); - + - if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity())) + if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity())) state.invisible = true; @@ -206,15 +236,15 @@ index 85719fdc80..78e2ab302c 100644 + } return state; } - + diff --git a/src/quick/accessible/qaccessiblequickview_p.h b/src/quick/accessible/qaccessiblequickview_p.h index 39ffcaf39c..8baa01330c 100644 --- a/src/quick/accessible/qaccessiblequickview_p.h +++ b/src/quick/accessible/qaccessiblequickview_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE - + #if QT_CONFIG(accessibility) - + -class QAccessibleQuickWindow : public QAccessibleObject +class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject { @@ -227,18 +257,18 @@ index 8321fcfeed..383078b3b9 100644 @@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys) \qmlattachedproperty stringlist QtQuick::Drag::mimeData \since 5.2 - + - This property holds a map of mimeData that is used during startDrag. + This property holds a map from mime type to data that is used during startDrag. + The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded + according to the mime type. */ - + QVariantMap QQuickDragAttached::mimeData() const @@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct QDrag *drag = new QDrag(source ? source : q); QMimeData *mimeData = new QMimeData(); - + - for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) - mimeData->setData(it.key(), it.value().toString().toUtf8()); + for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) { @@ -247,217 +277,9 @@ index 8321fcfeed..383078b3b9 100644 + else + mimeData->setData(it.key(), it.value().toString().toUtf8()); + } - + drag->setMimeData(mimeData); if (pixmapLoader.isReady()) { -diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp -index e12e85db64..2fa3b7142c 100644 ---- a/src/quick/items/qquickflickable.cpp -+++ b/src/quick/items/qquickflickable.cpp -@@ -62,6 +62,8 @@ - QT_BEGIN_NAMESPACE - - Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent) -+Q_LOGGING_CATEGORY(lcWheel, "qt.quick.flickable.wheel") -+Q_LOGGING_CATEGORY(lcVel, "qt.quick.flickable.velocity") - - // FlickThreshold determines how far the "mouse" must have moved - // before we perform a flick. -@@ -263,7 +265,8 @@ QQuickFlickablePrivate::QQuickFlickablePrivate() - , deceleration(QML_FLICK_DEFAULTDECELERATION) - , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) - , delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400) -- , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr) -+ , flickBoost(1.0), initialWheelFlickDistance(qApp->styleHints()->wheelScrollLines() * 24) -+ , fixupMode(Normal), vTime(0), visibleArea(nullptr) - , flickableDirection(QQuickFlickable::AutoFlickDirection) - , boundsBehavior(QQuickFlickable::DragAndOvershootBounds) - , boundsMovement(QQuickFlickable::FollowBoundsBehavior) -@@ -531,10 +534,14 @@ void QQuickFlickablePrivate::updateBeginningEnd() - if (atBeginning != vData.atBeginning) { - vData.atBeginning = atBeginning; - atYBeginningChange = true; -+ if (!vData.moving && atBeginning) -+ vData.smoothVelocity.setValue(0); - } - if (atEnd != vData.atEnd) { - vData.atEnd = atEnd; - atYEndChange = true; -+ if (!vData.moving && atEnd) -+ vData.smoothVelocity.setValue(0); - } - - // Horizontal -@@ -547,10 +554,14 @@ void QQuickFlickablePrivate::updateBeginningEnd() - if (atBeginning != hData.atBeginning) { - hData.atBeginning = atBeginning; - atXBeginningChange = true; -+ if (!hData.moving && atBeginning) -+ hData.smoothVelocity.setValue(0); - } - if (atEnd != hData.atEnd) { - hData.atEnd = atEnd; - atXEndChange = true; -+ if (!hData.moving && atEnd) -+ hData.smoothVelocity.setValue(0); - } - - if (vData.extentsChanged) { -@@ -1489,6 +1500,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) - d->hData.velocity = 0; - d->timer.start(); - d->maybeBeginDrag(currentTimestamp, event->position()); -+ d->lastPosTime = -1; - break; - case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse - case Qt::ScrollUpdate: -@@ -1515,20 +1527,34 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) - return; - } - -+ qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / qreal(1000); -+ if (elapsed <= 0) { -+ d->lastPosTime = currentTimestamp; -+ qCDebug(lcWheel) << "insufficient elapsed time: can't calculate velocity" << elapsed; -+ return; -+ } -+ - if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull()) { -- // physical mouse wheel, so use angleDelta -+ // no pixel delta (physical mouse wheel, or "dumb" touchpad), so use angleDelta - int xDelta = event->angleDelta().x(); - int yDelta = event->angleDelta().y(); -+ // For a single "clicky" wheel event (angleDelta +/- 120), -+ // we want flick() to end up moving a distance proportional to QStyleHints::wheelScrollLines(). -+ // The decel algo from there is -+ // qreal dist = v2 / (accel * 2.0); -+ // i.e. initialWheelFlickDistance = (120 / dt)^2 / (deceleration * 2) -+ // now solve for dt: -+ // dt = 120 / sqrt(deceleration * 2 * initialWheelFlickDistance) -+ if (!isMoving()) -+ elapsed = 120 / qSqrt(d->deceleration * 2 * d->initialWheelFlickDistance); - if (yflick() && yDelta != 0) { -- bool valid = false; -- if (yDelta > 0 && contentY() > -minYExtent()) { -- d->vData.velocity = qMax(yDelta*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4)); -- valid = true; -- } else if (yDelta < 0 && contentY() < -maxYExtent()) { -- d->vData.velocity = qMin(yDelta*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); -- valid = true; -- } -- if (valid) { -+ qreal instVelocity = yDelta / elapsed; -+ // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction -+ if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 && d->vData.velocity < 0)) -+ d->vData.velocityBuffer.clear(); -+ d->vData.addVelocitySample(instVelocity, d->maxVelocity); -+ d->vData.updateVelocity(); -+ if ((yDelta > 0 && contentY() > -minYExtent()) || (yDelta < 0 && contentY() < -maxYExtent())) { - d->flickY(d->vData.velocity); - d->flickingStarted(false, true); - if (d->vData.flicking) { -@@ -1539,15 +1565,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) - } - } - if (xflick() && xDelta != 0) { -- bool valid = false; -- if (xDelta > 0 && contentX() > -minXExtent()) { -- d->hData.velocity = qMax(xDelta*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4)); -- valid = true; -- } else if (xDelta < 0 && contentX() < -maxXExtent()) { -- d->hData.velocity = qMin(xDelta*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); -- valid = true; -- } -- if (valid) { -+ qreal instVelocity = xDelta / elapsed; -+ // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction -+ if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 && d->hData.velocity < 0)) -+ d->hData.velocityBuffer.clear(); -+ d->hData.addVelocitySample(instVelocity, d->maxVelocity); -+ d->hData.updateVelocity(); -+ if ((xDelta > 0 && contentX() > -minXExtent()) || (xDelta < 0 && contentX() < -maxXExtent())) { - d->flickX(d->hData.velocity); - d->flickingStarted(true, false); - if (d->hData.flicking) { -@@ -1562,18 +1586,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) - int xDelta = event->pixelDelta().x(); - int yDelta = event->pixelDelta().y(); - -- qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / 1000.; -- if (elapsed <= 0) { -- d->lastPosTime = currentTimestamp; -- return; -- } - QVector2D velocity(xDelta / elapsed, yDelta / elapsed); -- d->lastPosTime = currentTimestamp; - d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta()); - d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta, - true, !d->scrollingPhase, true, velocity); - event->accept(); - } -+ d->lastPosTime = currentTimestamp; - - if (!event->isAccepted()) - QQuickItem::wheelEvent(event); -@@ -1744,6 +1763,10 @@ void QQuickFlickable::componentComplete() - setContentX(-minXExtent()); - if (!d->vData.explicitValue && d->vData.startMargin != 0.) - setContentY(-minYExtent()); -+ if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) { -+ d->timeline.setObjectName(QLatin1String("timeline for Flickable ") + objectName()); -+ d->velocityTimeline.setObjectName(QLatin1String("velocity timeline for Flickable ") + objectName()); -+ } - } - - void QQuickFlickable::viewportMoved(Qt::Orientations orient) -@@ -2504,9 +2527,23 @@ void QQuickFlickable::setMaximumFlickVelocity(qreal v) - - /*! - \qmlproperty real QtQuick::Flickable::flickDeceleration -- This property holds the rate at which a flick will decelerate. -- -- The default value is platform dependent. -+ This property holds the rate at which a flick will decelerate: -+ the higher the number, the faster it slows down when the user stops -+ flicking via touch, touchpad or mouse wheel. For example 0.0001 is nearly -+ "frictionless", and 10000 feels quite "sticky". -+ -+ The default value is platform dependent. Values of zero or less are not allowed. -+ -+ \note For touchpad flicking, some platforms drive Flickable directly by -+ sending QWheelEvents with QWheelEvent::phase() being \c Qt::ScrollMomentum, -+ after the user has released all fingers from the touchpad. In that case, -+ the operating system is controlling the deceleration, and this property has -+ no effect. -+ -+ \note For mouse wheel scrolling, and for gesture scrolling on touchpads -+ that do not have a momentum phase, extremely large values of -+ flickDeceleration can make Flickable very resistant to scrolling, -+ especially if \l maximumFlickVelocity is too small. - */ - qreal QQuickFlickable::flickDeceleration() const - { -@@ -2519,7 +2556,7 @@ void QQuickFlickable::setFlickDeceleration(qreal deceleration) - Q_D(QQuickFlickable); - if (deceleration == d->deceleration) - return; -- d->deceleration = deceleration; -+ d->deceleration = qMax(0.001, deceleration); - emit flickDecelerationChanged(); - } - -diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h -index 414c9c33d6..6163613493 100644 ---- a/src/quick/items/qquickflickable_p_p.h -+++ b/src/quick/items/qquickflickable_p_p.h -@@ -241,6 +241,7 @@ public: - int pressDelay; - int fixupDuration; - qreal flickBoost; -+ qreal initialWheelFlickDistance; - - enum FixupMode { Normal, Immediate, ExtentChanged }; - FixupMode fixupMode; diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 75f1457816..dec0ae19ae 100644 --- a/src/quick/items/qquickitem.cpp @@ -467,7 +289,7 @@ index 75f1457816..dec0ae19ae 100644 #include #include +#include - + #include #include @@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent) @@ -475,7 +297,7 @@ index 75f1457816..dec0ae19ae 100644 { Q_D(QQuickItem); + d->inDestructor = true; - + if (d->windowRefCount > 1) d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow(). @@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo @@ -499,7 +321,7 @@ index 75f1457816..dec0ae19ae 100644 if (item == contentItem) { qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem"; @@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) - + const bool wasVisible = isVisible(); op->removeChild(this); - if (wasVisible) { @@ -510,9 +332,9 @@ index 75f1457816..dec0ae19ae 100644 QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this); } @@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) - + d->itemChange(ItemParentHasChanged, d->parentItem); - + - emit parentChanged(d->parentItem); - if (isVisible() && d->parentItem) + if (!d->inDestructor) @@ -520,16 +342,16 @@ index 75f1457816..dec0ae19ae 100644 + if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor) emit d->parentItem->visibleChildrenChanged(); } - + @@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child) - + itemChange(QQuickItem::ItemChildRemovedChange, child); - + - emit q->childrenChanged(); + if (!inDestructor) + emit q->childrenChanged(); } - + void QQuickItemPrivate::refWindow(QQuickWindow *c) @@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate() , touchEnabled(false) @@ -551,7 +373,7 @@ index 75f1457816..dec0ae19ae 100644 + } +#endif } - + QQuickStateGroup *QQuickItemPrivate::_states() @@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) QAccessible::updateAccessibility(&ev); @@ -565,12 +387,12 @@ index 75f1457816..dec0ae19ae 100644 + if (childVisibilityChanged) + emit q->visibleChildrenChanged(); + } - + return true; // effective visibility DID change } @@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec } - + itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable); +#if QT_CONFIG(accessibility) + if (isAccessible) { @@ -583,7 +405,7 @@ index 75f1457816..dec0ae19ae 100644 +#endif emit q->enabledChanged(); } - + diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 841d91bb40..ade8fb61f2 100644 --- a/src/quick/items/qquickitem_p.h @@ -593,15 +415,15 @@ index 841d91bb40..ade8fb61f2 100644 bool touchEnabled:1; bool hasCursorHandler:1; + quint32 inDestructor:1; // has entered ~QQuickItem - + enum DirtyType { TransformOrigin = 0x00000001, diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp -index 13e7b87049..f8ad168a17 100644 +index 010a0152e1..f8ad168a17 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) - + do { bufferPause.stop(); - if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) { @@ -609,21 +431,12 @@ index 13e7b87049..f8ad168a17 100644 currentChanges.reset(); bufferedChanges.reset(); releaseVisibleItems(reusableFlag); -@@ -2402,8 +2402,6 @@ void QQuickItemView::createdItem(int index, QObject* object) - d->repositionPackageItemAt(item, index); - else if (index == d->currentIndex) - d->updateCurrent(index); -- } else if (index == d->currentIndex) { -- d->updateCurrent(index); - } - } - diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h index fba383e268..0d63618622 100644 --- a/src/quick/items/qquickmousearea_p_p.h +++ b/src/quick/items/qquickmousearea_p_p.h @@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE - + class QQuickMouseEvent; class QQuickMouseArea; -class QQuickPointerMask; @@ -638,44 +451,6 @@ index fba383e268..0d63618622 100644 QPointF startScene; QPointF targetStartPos; QPointF lastPos; -diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp -index 4f61d61309..b298ed74da 100644 ---- a/src/quick/items/qquickshadereffectsource.cpp -+++ b/src/quick/items/qquickshadereffectsource.cpp -@@ -344,7 +344,6 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) - d->refFromEffectItem(m_hideSource); - d->addItemChangeListener(this, QQuickItemPrivate::Geometry); - connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); -- connect(m_sourceItem, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(sourceItemParentChanged(QQuickItem*))); - } else { - qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); - m_sourceItem = nullptr; -@@ -364,13 +363,6 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item) - } - - --void QQuickShaderEffectSource::sourceItemParentChanged(QQuickItem *parent) --{ -- if (!parent && m_texture) -- m_texture->setItem(0); --} -- -- - /*! - \qmlproperty rect QtQuick::ShaderEffectSource::sourceRect - -diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h -index 4deb6c70a3..c0a1ccab78 100644 ---- a/src/quick/items/qquickshadereffectsource_p.h -+++ b/src/quick/items/qquickshadereffectsource_p.h -@@ -173,7 +173,6 @@ Q_SIGNALS: - private Q_SLOTS: - void sourceItemDestroyed(QObject *item); - void invalidateSceneGraph(); -- void sourceItemParentChanged(QQuickItem *parent); - - protected: - void releaseResources() override; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 6230186933..e823ca1095 100644 --- a/src/quick/items/qquicktext.cpp @@ -687,14 +462,14 @@ index 6230186933..e823ca1095 100644 - > < & + > < & "   ' \endcode - + \c Text.StyledText parser is strict, requiring tags to be correctly nested. diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp -index 53b6fe117f..219cdd5966 100644 +index eb4db0f85e..2325a2665b 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) - + const char *textureRecord = allocatorData; for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) { - if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) { @@ -703,7 +478,7 @@ index 53b6fe117f..219cdd5966 100644 qPrintable(font.familyName())); return false; @@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) - + const char *glyphRecord = textureRecord; for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) { - if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) { @@ -712,7 +487,7 @@ index 53b6fe117f..219cdd5966 100644 qPrintable(font.familyName())); return false; @@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) - + int width = texInfo->allocatedArea.width(); int height = texInfo->allocatedArea.height(); - qint64 size = width * height; @@ -735,27 +510,6 @@ index d531fc9205..a25af90414 100644 else if (entity == QLatin1String("quot")) textOut += QChar(34); else if (entity == QLatin1String("nbsp")) -diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp -index 7ec7c827eb..abe6eb7261 100644 ---- a/src/quick/util/qquicktimeline.cpp -+++ b/src/quick/util/qquicktimeline.cpp -@@ -53,6 +53,8 @@ - - QT_BEGIN_NAMESPACE - -+Q_LOGGING_CATEGORY(lcTl, "qt.quick.timeline") -+ - struct Update { - Update(QQuickTimeLineValue *_g, qreal _v) - : g(_g), v(_v) {} -@@ -513,6 +515,7 @@ void QQuickTimeLine::reset(QQuickTimeLineValue &timeLineValue) - qWarning() << "QQuickTimeLine: Cannot reset a QQuickTimeLineValue owned by another timeline."; - return; - } -+ qCDebug(lcTl) << static_cast(this) << timeLineValue.value(); - remove(&timeLineValue); - timeLineValue._t = nullptr; - } diff --git a/src/quickwidgets/qaccessiblequickwidget.cpp b/src/quickwidgets/qaccessiblequickwidget.cpp new file mode 100644 index 0000000000..8a1c901880 @@ -1116,17 +870,17 @@ index 39780f8de3..9c97b43518 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -39,6 +39,7 @@ - + #include "qquickwidget.h" #include "qquickwidget_p.h" +#include "qaccessiblequickwidgetfactory_p.h" - + #include "private/qquickwindow_p.h" #include "private/qquickitem_p.h" @@ -75,9 +76,16 @@ - + QT_BEGIN_NAMESPACE - + +QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control) +:QQuickWindow(dd, control) +{ @@ -1143,7 +897,7 @@ index 39780f8de3..9c97b43518 100644 Q_Q(QWindow); @@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e) Q_Q(QQuickWidget); - + renderControl = new QQuickWidgetRenderControl(q); - offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl); - offscreenWindow->setTitle(QString::fromLatin1("Offscreen")); @@ -1151,7 +905,7 @@ index 39780f8de3..9c97b43518 100644 + offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl); + offscreenWindow->setScreen(q->screen()); // Do not call create() on offscreenWindow. - + // Check if the Software Adaptation is being used @@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e) QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged); @@ -1162,10 +916,10 @@ index 39780f8de3..9c97b43518 100644 + QAccessible::installFactory(&qAccessibleQuickWidgetFactory); +#endif } - + void QQuickWidgetPrivate::ensureEngine() const @@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext() - + context = new QOpenGLContext; context->setFormat(offscreenWindow->requestedFormat()); - const QWindow *win = q->window()->windowHandle(); @@ -1178,7 +932,7 @@ index 39780f8de3..9c97b43518 100644 @@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e) d->handleWindowChange(); break; - + - case QEvent::ScreenChangeInternal: - if (QWindow *window = this->window()->windowHandle()) { - QScreen *newScreen = window->screen(); @@ -1200,7 +954,7 @@ index 39780f8de3..9c97b43518 100644 + d->context->setScreen(newScreen); #endif - } - + if (d->useSoftwareRenderer #if QT_CONFIG(opengl) @@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e) @@ -1219,7 +973,7 @@ index 881f7f9220..1a946bcc71 100644 @@ -148,6 +148,14 @@ public: bool forceFullUpdate; }; - + +class QQuickWidgetOffscreenWindow: public QQuickWindow +{ + Q_OBJECT @@ -1229,7 +983,7 @@ index 881f7f9220..1a946bcc71 100644 +}; + QT_END_NAMESPACE - + #endif // QQuickWidget_P_H diff --git a/src/quickwidgets/quickwidgets.pro b/src/quickwidgets/quickwidgets.pro index 2438e577ae..85d156b8a3 100644 @@ -1243,13 +997,13 @@ index 2438e577ae..85d156b8a3 100644 + qtquickwidgetsglobal.h \ + qaccessiblequickwidget_p.h \ + qaccessiblequickwidgetfactory_p.h - + SOURCES += \ - qquickwidget.cpp + qquickwidget.cpp \ + qaccessiblequickwidget.cpp \ + qaccessiblequickwidgetfactory.cpp - + load(qt_module) diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 3b7d74df63..b75bf820d5 100644 @@ -1266,7 +1020,7 @@ index 3b7d74df63..b75bf820d5 100644 @@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage() QVERIFY(ptr.isNull()); } - + +class TestObjectContainer : public QObject +{ + Q_OBJECT @@ -1331,7 +1085,7 @@ index 35f1e2c94d..1722447830 100644 +++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp @@ -27,6 +27,8 @@ ****************************************************************************/ - + #include +#include +#include @@ -1344,12 +1098,12 @@ index 35f1e2c94d..1722447830 100644 void contextAccessedByHandler(); + void redrawUponColumnChange(); }; - + class AbstractItemModel : public QAbstractItemModel @@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler() QVERIFY(root->property("works").toBool()); } - + +void tst_QQmlDelegateModel::redrawUponColumnChange() +{ + QStandardItemModel m1; @@ -1375,8 +1129,65 @@ index 35f1e2c94d..1722447830 100644 +} + QTEST_MAIN(tst_QQmlDelegateModel) - + #include "tst_qqmldelegatemodel.moc" +diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml +new file mode 100644 +index 0000000000..e24d9112a8 +--- /dev/null ++++ b/tests/auto/qml/qqmllanguage/data/Broken.qml +@@ -0,0 +1,5 @@ ++import QtQml 2.15 ++ ++QtObject { ++ notThere: 5 ++} +diff --git a/tests/auto/qml/qqmllanguage/data/asBroken.qml b/tests/auto/qml/qqmllanguage/data/asBroken.qml +new file mode 100644 +index 0000000000..bd88d14c76 +--- /dev/null ++++ b/tests/auto/qml/qqmllanguage/data/asBroken.qml +@@ -0,0 +1,6 @@ ++import QtQml 2.15 ++ ++QtObject { ++ id: self ++ property var selfAsBroken: self as Broken ++} +diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +index bffb62c59e..97cc64991f 100644 +--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp ++++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +@@ -336,6 +336,7 @@ private slots: + void bareInlineComponent(); + + void hangOnWarning(); ++ void objectAsBroken(); + + void ambiguousContainingType(); + +@@ -5876,6 +5877,21 @@ void tst_qqmllanguage::ambiguousContainingType() + } + } + ++void tst_qqmllanguage::objectAsBroken() ++{ ++ QQmlEngine engine; ++ QQmlComponent c(&engine, testFileUrl("asBroken.qml")); ++ QVERIFY2(c.isReady(), qPrintable(c.errorString())); ++ QScopedPointer o(c.create()); ++ QVERIFY(!o.isNull()); ++ QVariant selfAsBroken = o->property("selfAsBroken"); ++ QVERIFY(selfAsBroken.isValid()); ++ // QCOMPARE(selfAsBroken.metaType(), QMetaType::fromType()); ++ ++ QQmlComponent b(&engine, testFileUrl("Broken.qml")); ++ QVERIFY(b.isError()); ++} ++ + QTEST_MAIN(tst_qqmllanguage) + + #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp index 5d635aa63b..824fd89e5b 100644 --- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp @@ -1384,7 +1195,7 @@ index 5d635aa63b..824fd89e5b 100644 @@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects() QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1); QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); - + - // Moves the additional WeakValue from m_multiplyWrappedQObjects to - // m_pendingFreedObjectWrapperValue. It's still alive after all. + // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved @@ -1392,77 +1203,9 @@ index 5d635aa63b..824fd89e5b 100644 engine1.memoryManager->runGC(); - QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2); + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1); - + // engine2 doesn't own the object as engine1 was the first to wrap it above. // Therefore, no effect here. -diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp -index f3659290eb..9fa51da6f8 100644 ---- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp -+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp -@@ -870,6 +870,7 @@ void tst_qquickflickable::wheel() - QVERIFY(flick != nullptr); - QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flick); - QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); -+ quint64 timestamp = 10; - - // test a vertical flick - { -@@ -877,6 +878,7 @@ void tst_qquickflickable::wheel() - QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120), - Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); - event.setAccepted(false); -+ event.setTimestamp(timestamp); - QGuiApplication::sendEvent(window.data(), &event); - } - -@@ -887,6 +889,7 @@ void tst_qquickflickable::wheel() - QCOMPARE(fp->velocityTimeline.isActive(), false); - QCOMPARE(fp->timeline.isActive(), false); - QTest::qWait(50); // make sure that onContentYChanged won't sneak in again -+ timestamp += 50; - QCOMPARE(flick->property("movementsAfterEnd").value(), 0); // QTBUG-55886 - - // get ready to test horizontal flick -@@ -900,8 +903,8 @@ void tst_qquickflickable::wheel() - QPoint pos(200, 200); - QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0), - Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); -- - event.setAccepted(false); -+ event.setTimestamp(timestamp); - QGuiApplication::sendEvent(window.data(), &event); - } - -@@ -926,11 +929,13 @@ void tst_qquickflickable::trackpad() - QVERIFY(flick != nullptr); - QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); - QPoint pos(200, 200); -+ quint64 timestamp = 10; - - { - QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120), - Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin, false); - event.setAccepted(false); -+ event.setTimestamp(timestamp++); - QGuiApplication::sendEvent(window.data(), &event); - } - -@@ -944,6 +949,7 @@ void tst_qquickflickable::trackpad() - QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0), - Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate, false); - event.setAccepted(false); -+ event.setTimestamp(timestamp++); - QGuiApplication::sendEvent(window.data(), &event); - } - -@@ -954,6 +960,7 @@ void tst_qquickflickable::trackpad() - QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0), - Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, false); - event.setAccepted(false); -+ event.setTimestamp(timestamp++); - QGuiApplication::sendEvent(window.data(), &event); - } - diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml new file mode 100644 index 0000000000..889e480f3b @@ -1491,13 +1234,13 @@ index c8f251dbe1..c8ef36ee68 100644 void activeFocusOnTab_infiniteLoop_data(); void activeFocusOnTab_infiniteLoop(); + void activeFocusOnTab_infiniteLoopControls(); - + void nextItemInFocusChain(); void nextItemInFocusChain2(); @@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop() QCOMPARE(item, window->rootObject()); } - + + +void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls() +{ @@ -1512,96 +1255,3 @@ index c8f251dbe1..c8ef36ee68 100644 void tst_QQuickItem::nextItemInFocusChain() { if (!qt_tab_all_widgets()) -diff --git a/tests/auto/quick/qquicklistview/data/qtbug86744.qml b/tests/auto/quick/qquicklistview/data/qtbug86744.qml -deleted file mode 100644 -index 6dc82d57eb..0000000000 ---- a/tests/auto/quick/qquicklistview/data/qtbug86744.qml -+++ /dev/null -@@ -1,21 +0,0 @@ --import QtQuick 2.15 --import QtQml.Models 2.15 -- --Item { -- height: 200 -- width: 100 -- DelegateModel { -- id: dm -- model: 2 -- delegate: Item { -- width: 100; height: 20 -- property bool isCurrent: ListView.isCurrentItem -- } -- } -- ListView { -- objectName: "listView" -- model: dm -- currentIndex: 1 -- anchors.fill: parent -- } --} -diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp -index df329f8318..b564fd3ba5 100644 ---- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp -+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp -@@ -10201,20 +10201,6 @@ void tst_QQuickListView::dragDelegateWithMouseArea_data() - } - } - --void tst_QQuickListView::isCurrentItem_DelegateModel() --{ -- QScopedPointer window(createView()); -- window->setSource(testFileUrl("qtbug86744.qml")); -- window->resize(640, 480); -- window->show(); -- QVERIFY(QTest::qWaitForWindowExposed(window.data())); -- -- QQuickListView* listView = window->rootObject()->findChild("listView"); -- QVERIFY(listView); -- QVariant value = listView->itemAtIndex(1)->property("isCurrent"); -- QVERIFY(value.toBool() == true); --} -- - QTEST_MAIN(tst_QQuickListView) - - #include "tst_qquicklistview.moc" -diff --git a/tests/manual/touch/flicktext.qml b/tests/manual/touch/flicktext.qml -index 9e84261687..e69d6207a9 100644 ---- a/tests/manual/touch/flicktext.qml -+++ b/tests/manual/touch/flicktext.qml -@@ -380,6 +380,36 @@ Rectangle { - text: "content X " + flick.contentX.toFixed(2) + " Y " + flick.contentY.toFixed(2) - } - } -+ -+ Column { -+ Row { -+ spacing: 2 -+ Examples.Button { -+ id: decrButton -+ text: "-" -+ onClicked: flick.flickDeceleration -= 100 -+ Timer { -+ running: decrButton.pressed -+ interval: 100; repeat: true -+ onTriggered: flick.flickDeceleration -= 100 -+ } -+ } -+ Text { -+ horizontalAlignment: Text.AlignHCenter -+ text: "decel:\n" + flick.flickDeceleration.toFixed(4) -+ } -+ Examples.Button { -+ id: incrButton -+ text: "+" -+ onClicked: flick.flickDeceleration += 100 -+ } -+ Timer { -+ running: incrButton.pressed -+ interval: 100; repeat: true -+ onTriggered: flick.flickDeceleration += 100 -+ } -+ } -+ } - } - - Component.onCompleted: { diff --git a/desktop/toolkit/qt5/qt5-declarative/pspec.xml b/desktop/toolkit/qt5/qt5-declarative/pspec.xml index c40be834c2..3e2c817f39 100755 --- a/desktop/toolkit/qt5/qt5-declarative/pspec.xml +++ b/desktop/toolkit/qt5/qt5-declarative/pspec.xml @@ -69,6 +69,13 @@ + + 2023-02-15 + 5.15.7 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-21 5.15.7 diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch b/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch index 58bc945089..78382fbefc 100644 --- a/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch +++ b/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch @@ -30,7 +30,7 @@ index 2f424580..29222357 100644 + "use": "egl wayland-client" } }, - + diff --git a/src/client/global/qwaylandclientextension.cpp b/src/client/global/qwaylandclientextension.cpp index 125b1e19..edccfe63 100644 --- a/src/client/global/qwaylandclientextension.cpp @@ -45,12 +45,12 @@ index 125b1e19..edccfe63 100644 + d->registered = true; + } } - + QWaylandClientExtension::QWaylandClientExtension(const int ver) @@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver) QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection); } - + +QWaylandClientExtension::~QWaylandClientExtension() +{ + Q_D(QWaylandClientExtension); @@ -70,7 +70,7 @@ index 98272e57..5bd28398 100644 public: QWaylandClientExtension(const int version); + ~QWaylandClientExtension(); - + QtWaylandClient::QWaylandIntegration *integration() const; int version() const; diff --git a/src/client/global/qwaylandclientextension_p.h b/src/client/global/qwaylandclientextension_p.h @@ -83,25 +83,25 @@ index 69cc46a0..9091efbe 100644 bool active = false; + bool registered = false; }; - + class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index 7e2e3308..e3e60ed5 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -72,6 +72,8 @@ QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWayl - + QWaylandDataDevice::~QWaylandDataDevice() { + if (wl_data_device_get_version(object()) >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION) + release(); } - + QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const @@ -110,7 +112,7 @@ QWaylandDataOffer *QWaylandDataDevice::dragOffer() const return m_dragOffer.data(); } - + -bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) +bool QWaylandDataDevice::startDrag(QMimeData *mimeData, Qt::DropActions supportedActions, QWaylandWindow *icon) { @@ -109,7 +109,7 @@ index 7e2e3308..e3e60ed5 100644 auto *origin = seat->pointerFocus(); @@ -123,7 +125,28 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) } - + m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); + + if (wl_data_device_get_version(object()) >= 3) @@ -133,7 +133,7 @@ index 7e2e3308..e3e60ed5 100644 + connect(m_dragSource.data(), &QWaylandDataSource::finished, this, []() { + static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(); + }); - + start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); return true; @@ -152,7 +175,7 @@ void QWaylandDataDevice::data_device_drop() @@ -147,7 +147,7 @@ index 7e2e3308..e3e60ed5 100644 } @@ -162,7 +185,11 @@ void QWaylandDataDevice::data_device_drop() QGuiApplication::keyboardModifiers()); - + if (drag) { - static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(response); + auto drag = static_cast(QGuiApplicationPrivate::platformIntegration()->drag()); @@ -157,7 +157,7 @@ index 7e2e3308..e3e60ed5 100644 + m_dragOffer->finish(); } } - + @@ -186,7 +213,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, supportedActions = drag->supportedActions(); } else if (m_dragOffer) { @@ -165,12 +165,12 @@ index 7e2e3308..e3e60ed5 100644 - supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + supportedActions = m_dragOffer->supportedActions(); } - + const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions, @@ -197,11 +224,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } - + - if (response.isAccepted()) { - wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData()); - } else { @@ -178,7 +178,7 @@ index 7e2e3308..e3e60ed5 100644 - } + sendResponse(supportedActions, response); } - + void QWaylandDataDevice::data_device_leave() @@ -235,10 +258,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe supportedActions = drag->supportedActions(); @@ -187,16 +187,16 @@ index 7e2e3308..e3e60ed5 100644 - supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + supportedActions = m_dragOffer->supportedActions(); } - + - QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions, + const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); - + @@ -246,11 +269,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } - + - if (response.isAccepted()) { - wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData()); - } else { @@ -205,7 +205,7 @@ index 7e2e3308..e3e60ed5 100644 + sendResponse(supportedActions, response); } #endif // QT_CONFIG(draganddrop) - + @@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled() #if QT_CONFIG(draganddrop) void QWaylandDataDevice::dragSourceCancelled() @@ -213,7 +213,7 @@ index 7e2e3308..e3e60ed5 100644 + static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(); m_dragSource.reset(); } - + -void QWaylandDataDevice::dragSourceTargetChanged(const QString &mimeType) -{ - static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->updateTarget(mimeType); @@ -254,7 +254,7 @@ index 7e2e3308..e3e60ed5 100644 + + #endif // QT_CONFIG(draganddrop) - + } diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h index 16c3ad28..801dcc2c 100644 @@ -262,28 +262,28 @@ index 16c3ad28..801dcc2c 100644 +++ b/src/client/qwaylanddatadevice_p.h @@ -64,6 +64,7 @@ QT_REQUIRE_CONFIG(wayland_datadevice); QT_BEGIN_NAMESPACE - + class QMimeData; +class QPlatformDragQtResponse; class QWindow; - + namespace QtWaylandClient { @@ -89,7 +90,7 @@ public: - + #if QT_CONFIG(draganddrop) QWaylandDataOffer *dragOffer() const; - bool startDrag(QMimeData *mimeData, QWaylandWindow *icon); + bool startDrag(QMimeData *mimeData, Qt::DropActions supportedActions, QWaylandWindow *icon); void cancelDrag(); #endif - + @@ -109,13 +110,16 @@ private Q_SLOTS: - + #if QT_CONFIG(draganddrop) void dragSourceCancelled(); - void dragSourceTargetChanged(const QString &mimeType); #endif - + private: #if QT_CONFIG(draganddrop) QPoint calculateDragPosition(int x, int y, QWindow *wnd) const; @@ -292,7 +292,7 @@ index 16c3ad28..801dcc2c 100644 + + static int dropActionsToWl(Qt::DropActions dropActions); + - + QWaylandDisplay *m_display = nullptr; QWaylandInputDevice *m_inputDevice = nullptr; diff --git a/src/client/qwaylanddatadevicemanager.cpp b/src/client/qwaylanddatadevicemanager.cpp @@ -300,9 +300,9 @@ index 35d67307..6dc4f77f 100644 --- a/src/client/qwaylanddatadevicemanager.cpp +++ b/src/client/qwaylanddatadevicemanager.cpp @@ -50,8 +50,8 @@ QT_BEGIN_NAMESPACE - + namespace QtWaylandClient { - + -QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id) - : wl_data_device_manager(display->wl_registry(), id, 1) +QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, int version, uint32_t id) @@ -321,7 +321,7 @@ index bd05c0fb..510d9be4 100644 - QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id); + QWaylandDataDeviceManager(QWaylandDisplay *display, int version, uint32_t id); ~QWaylandDataDeviceManager() override; - + QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice); diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp index 2297e8a1..fe0ea8c9 100644 @@ -330,7 +330,7 @@ index 2297e8a1..fe0ea8c9 100644 @@ -82,6 +82,15 @@ QMimeData *QWaylandDataOffer::mimeData() return m_mimeData.data(); } - + +Qt::DropActions QWaylandDataOffer::supportedActions() const +{ + if (wl_data_offer_get_version(const_cast<::wl_data_offer*>(object())) < 3) { @@ -346,7 +346,7 @@ index 2297e8a1..fe0ea8c9 100644 @@ -93,6 +102,22 @@ void QWaylandDataOffer::data_offer_offer(const QString &mime_type) m_mimeData->appendFormat(mime_type); } - + +void QWaylandDataOffer::data_offer_action(uint32_t dnd_action) +{ + Q_UNUSED(dnd_action); @@ -367,7 +367,7 @@ index 2297e8a1..fe0ea8c9 100644 : m_dataOffer(dataOffer) { @@ -163,17 +188,18 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T - + int QWaylandMimeData::readData(int fd, QByteArray &data) const { - fd_set readset; @@ -382,7 +382,7 @@ index 2297e8a1..fe0ea8c9 100644 - timeout.tv_usec = 0; + timeout.tv_nsec = 0; + - + Q_FOREVER { - int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout); + int ready = qt_safe_poll(&readset, 1, &timeout); @@ -401,29 +401,29 @@ index 9cf1483c..6f667398 100644 ~QWaylandDataOffer() override; QMimeData *mimeData() override; + Qt::DropActions supportedActions() const; - + QString firstFormat() const; - + @@ -89,10 +90,13 @@ public: - + protected: void data_offer_offer(const QString &mime_type) override; + void data_offer_source_actions(uint32_t source_actions) override; + void data_offer_action(uint32_t dnd_action) override; - + private: QWaylandDisplay *m_display = nullptr; QScopedPointer m_mimeData; + Qt::DropActions m_supportedActions; }; - - + + diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp index f45122fb..5599cbd4 100644 --- a/src/client/qwaylanddatasource.cpp +++ b/src/client/qwaylanddatasource.cpp @@ -101,7 +101,32 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) - + void QWaylandDataSource::data_source_target(const QString &mime_type) { - Q_EMIT targetChanged(mime_type); @@ -454,7 +454,7 @@ index f45122fb..5599cbd4 100644 + + Q_EMIT dndDropped(m_accepted, m_dropAction); } - + } diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h index 25afff79..96f07bc3 100644 @@ -462,7 +462,7 @@ index 25afff79..96f07bc3 100644 +++ b/src/client/qwaylanddatasource_p.h @@ -77,17 +77,25 @@ public: QMimeData *mimeData() const; - + Q_SIGNALS: - void targetChanged(const QString &mime_type); void cancelled(); @@ -470,7 +470,7 @@ index 25afff79..96f07bc3 100644 + + void dndResponseUpdated(bool accepted, Qt::DropAction action); + void dndDropped(bool accepted, Qt::DropAction action); - + protected: void data_source_cancelled() override; void data_source_send(const QString &mime_type, int32_t fd) override; @@ -478,23 +478,23 @@ index 25afff79..96f07bc3 100644 + void data_source_dnd_drop_performed() override; + void data_source_dnd_finished() override; + void data_source_action(uint32_t action) override; - + private: QWaylandDisplay *m_display = nullptr; QMimeData *m_mime_data = nullptr; + bool m_accepted = false; + Qt::DropAction m_dropAction = Qt::IgnoreAction; }; - + } diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index f10c1f79..e8613ed8 100644 +index f10c1f79..c01e238b 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -85,10 +85,203 @@ - + #include - + +#include // for std::tie + +static void checkWaylandError(struct wl_display *display) @@ -510,9 +510,9 @@ index f10c1f79..e8613ed8 100644 +} + QT_BEGIN_NAMESPACE - + namespace QtWaylandClient { - + +class EventThread : public QThread +{ + Q_OBJECT @@ -693,7 +693,7 @@ index f10c1f79..e8613ed8 100644 +}; + Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorized) Wayland platform logging - + struct wl_surface *QWaylandDisplay::createSurface(void *handle) @@ -158,17 +351,16 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) if (!mXkbContext) @@ -707,7 +707,7 @@ index f10c1f79..e8613ed8 100644 - forceRoundTrip(); - } } - + QWaylandDisplay::~QWaylandDisplay(void) { + if (m_eventThread) @@ -718,7 +718,7 @@ index f10c1f79..e8613ed8 100644 + if (mSyncCallback) wl_callback_destroy(mSyncCallback); - + @@ -187,6 +379,21 @@ QWaylandDisplay::~QWaylandDisplay(void) #endif if (mDisplay) @@ -739,10 +739,10 @@ index f10c1f79..e8613ed8 100644 + forceRoundTrip(); + } } - + void QWaylandDisplay::ensureScreen() @@ -203,98 +410,37 @@ void QWaylandDisplay::ensureScreen() - + void QWaylandDisplay::checkError() const { - int ecode = wl_display_get_error(mDisplay); @@ -755,7 +755,7 @@ index f10c1f79..e8613ed8 100644 - _exit(1); + checkWaylandError(mDisplay); } - + +// Called in main thread, either from queued signal or directly. void QWaylandDisplay::flushRequests() { @@ -778,24 +778,14 @@ index f10c1f79..e8613ed8 100644 - } - - wl_display_flush(mDisplay); -+ m_eventThread->readAndDispatchEvents(); - } - +-} +- -void QWaylandDisplay::blockingReadEvents() -+// We have to wait until we have an eventDispatcher before creating the eventThread, -+// otherwise forceRoundTrip() may block inside _events_read() because eventThread is -+// polling. -+void QWaylandDisplay::initEventThread() - { +-{ - if (wl_display_dispatch(mDisplay) < 0) - checkError(); -} -+ m_eventThread.reset( -+ new EventThread(mDisplay, /* default queue */ nullptr, EventThread::EmitToDispatch)); -+ connect(m_eventThread.get(), &EventThread::needReadAndDispatch, this, -+ &QWaylandDisplay::flushRequests, Qt::QueuedConnection); -+ m_eventThread->start(); - +- -void QWaylandDisplay::destroyFrameQueue(const QWaylandDisplay::FrameQueue &q) -{ - QWriteLocker locker(&m_frameQueueLock); @@ -807,26 +797,36 @@ index f10c1f79..e8613ed8 100644 - if (q.queue != nullptr) - wl_event_queue_destroy(q.queue); - delete q.mutex; ++ m_eventThread->readAndDispatchEvents(); + } + +-QWaylandDisplay::FrameQueue QWaylandDisplay::createFrameQueue() ++// We have to wait until we have an eventDispatcher before creating the eventThread, ++// otherwise forceRoundTrip() may block inside _events_read() because eventThread is ++// polling. ++void QWaylandDisplay::initEventThread() + { +- QWriteLocker locker(&m_frameQueueLock); +- FrameQueue q{createEventQueue()}; +- mExternalQueues.append(q); +- return q; +-} ++ m_eventThread.reset( ++ new EventThread(mDisplay, /* default queue */ nullptr, EventThread::EmitToDispatch)); ++ connect(m_eventThread.get(), &EventThread::needReadAndDispatch, this, ++ &QWaylandDisplay::flushRequests, Qt::QueuedConnection); ++ m_eventThread->start(); + +-wl_event_queue *QWaylandDisplay::createEventQueue() +-{ +- return wl_display_create_queue(mDisplay); + // wl_display_disconnect() free this. + m_frameEventQueue = wl_display_create_queue(mDisplay); + m_frameEventQueueThread.reset( + new EventThread(mDisplay, m_frameEventQueue, EventThread::SelfDispatch)); + m_frameEventQueueThread->start(); } - --QWaylandDisplay::FrameQueue QWaylandDisplay::createFrameQueue() --{ -- QWriteLocker locker(&m_frameQueueLock); -- FrameQueue q{createEventQueue()}; -- mExternalQueues.append(q); -- return q; --} -- --wl_event_queue *QWaylandDisplay::createEventQueue() --{ -- return wl_display_create_queue(mDisplay); --} -- + -void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue, std::function condition, int timeout) +void QWaylandDisplay::blockingReadEvents() { @@ -858,7 +858,7 @@ index f10c1f79..e8613ed8 100644 + if (wl_display_dispatch(mDisplay) < 0) + checkWaylandError(mDisplay); } - + QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const @@ -345,7 +491,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin if (interface == QStringLiteral("wl_output")) { @@ -878,8 +878,31 @@ index f10c1f79..e8613ed8 100644 #endif } else if (interface == QStringLiteral("qt_surface_extension")) { mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1)); -@@ -452,9 +598,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) - +@@ -369,6 +515,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin + #if QT_CONFIG(wayland_client_primary_selection) + } else if (interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) { + mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1)); ++ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices)) ++ inputDevice->setPrimarySelectionDevice(mPrimarySelectionManager->createDevice(inputDevice)); + #endif + } else if (interface == QStringLiteral("zwp_text_input_manager_v2") && !mClientSideInputContextRequested) { + mTextInputManager.reset(new QtWayland::zwp_text_input_manager_v2(registry, id, 1)); +@@ -427,6 +575,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id) + inputDevice->setTextInput(nullptr); + mWaylandIntegration->reconfigureInputContext(); + } ++#if QT_CONFIG(wayland_client_primary_selection) ++ if (global.interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) { ++ mPrimarySelectionManager.reset(); ++ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices)) ++ inputDevice->setPrimarySelectionDevice(nullptr); ++ } ++#endif + mGlobals.removeAt(i); + break; + } +@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) + void QWaylandDisplay::removeListener(RegistryListener listener, void *data) { - std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){ @@ -888,12 +911,12 @@ index f10c1f79..e8613ed8 100644 }); + mRegistryListeners.erase(iter, mRegistryListeners.end()); } - + uint32_t QWaylandDisplay::currentTimeMillisec() -@@ -467,50 +614,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() +@@ -467,50 +623,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() return 0; } - + -static void -sync_callback(void *data, struct wl_callback *callback, uint32_t serial) -{ @@ -940,12 +963,12 @@ index f10c1f79..e8613ed8 100644 - wl_callback_destroy(callback); + wl_display_roundtrip(mDisplay); } - + bool QWaylandDisplay::supportsWindowDecoration() const -@@ -574,14 +680,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic +@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic if (mLastKeyboardFocus == keyboardFocus) return; - + - if (mWaylandIntegration->mShellIntegration) { - mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus); - } else { @@ -958,10 +981,10 @@ index f10c1f79..e8613ed8 100644 + handleWindowActivated(keyboardFocus); + if (mLastKeyboardFocus) + handleWindowDeactivated(mLastKeyboardFocus); - + mLastKeyboardFocus = keyboardFocus; } -@@ -600,6 +702,19 @@ void QWaylandDisplay::handleWaylandSync() +@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync() QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window(); if (activeWindow != QGuiApplication::focusWindow()) QWindowSystemInterface::handleWindowActivated(activeWindow); @@ -979,12 +1002,12 @@ index f10c1f79..e8613ed8 100644 + } + } } - + const wl_callback_listener QWaylandDisplay::syncCallbackListener = { -@@ -626,6 +741,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const +@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const return mInputDevices.isEmpty() ? 0 : mInputDevices.first(); } - + +bool QWaylandDisplay::isKeyboardAvailable() const +{ + return std::any_of( @@ -993,12 +1016,12 @@ index f10c1f79..e8613ed8 100644 +} + #if QT_CONFIG(cursor) - + QWaylandCursor *QWaylandDisplay::waylandCursor() -@@ -652,4 +774,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p - +@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p + } // namespace QtWaylandClient - + +#include "qwaylanddisplay.moc" + QT_END_NAMESPACE @@ -1011,12 +1034,12 @@ index 3b092bc8..42bc661d 100644 class QWaylandCursor; class QWaylandCursorTheme; +class EventThread; - + typedef void (*RegistryListener)(void *data, struct wl_registry *registry, @@ -120,15 +121,11 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland Q_OBJECT - + public: - struct FrameQueue { - FrameQueue(wl_event_queue *q = nullptr) : queue(q), mutex(new QMutex) {} @@ -1026,7 +1049,7 @@ index 3b092bc8..42bc661d 100644 - QWaylandDisplay(QWaylandIntegration *waylandIntegration); ~QWaylandDisplay(void) override; - + + void initialize(); + #if QT_CONFIG(xkbcommon) @@ -1035,7 +1058,7 @@ index 3b092bc8..42bc661d 100644 @@ -210,11 +207,11 @@ public: void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice); void handleWindowDestroyed(QWaylandWindow *window); - + - wl_event_queue *createEventQueue(); - FrameQueue createFrameQueue(); - void destroyFrameQueue(const FrameQueue &q); @@ -1043,14 +1066,14 @@ index 3b092bc8..42bc661d 100644 + wl_event_queue *frameEventQueue() { return m_frameEventQueue; }; + + bool isKeyboardAvailable() const; - + + void initEventThread(); public slots: void blockingReadEvents(); void flushRequests(); @@ -237,6 +234,9 @@ private: }; - + struct wl_display *mDisplay = nullptr; + QScopedPointer m_eventThread; + wl_event_queue *m_frameEventQueue = nullptr; @@ -1068,9 +1091,9 @@ index 3b092bc8..42bc661d 100644 struct wl_callback *mSyncCallback = nullptr; static const wl_callback_listener syncCallbackListener; - QReadWriteLock m_frameQueueLock; - + bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull(); - + diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp index 6535aa16..7c53f5fa 100644 --- a/src/client/qwaylanddnd.cpp @@ -1086,18 +1109,18 @@ index 6535aa16..7c53f5fa 100644 // Cancelling immediately does not work, since the event loop for QDrag::exec is started @@ -80,6 +80,9 @@ void QWaylandDrag::cancel() QBasicDrag::cancel(); - + m_display->currentInputDevice()->dataDevice()->cancelDrag(); + + if (drag()) + drag()->deleteLater(); } - + void QWaylandDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) @@ -103,33 +106,41 @@ void QWaylandDrag::endDrag() m_display->currentInputDevice()->handleEndDrag(); } - + -void QWaylandDrag::updateTarget(const QString &mimeType) +void QWaylandDrag::setResponse(bool accepted) { @@ -1112,12 +1135,12 @@ index 6535aa16..7c53f5fa 100644 + Qt::DropAction action = defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers()); + setResponse(QPlatformDropQtResponse(accepted, action)); } - + -void QWaylandDrag::setResponse(const QPlatformDragQtResponse &response) +void QWaylandDrag::setResponse(const QPlatformDropQtResponse &response) { setCanDrop(response.isAccepted()); - + if (canDrop()) { - updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers())); + updateCursor(response.acceptedAction()); @@ -1125,7 +1148,7 @@ index 6535aa16..7c53f5fa 100644 updateCursor(Qt::IgnoreAction); } } - + -void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response) +void QWaylandDrag::setDropResponse(const QPlatformDropQtResponse &response) { @@ -1145,7 +1168,7 @@ index 6535aa16..7c53f5fa 100644 +{ + return true; } - + } diff --git a/src/client/qwaylanddnd_p.h b/src/client/qwaylanddnd_p.h index 474fe2ab..46f629ac 100644 @@ -1154,7 +1177,7 @@ index 474fe2ab..46f629ac 100644 @@ -71,9 +71,10 @@ public: QWaylandDrag(QWaylandDisplay *display); ~QWaylandDrag() override; - + - void updateTarget(const QString &mimeType); - void setResponse(const QPlatformDragQtResponse &response); - void finishDrag(const QPlatformDropQtResponse &response); @@ -1162,40 +1185,33 @@ index 474fe2ab..46f629ac 100644 + void setResponse(const QPlatformDropQtResponse &response); + void setDropResponse(const QPlatformDropQtResponse &response); + void finishDrag(); - + protected: void startDrag() override; @@ -82,6 +83,7 @@ protected: void drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override; void endDrag() override; - + + bool ownsDragObject() const override; - + private: QWaylandDisplay *m_display = nullptr; -diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp -index 8b79c08f..84a34674 100644 ---- a/src/client/qwaylandinputcontext.cpp -+++ b/src/client/qwaylandinputcontext.cpp -@@ -387,8 +387,10 @@ void QWaylandTextInput::zwp_text_input_v2_input_method_changed(uint32_t serial, - Qt::KeyboardModifiers QWaylandTextInput::modifiersToQtModifiers(uint32_t modifiers) - { - Qt::KeyboardModifiers ret = Qt::NoModifier; -- for (int i = 0; modifiers >>= 1; ++i) { -- ret |= m_modifiersMap[i]; -+ for (int i = 0; i < m_modifiersMap.size(); ++i) { -+ if (modifiers & (1 << i)) { -+ ret |= m_modifiersMap[i]; -+ } - } - return ret; - } diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp -index 613fe862..4b90de84 100644 +index 613fe862..4bea321e 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp -@@ -685,6 +685,11 @@ public: - +@@ -308,8 +308,7 @@ void QWaylandInputDevice::Pointer::updateCursor() + auto shape = seat()->mCursor.shape; + + if (shape == Qt::BlankCursor) { +- if (mCursor.surface) +- mCursor.surface->hide(); ++ getOrCreateCursorSurface()->hide(); + return; + } + +@@ -685,6 +684,11 @@ public: + void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface) { + invalidateFocus(); @@ -1206,8 +1222,8 @@ index 613fe862..4b90de84 100644 // The event may arrive after destroying the window, indicated by // a null surface. if (!surface) -@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac - +@@ -696,11 +700,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac + if (!QWaylandWindow::mouseGrab()) setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos)); - @@ -1216,9 +1232,9 @@ index 613fe862..4b90de84 100644 - - mParent->mTime = time; } - + class MotionEvent : public QWaylandPointerEvent -@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed() +@@ -1300,14 +1299,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed() void QWaylandInputDevice::Keyboard::handleFocusLost() { mFocus = nullptr; @@ -1233,30 +1249,30 @@ index 613fe862..4b90de84 100644 mParent->mQDisplay->handleKeyboardFocusChanged(mParent); mRepeatTimer.stop(); } -@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel() +@@ -1396,6 +1387,7 @@ void QWaylandInputDevice::Touch::touch_cancel() if (touchExt) touchExt->touchCanceled(); - + + mFocus = nullptr; QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); } - + diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index c53ccb78..54861600 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration() #endif - + reconfigureInputContext(); + + QWaylandWindow::fixedToplevelPositions = + !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS"); } - + QWaylandIntegration::~QWaylandIntegration() @@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const - + void QWaylandIntegration::initialize() { + mDisplay->initEventThread(); @@ -1270,7 +1286,7 @@ index c53ccb78..54861600 100644 QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests())); QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests())); - + - int fd = wl_display_get_fd(mDisplay->wl_display()); - QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data()); - QObject::connect(sn, SIGNAL(activated(QSocketDescriptor)), mDisplay.data(), SLOT(flushRequests())); @@ -1281,7 +1297,7 @@ index c53ccb78..54861600 100644 @@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const return mDisplay.data(); } - + +Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const +{ + if (auto *seat = mDisplay->currentInputDevice()) { @@ -1296,32 +1312,48 @@ index c53ccb78..54861600 100644 @@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext() } #endif - + - qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className(); + qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : ""); } - + QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName) diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h index ff70ae25..73b80658 100644 --- a/src/client/qwaylandintegration_p.h +++ b/src/client/qwaylandintegration_p.h @@ -107,6 +107,8 @@ public: - + QWaylandDisplay *display() const; - + + Qt::KeyboardModifiers queryKeyboardModifiers() const override; + QList possibleKeys(const QKeyEvent *event) const override; - + QStringList themeNames() const override; +diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp +index 832f9678..ea508771 100644 +--- a/src/client/qwaylandprimaryselectionv1.cpp ++++ b/src/client/qwaylandprimaryselectionv1.cpp +@@ -54,11 +54,6 @@ QWaylandPrimarySelectionDeviceManagerV1::QWaylandPrimarySelectionDeviceManagerV1 + : zwp_primary_selection_device_manager_v1(display->wl_registry(), id, qMin(version, uint(1))) + , m_display(display) + { +- // Create devices for all seats. +- // This only works if we get the global before all devices +- const auto seats = m_display->inputDevices(); +- for (auto *seat : seats) +- seat->setPrimarySelectionDevice(createDevice(seat)); + } + + QWaylandPrimarySelectionDeviceV1 *QWaylandPrimarySelectionDeviceManagerV1::createDevice(QWaylandInputDevice *seat) diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp index 6cb337de..5537dafd 100644 --- a/src/client/qwaylandscreen.cpp +++ b/src/client/qwaylandscreen.cpp @@ -60,7 +60,7 @@ QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1(QWaylandDisplay* display, } - + QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id) - : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 2)) + : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 3)) @@ -1357,11 +1389,11 @@ index 6cb337de..5537dafd 100644 + } + return ret; } - + void QWaylandScreen::maybeInitialize() { Q_ASSERT(!mInitialized); - + - if (!mOutputDone) - return; - @@ -1369,10 +1401,10 @@ index 6cb337de..5537dafd 100644 + const uint requiredEvents = this->requiredEvents(); + if ((mProcessedEvents & requiredEvents) != requiredEvents) return; - + mInitialized = true; @@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor) - + void QWaylandScreen::output_done() { - mOutputDone = true; @@ -1386,14 +1418,14 @@ index 6cb337de..5537dafd 100644 @@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done() if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3)) qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor"; - + - mXdgOutputDone = true; + mProcessedEvents |= XdgOutputDoneEvent; if (mInitialized) updateXdgOutputProperties(); else @@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done() - + void QWaylandScreen::zxdg_output_v1_name(const QString &name) { + if (Q_UNLIKELY(mInitialized)) @@ -1402,7 +1434,7 @@ index 6cb337de..5537dafd 100644 mOutputName = name; + mProcessedEvents |= XdgOutputNameEvent; } - + void QWaylandScreen::updateXdgOutputProperties() diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h index df1c94f2..050cfdc0 100644 @@ -1410,7 +1442,7 @@ index df1c94f2..050cfdc0 100644 +++ b/src/client/qwaylandscreen_p.h @@ -116,6 +116,13 @@ public: static QWaylandScreen *fromWlOutput(::wl_output *output); - + private: + enum Event : uint { + XdgOutputDoneEvent = 0x1, @@ -1430,20 +1462,20 @@ index df1c94f2..050cfdc0 100644 - bool mXdgOutputDone = false; + uint mProcessedEvents = 0; bool mInitialized = false; - + #if QT_CONFIG(cursor) diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp -index dc7ff670..98acd42d 100644 +index dc7ff670..41cffdf7 100644 --- a/src/client/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -52,6 +52,7 @@ - + #include - + +#include #include #include - + @@ -61,6 +62,9 @@ # ifndef MFD_CLOEXEC # define MFD_CLOEXEC 0x0001U @@ -1452,21 +1484,23 @@ index dc7ff670..98acd42d 100644 +# define MFD_ALLOW_SEALING 0x0002U +# endif #endif - + QT_BEGIN_NAMESPACE -@@ -75,7 +79,9 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, +@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + int alloc = stride * size.height(); int fd = -1; - - #ifdef SYS_memfd_create + +-#ifdef SYS_memfd_create - fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC); ++#if defined(SYS_memfd_create) && defined(F_SEAL_SEAL) + fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (fd >= 0) + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL); #endif - + QScopedPointer filePointer; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index afdebf55..fb2c59dc 100644 +index cb82857a..fb2c59dc 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr; @@ -1478,17 +1512,17 @@ index afdebf55..fb2c59dc 100644 { { @@ -95,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display) - + QWaylandWindow::~QWaylandWindow() { - mDisplay->destroyFrameQueue(mFrameQueue); - mDisplay->handleWindowDestroyed(this); - delete mWindowDecoration; - + if (mSurface) @@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const - + void QWaylandWindow::reset() { + closeChildPopups(); @@ -1498,7 +1532,7 @@ index afdebf55..fb2c59dc 100644 @@ -255,17 +252,22 @@ void QWaylandWindow::reset() mSurface.reset(); } - + - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = nullptr; @@ -1509,25 +1543,25 @@ index afdebf55..fb2c59dc 100644 + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + } - + - mFrameCallbackElapsedTimer.invalidate(); - mWaitingForFrameCallback = false; + mFrameCallbackElapsedTimer.invalidate(); + mWaitingForFrameCallback = false; + } mFrameCallbackTimedOut = false; - + mMask = QRegion(); mQueuedBuffer = nullptr; + + mDisplay->handleWindowDestroyed(this); } - + QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -351,19 +353,25 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect) } } - + -void QWaylandWindow::setGeometry(const QRect &rect) +void QWaylandWindow::setGeometry(const QRect &r) { @@ -1537,11 +1571,11 @@ index afdebf55..fb2c59dc 100644 + rect.moveTo(screen()->geometry().topLeft()); + } setGeometry_helper(rect); - + if (window()->isVisible() && rect.isValid()) { if (mWindowDecoration) mWindowDecoration->update(); - + - if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) + if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) { + QMutexLocker lock(&mResizeLock); @@ -1556,17 +1590,17 @@ index afdebf55..fb2c59dc 100644 QRect exposeGeometry(QPoint(), geometry().size()); @@ -374,7 +382,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) mShellSurface->setWindowGeometry(windowContentGeometry()); - + if (isOpaque() && mMask.isEmpty()) - setOpaqueArea(rect); + setOpaqueArea(QRect(QPoint(0, 0), rect.size())); } - + void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset) @@ -399,21 +407,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect) mLastExposeGeometry = rect; } - + - -static QVector> activePopups; - @@ -1587,13 +1621,13 @@ index afdebf55..fb2c59dc 100644 QReadLocker lock(&mSurfaceLock); @@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible) lastVisible = visible; - + if (visible) { - if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) - activePopups << this; initWindow(); - mDisplay->flushRequests(); - + setGeometry(windowGeometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since @@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible) @@ -1605,23 +1639,23 @@ index afdebf55..fb2c59dc 100644 } } @@ -556,12 +545,12 @@ void QWaylandWindow::sendRecursiveExposeEvent() - + void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { - Q_ASSERT(!buffer->committed()); QReadLocker locker(&mSurfaceLock); if (mSurface == nullptr) return; - + if (buffer) { + Q_ASSERT(!buffer->committed()); handleUpdate(); buffer->setBusy(); - + @@ -583,7 +572,11 @@ void QWaylandWindow::damage(const QRect &rect) if (mSurface == nullptr) return; - + - mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); + const int s = scale(); + if (mDisplay->compositorVersion() >= 4) @@ -1629,11 +1663,11 @@ index afdebf55..fb2c59dc 100644 + else + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); } - + void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) @@ -619,8 +612,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) return; - + attachOffset(buffer); - for (const QRect &rect: damage) - mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); @@ -1649,7 +1683,7 @@ index afdebf55..fb2c59dc 100644 buffer->setCommitted(); mSurface->commit(); @@ -635,42 +634,53 @@ void QWaylandWindow::commit() - + const wl_callback_listener QWaylandWindow::callbackListener = { [](void *data, wl_callback *callback, uint32_t time) { - Q_UNUSED(callback); @@ -1659,7 +1693,7 @@ index afdebf55..fb2c59dc 100644 + window->handleFrameCallback(callback); } }; - + -void QWaylandWindow::handleFrameCallback() +void QWaylandWindow::handleFrameCallback(wl_callback* callback) { @@ -1675,7 +1709,7 @@ index afdebf55..fb2c59dc 100644 + mWaitingForFrameCallback = false; mFrameCallbackElapsedTimer.invalidate(); - + // The rest can wait until we can run it on the correct thread - if (!mWaitingForUpdateDelivery) { - auto doHandleExpose = [this]() { @@ -1697,7 +1731,7 @@ index afdebf55..fb2c59dc 100644 + if (wasExposed && hasPendingUpdateRequest()) + deliverUpdateRequest(); + }; - + + if (mWaitingForUpdateDelivery.testAndSetAcquire(false, true)) { // Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync() // in the single-threaded case. @@ -1707,7 +1741,7 @@ index afdebf55..fb2c59dc 100644 + + mFrameSyncWait.notify_all(); } - + bool QWaylandWindow::waitForFrameSync(int timeout) { - QMutexLocker locker(mFrameQueue.mutex); @@ -1716,18 +1750,9 @@ index afdebf55..fb2c59dc 100644 + + QDeadlineTimer deadline(timeout); + while (mWaitingForFrameCallback && mFrameSyncWait.wait(&mFrameSyncMutex, deadline)) { } - + if (mWaitingForFrameCallback) { qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; -@@ -821,7 +831,7 @@ bool QWaylandWindow::createDecoration() - decoration = false; - if (mSubSurfaceWindow) - decoration = false; -- if (mShellSurface && !mShellSurface->wantsDecorations()) -+ if (!mShellSurface || !mShellSurface->wantsDecorations()) - decoration = false; - - bool hadDecoration = mWindowDecoration; @@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration() subsurf->set_position(pos.x() + m.left(), pos.y() + m.top()); } @@ -1744,10 +1769,10 @@ index afdebf55..fb2c59dc 100644 + // here to avoid asserts. + QMetaObject::invokeMethod(window(), &QWindow::requestUpdate); } - + return mWindowDecoration; @@ -1023,6 +1044,13 @@ void QWaylandWindow::handleScreensChanged() - + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); mLastReportedScreen = newScreen; + if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup @@ -1757,13 +1782,13 @@ index afdebf55..fb2c59dc 100644 + geometry.moveTo(newScreen->geometry().topLeft()); + setGeometry(geometry); + } - + int scale = newScreen->isPlaceholder() ? 1 : static_cast(newScreen)->scale(); if (scale != mScale) { @@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab) return true; } - + +Qt::WindowStates QWaylandWindow::windowStates() const +{ + return mLastReportedWindowStates; @@ -1779,11 +1804,11 @@ index afdebf55..fb2c59dc 100644 + lastStatesWithoutActive); mLastReportedWindowStates = states; } - + @@ -1139,19 +1175,24 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) if (event->timerId() != mFrameCallbackCheckIntervalTimerId) return; - + - bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout); - if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) { - killTimer(mFrameCallbackCheckIntervalTimerId); @@ -1793,7 +1818,7 @@ index afdebf55..fb2c59dc 100644 - mFrameCallbackElapsedTimer.invalidate(); + { + QMutexLocker lock(&mFrameSyncMutex); - + - qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; - mFrameCallbackTimedOut = true; - mWaitingForUpdate = false; @@ -1814,11 +1839,11 @@ index afdebf55..fb2c59dc 100644 + mWaitingForUpdate = false; + sendExposeEvent(QRect()); } - + void QWaylandWindow::requestUpdate() @@ -1160,8 +1201,11 @@ void QWaylandWindow::requestUpdate() Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA - + // If we have a frame callback all is good and will be taken care of there - if (mWaitingForFrameCallback) - return; @@ -1827,7 +1852,7 @@ index afdebf55..fb2c59dc 100644 + if (mWaitingForFrameCallback) + return; + } - + // If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet // This is a somewhat redundant behavior and might indicate a bug in the calling code, so log @@ -1174,7 +1218,12 @@ void QWaylandWindow::requestUpdate() @@ -1853,7 +1878,7 @@ index afdebf55..fb2c59dc 100644 QReadLocker lock(&mSurfaceLock); if (!mSurface) return; - + - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = nullptr; @@ -1861,7 +1886,7 @@ index afdebf55..fb2c59dc 100644 + QMutexLocker locker(&mFrameSyncMutex); + if (mWaitingForFrameCallback) + return; - + - QMutexLocker locker(mFrameQueue.mutex); struct ::wl_surface *wrappedSurface = reinterpret_cast(wl_proxy_create_wrapper(mSurface->object())); - wl_proxy_set_queue(reinterpret_cast(wrappedSurface), mFrameQueue.queue); @@ -1881,7 +1906,7 @@ index afdebf55..fb2c59dc 100644 @@ -1267,6 +1317,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) wl_region_destroy(region); } - + +void QWaylandWindow::addChildPopup(QWaylandWindow *surface) { + mChildPopups.append(surface); +} @@ -1897,7 +1922,7 @@ index afdebf55..fb2c59dc 100644 + } +} } - + QT_END_NAMESPACE diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 01337cff..2f219d8c 100644 @@ -1906,7 +1931,7 @@ index 01337cff..2f219d8c 100644 @@ -98,6 +98,9 @@ public: QWaylandWindow(QWindow *window, QWaylandDisplay *display); ~QWaylandWindow() override; - + + // Keep Toplevels position on the top left corner of their screen + static inline bool fixedToplevelPositions = true; + @@ -1918,22 +1943,22 @@ index 01337cff..2f219d8c 100644 void setWindowFlags(Qt::WindowFlags flags) override; void handleWindowStatesChanged(Qt::WindowStates states); + Qt::WindowStates windowStates() const; - + void raise() override; void lower() override; @@ -206,6 +210,10 @@ public: void handleUpdate(); void deliverUpdateRequest() override; - + + void addChildPopup(QWaylandWindow* child); + void removeChildPopup(QWaylandWindow* child); + void closeChildPopups(); + public slots: void applyConfigure(); - + @@ -215,7 +223,11 @@ signals: - + protected: QWaylandDisplay *mDisplay = nullptr; + @@ -1946,7 +1971,7 @@ index 01337cff..2f219d8c 100644 QVector mChildren; @@ -225,13 +237,14 @@ protected: Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton; - + WId mWindowId; - bool mWaitingForFrameCallback = false; bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out @@ -1962,12 +1987,12 @@ index 01337cff..2f219d8c 100644 + struct ::wl_callback *mFrameCallback = nullptr; // Protected by mFrameSyncMutex + QMutex mFrameSyncMutex; QWaitCondition mFrameSyncWait; - + // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer @@ -261,6 +274,8 @@ protected: QWaylandBuffer *mQueuedBuffer = nullptr; QRegion mQueuedBufferDamage; - + + QList> mChildPopups; + private: @@ -1975,18 +2000,18 @@ index 01337cff..2f219d8c 100644 void initWindow(); @@ -283,12 +298,10 @@ private: QRect mLastExposeGeometry; - + static const wl_callback_listener callbackListener; - void handleFrameCallback(); + void handleFrameCallback(struct ::wl_callback* callback); - + static QWaylandWindow *mMouseGrab; - + - mutable QReadWriteLock mSurfaceLock; - friend class QWaylandSubSurface; }; - + diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h index ccad0048..4cc9b3b8 100644 --- a/src/client/shellintegration/qwaylandshellintegration_p.h @@ -2012,7 +2037,7 @@ index bcfd5215..da95d07b 100644 +++ b/src/compositor/configure.json @@ -7,6 +7,31 @@ "testDir": "../../config.tests", - + "libraries": { + "wayland-client": { + "label": "Wayland client library", @@ -2071,18 +2096,18 @@ index bcfd5215..da95d07b 100644 + "use": "wayland-client" } }, - + diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index 7889f575..64140672 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -40,6 +40,7 @@ #include "qwaylandeglwindow.h" - + #include +#include #include "qwaylandglcontext.h" - + #include @@ -124,6 +125,7 @@ void QWaylandEglWindow::updateSurface(bool create) } @@ -2101,7 +2126,7 @@ index 7889f575..64140672 100644 wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y()); + m_requestedSize = sizeWithMargins; mOffset = QPoint(); - + m_resize = true; } - } else if (create && wlSurface()) { @@ -2110,7 +2135,7 @@ index 7889f575..64140672 100644 + m_waylandEglWindow = wl_egl_window_create(mSurface->object(), sizeWithMargins.width(), sizeWithMargins.height()); + m_requestedSize = sizeWithMargins; } - + if (!m_eglSurface && m_waylandEglWindow && create) { diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index 5b1f4d56..0079dfef 100644 @@ -2118,11 +2143,11 @@ index 5b1f4d56..0079dfef 100644 +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -88,6 +88,7 @@ private: mutable QOpenGLFramebufferObject *m_contentFBO = nullptr; - + QSurfaceFormat m_format; + QSize m_requestedSize; }; - + } diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h index 56a710c3..c6a8b6c6 100644 @@ -2131,12 +2156,12 @@ index 56a710c3..c6a8b6c6 100644 @@ -41,6 +41,8 @@ #include #include - + +#include + #include #include - + diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp index e75fda3c..fa885143 100644 --- a/src/plugins/decorations/bradient/main.cpp @@ -2156,16 +2181,16 @@ index e75fda3c..fa885143 100644 + margins().left() + BUTTON_SPACING, 4), + icon.paint(&p, iconRect.toRect()); } - + // Window title diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp index 85d25e3c..60bdd491 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp @@ -47,18 +47,21 @@ QT_BEGIN_NAMESPACE - + namespace QtWaylandClient { - + -QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window) +QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window) : QWaylandShellSurface(window) @@ -2177,14 +2202,14 @@ index 85d25e3c..60bdd491 100644 m_extendedWindow = new QWaylandExtendedSurface(window); + m_parent->addChildPopup(m_window); } - + QWaylandXdgPopupV5::~QWaylandXdgPopupV5() { xdg_popup_destroy(object()); + m_parent->removeChildPopup(m_window); delete m_extendedWindow; } - + diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h index 7494f6a6..d85f130b 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h @@ -2196,16 +2221,16 @@ index 7494f6a6..d85f130b 100644 - QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window); + QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window); ~QWaylandXdgPopupV5() override; - + protected: @@ -78,6 +78,7 @@ protected: - + private: QWaylandExtendedSurface *m_extendedWindow = nullptr; + QWaylandWindow *m_parent = nullptr; QWaylandWindow *m_window = nullptr; }; - + diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp index 7e242c4a..def8452a 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp @@ -2213,7 +2238,7 @@ index 7e242c4a..def8452a 100644 @@ -84,7 +84,7 @@ QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, Q int x = position.x() + parentWindow->frameMargins().left(); int y = position.y() + parentWindow->frameMargins().top(); - + - auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window); + auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), parentWindow, window); m_popups.append(window); @@ -2226,7 +2251,7 @@ index 4e25949f..cfc60939 100644 @@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland return m_xdgShell->createXdgSurface(window); } - + -void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) { - if (newFocus && qobject_cast(newFocus->shellSurface())) - m_display->handleWindowActivated(newFocus); @@ -2235,7 +2260,7 @@ index 4e25949f..cfc60939 100644 -} - } - + QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h index ce6bdb9e..aed88670 100644 @@ -2246,7 +2271,7 @@ index ce6bdb9e..aed88670 100644 bool initialize(QWaylandDisplay *display) override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; - void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override; - + private: QScopedPointer m_xdgShell; diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp @@ -2259,12 +2284,12 @@ index 8c371661..151c78e3 100644 { + m_parent->window()->addChildPopup(m_xdgSurface->window()); } - + QWaylandXdgSurfaceV6::Popup::~Popup() @@ -181,6 +182,8 @@ QWaylandXdgSurfaceV6::Popup::~Popup() if (isInitialized()) destroy(); - + + m_parent->window()->removeChildPopup(m_xdgSurface->window()); + if (m_grabbing) { @@ -2277,7 +2302,7 @@ index 03164316..e8da8ba1 100644 @@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland return m_xdgShell->getXdgSurface(window); } - + -void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) -{ - if (newFocus) { @@ -2293,7 +2318,7 @@ index 03164316..e8da8ba1 100644 -} - } - + QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h index 261f8cbb..c1bcd5c6 100644 @@ -2304,15 +2329,15 @@ index 261f8cbb..c1bcd5c6 100644 bool initialize(QWaylandDisplay *display) override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; - void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override; - + private: QScopedPointer m_xdgShell; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -index 3a1569f7..79177540 100644 +index f3e3c330..67342b0c 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface) - + QWaylandXdgSurface::Toplevel::~Toplevel() { - if (m_applied.states & Qt::WindowActive) { @@ -2326,29 +2351,29 @@ index 3a1569f7..79177540 100644 @@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size(); - + - if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive)) + if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive) + && !m_xdgSurface->m_window->display()->isKeyboardAvailable()) m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window); - + - if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive)) + if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive) + && !m_xdgSurface->m_window->display()->isKeyboardAvailable()) m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window); - + - // TODO: none of the other plugins send WindowActive either, but is it on purpose? - Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive; - - m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive); + m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states); - + if (m_pending.size.isEmpty()) { // An empty size in the configure means it's up to the client to choose the size @@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure() m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size); } - + - m_xdgSurface->setSizeHints(); - m_applied = m_pending; @@ -2357,7 +2382,7 @@ index 3a1569f7..79177540 100644 @@ -203,12 +195,17 @@ QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResi | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); } - + -QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, +QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner) @@ -2373,12 +2398,12 @@ index 3a1569f7..79177540 100644 + m_parent->addChildPopup(m_xdgSurface->window()); + } } - + QWaylandXdgSurface::Popup::~Popup() @@ -216,10 +213,24 @@ QWaylandXdgSurface::Popup::~Popup() if (isInitialized()) destroy(); - + + if (m_parent) { + m_parent->removeChildPopup(m_xdgSurface->window()); + } @@ -2400,25 +2425,38 @@ index 3a1569f7..79177540 100644 + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } } - + @@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s m_toplevel->set_parent(parentXdgSurface->m_toplevel->object()); } } + setSizeHints(); } - + QWaylandXdgSurface::~QWaylandXdgSurface() -@@ -399,8 +411,6 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) +@@ -372,10 +384,10 @@ void QWaylandXdgSurface::setSizeHints() + const int minHeight = qMax(0, m_window->windowMinimumSize().height()); + m_toplevel->set_min_size(minWidth, minHeight); + +- int maxWidth = qMax(0, m_window->windowMaximumSize().width()); ++ int maxWidth = qMax(minWidth, m_window->windowMaximumSize().width()); + if (maxWidth == QWINDOWSIZE_MAX) + maxWidth = 0; +- int maxHeight = qMax(0, m_window->windowMaximumSize().height()); ++ int maxHeight = qMax(minHeight, m_window->windowMaximumSize().height()); + if (maxHeight == QWINDOWSIZE_MAX) + maxHeight = 0; + m_toplevel->set_max_size(maxWidth, maxHeight); +@@ -400,8 +412,6 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) { Q_ASSERT(!m_toplevel && !m_popup); - + - auto parentXdgSurface = static_cast(parent->shellSurface()); - auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner()); // set_popup expects a position relative to the parent QPoint transientPos = m_window->geometry().topLeft(); // this is absolute -@@ -413,8 +423,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) +@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left); positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right); positioner->set_size(m_window->geometry().width(), m_window->geometry().height()); @@ -2428,8 +2466,8 @@ index 3a1569f7..79177540 100644 + delete positioner; } - -@@ -436,6 +447,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic + +@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic } setPopup(parent); m_popup->grab(device, serial); @@ -2451,30 +2489,30 @@ index 3a1569f7..79177540 100644 + if (enter) + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } - + void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial) diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h -index 0c98be35..28ff76ba 100644 +index 96785205..4b518f0a 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -131,14 +131,15 @@ private: - + class Popup : public QtWayland::xdg_popup { public: - Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner); + Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); ~Popup() override; - + void grab(QWaylandInputDevice *seat, uint serial); void xdg_popup_popup_done() override; - + QWaylandXdgSurface *m_xdgSurface = nullptr; - QWaylandXdgSurface *m_parent = nullptr; + QWaylandXdgSurface *m_parentXdgSurface = nullptr; + QWaylandWindow *m_parent = nullptr; bool m_grabbing = false; }; - + diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp index 8769d971..da0dd6a7 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp @@ -2482,7 +2520,7 @@ index 8769d971..da0dd6a7 100644 @@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi return m_xdgShell->getXdgSurface(window); } - + -void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) -{ - if (newFocus) { @@ -2498,7 +2536,7 @@ index 8769d971..da0dd6a7 100644 -} - } - + QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h index b6caa6c9..2f929f98 100644 @@ -2509,7 +2547,7 @@ index b6caa6c9..2f929f98 100644 bool initialize(QWaylandDisplay *display) override; QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; - void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override; - + private: QScopedPointer m_xdgShell; diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp @@ -2517,19 +2555,19 @@ index 526d0ef4..f50ccf30 100644 --- a/src/shared/qwaylandinputmethodeventbuilder.cpp +++ b/src/shared/qwaylandinputmethodeventbuilder.cpp @@ -39,7 +39,10 @@ - + #include "qwaylandinputmethodeventbuilder_p.h" - + +#include +#include #include +#include #include - + #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB @@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t QTextCharFormat format; - + switch (style) { - case 0: - case 1: @@ -2578,14 +2616,14 @@ index 526d0ef4..f50ccf30 100644 break; } @@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t - + if (m_preeditCursor < 0) { attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); - } else if (m_preeditCursor > 0) { + } else { attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant())); } - + diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp index a5fdd34d..e2fe1928 100644 --- a/src/shared/qwaylandmimehelper.cpp @@ -2613,12 +2651,12 @@ index 1568b3b9..067410d0 100644 --- a/tests/auto/client/datadevicev1/tst_datadevicev1.cpp +++ b/tests/auto/client/datadevicev1/tst_datadevicev1.cpp @@ -35,7 +35,7 @@ - + using namespace MockCompositor; - + -constexpr int dataDeviceVersion = 1; +constexpr int dataDeviceVersion = 3; - + class DataDeviceCompositor : public DefaultCompositor { public: diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp @@ -2631,12 +2669,12 @@ index 9312c2e5..2ea382f1 100644 void tapAndMoveInSameFrame(); + void cancelTouch(); }; - + void tst_seatv5::bindsToSeat() @@ -646,5 +647,34 @@ void tst_seatv5::tapAndMoveInSameFrame() QTRY_COMPARE(window.m_events.last().touchPoints.first().state(), Qt::TouchPointState::TouchPointReleased); } - + +void tst_seatv5::cancelTouch() +{ + TouchWindow window; @@ -2674,12 +2712,12 @@ index 5c6c83ba..fa9b7662 100644 +++ b/tests/auto/client/shared/corecompositor.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ - + #include "corecompositor.h" +#include - + namespace MockCompositor { - + diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp index 0d988521..d1a2e7cb 100644 --- a/tests/auto/client/shared/coreprotocol.cpp @@ -2687,7 +2725,7 @@ index 0d988521..d1a2e7cb 100644 @@ -451,6 +451,13 @@ void Touch::sendFrame(wl_client *client) send_frame(r->handle); } - + +void Touch::sendCancel(wl_client *client) +{ + const auto touchResources = resourceMap().values(client); @@ -2716,7 +2754,7 @@ index a1af137a..210d8ddb 100644 void sendMotion(wl_client *client, const QPointF &position, int id); void sendFrame(wl_client *client); + void sendCancel(wl_client *client); - + Seat *m_seat = nullptr; }; diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp @@ -2726,12 +2764,12 @@ index a415cbf5..b1d3d07d 100644 @@ -342,7 +342,7 @@ Compositor::Compositor(MockCompositor *mockCompositor) exit(EXIT_FAILURE); } - + - wl_global_create(m_display, &wl_compositor_interface, 1, this, bindCompositor); + wl_global_create(m_display, &wl_compositor_interface, 4, this, bindCompositor); - + m_data_device_manager.reset(new DataDeviceManager(this, m_display)); - + diff --git a/tests/auto/client/shared_old/mocksurface.cpp b/tests/auto/client/shared_old/mocksurface.cpp index e9df5f90..c3246e4a 100644 --- a/tests/auto/client/shared_old/mocksurface.cpp @@ -2739,7 +2777,7 @@ index e9df5f90..c3246e4a 100644 @@ -125,6 +125,16 @@ void Surface::surface_damage(Resource *resource, Q_UNUSED(height); } - + +void Surface::surface_damage_buffer(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) +{ @@ -2790,9 +2828,9 @@ index 2277bbb8..747875b4 100644 #include #include +#include - + using namespace MockCompositor; - + @@ -45,6 +46,7 @@ private slots: void configureStates(); void popup(); @@ -2802,7 +2840,7 @@ index 2277bbb8..747875b4 100644 void hidePopupParent(); void pongs(); @@ -138,6 +140,7 @@ void tst_xdgshell::configureSize() - + void tst_xdgshell::configureStates() { + QVERIFY(qputenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", "0")); @@ -2812,7 +2850,7 @@ index 2277bbb8..747875b4 100644 @@ -154,9 +157,12 @@ void tst_xdgshell::configureStates() // Toplevel windows don't know their position on xdg-shell // QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled - + -// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue); -// QVERIFY(window.isActive()); - QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly @@ -2822,7 +2860,7 @@ index 2277bbb8..747875b4 100644 + Q_ASSERT(waylandWindow); + QTRY_VERIFY(waylandWindow->windowStates().testFlag( + Qt::WindowActive)); // Just make sure it eventually get's set correctly - + const QSize screenSize(640, 480); const uint maximizedSerial = exec([=] { @@ -186,6 +192,7 @@ void tst_xdgshell::configureStates() @@ -2831,12 +2869,12 @@ index 2277bbb8..747875b4 100644 // QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled + QVERIFY(qunsetenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT")); } - + void tst_xdgshell::popup() @@ -340,6 +347,92 @@ void tst_xdgshell::tooltipOnPopup() QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr); } - + +void tst_xdgshell::tooltipAndSiblingPopup() +{ + class ToolTip : public QRasterWindow { @@ -2929,9 +2967,9 @@ index 2277bbb8..747875b4 100644 @@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); - + - exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + // we don't roundtrip with our configuration the initial commit should be correct - + QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100)); QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000)); diff --git a/desktop/toolkit/qt5/qt5-wayland/pspec.xml b/desktop/toolkit/qt5/qt5-wayland/pspec.xml index 08a6c6d548..db6b483926 100755 --- a/desktop/toolkit/qt5/qt5-wayland/pspec.xml +++ b/desktop/toolkit/qt5/qt5-wayland/pspec.xml @@ -85,6 +85,13 @@ + + 2023-02-15 + 5.15.7 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-21 5.15.7