From 082a47abc276aef098d135327e79502d6b30a7b9 Mon Sep 17 00:00:00 2001 From: Rmys Date: Fri, 8 Sep 2023 15:49:58 +0300 Subject: [PATCH] qt5-declarative, qt5-wayland rebuild --- .../qt5/qt5-declarative/files/qt_kde.patch | 459 +++++++++++++++--- desktop/toolkit/qt5/qt5-declarative/pspec.xml | 7 + .../qt5/qt5-wayland/files/qt_kde.patch | 284 +++++++++-- desktop/toolkit/qt5/qt5-wayland/pspec.xml | 7 + 4 files changed, 625 insertions(+), 132 deletions(-) diff --git a/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch b/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch index df7db63b7a..14c30e28c9 100644 --- a/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch +++ b/desktop/toolkit/qt5/qt5-declarative/files/qt_kde.patch @@ -55,10 +55,10 @@ index 45150cfffd..5ad53faf95 100644 + + // LOAD_ACC(); <- not needed here since it would be unreachable. } - + void BaselineJIT::generate_GetException() { as->getException(); } @@ -547,9 +549,11 @@ void BaselineJIT::generate_SetException() { as->setException(); } - + void BaselineJIT::generate_CreateCallContext() { + STORE_ACC(); @@ -67,7 +67,7 @@ index 45150cfffd..5ad53faf95 100644 BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore); + LOAD_ACC(); } - + void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); } diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index aeb4835c40..9082628a1a 100644 @@ -94,7 +94,7 @@ index 39f4f88512..c963e1878e 100644 - return rv; + return new (rv) T; } - + template @@ -139,8 +138,7 @@ template T *QRecyclePool::New(const T1 &a) @@ -104,7 +104,7 @@ index 39f4f88512..c963e1878e 100644 - return rv; + return new (rv) T(a); } - + template @@ -148,8 +146,7 @@ template T *QRecyclePool::New(T1 &a) @@ -114,8 +114,307 @@ index 39f4f88512..c963e1878e 100644 - return rv; + return new (rv) T(a); } - + template +diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h +index ee31cb38d9..187339169b 100644 +--- a/src/qml/qml/qqmldata_p.h ++++ b/src/qml/qml/qqmldata_p.h +@@ -176,24 +176,24 @@ public: + }; + + struct NotifyList { +- quint64 connectionMask; +- +- quint16 maximumTodoIndex; +- quint16 notifiesSize; +- +- QQmlNotifierEndpoint *todo; +- QQmlNotifierEndpoint**notifies; ++ QAtomicInteger connectionMask; ++ QQmlNotifierEndpoint *todo = nullptr; ++ QQmlNotifierEndpoint**notifies = nullptr; ++ quint16 maximumTodoIndex = 0; ++ quint16 notifiesSize = 0; + void layout(); + private: + void layout(QQmlNotifierEndpoint*); + }; +- NotifyList *notifyList; ++ QAtomicPointer notifyList; + +- inline QQmlNotifierEndpoint *notify(int index); ++ inline QQmlNotifierEndpoint *notify(int index) const; + void addNotify(int index, QQmlNotifierEndpoint *); + int endpointCount(int index); + bool signalHasEndpoint(int index) const; +- void disconnectNotifiers(); ++ ++ enum class DeleteNotifyList { Yes, No }; ++ void disconnectNotifiers(DeleteNotifyList doDelete); + + // The context that created the C++ object + QQmlContextData *context = nullptr; +@@ -201,12 +201,12 @@ public: + QQmlContextData *outerContext = nullptr; + QQmlContextDataRef ownContext; + +- QQmlAbstractBinding *bindings; +- QQmlBoundSignal *signalHandlers; ++ QQmlAbstractBinding *bindings = nullptr; ++ QQmlBoundSignal *signalHandlers = nullptr; + + // Linked list for QQmlContext::contextObjects +- QQmlData *nextContextObject; +- QQmlData**prevContextObject; ++ QQmlData *nextContextObject = nullptr; ++ QQmlData**prevContextObject = nullptr; + + inline bool hasBindingBit(int) const; + inline void setBindingBit(QObject *obj, int); +@@ -216,10 +216,10 @@ public: + inline void setPendingBindingBit(QObject *obj, int); + inline void clearPendingBindingBit(int); + +- quint16 lineNumber; +- quint16 columnNumber; ++ quint16 lineNumber = 0; ++ quint16 columnNumber = 0; + +- quint32 jsEngineId; // id of the engine that created the jsWrapper ++ quint32 jsEngineId = 0; // id of the engine that created the jsWrapper + + struct DeferredData { + DeferredData(); +@@ -240,7 +240,7 @@ public: + + QQmlPropertyCache *propertyCache; + +- QQmlGuardImpl *guards; ++ QQmlGuardImpl *guards = nullptr; + + static QQmlData *get(const QObject *object, bool create = false) { + QObjectPrivate *priv = QObjectPrivate::get(const_cast(object)); +@@ -289,7 +289,7 @@ public: + + private: + // For attachedProperties +- mutable QQmlDataExtended *extendedData; ++ mutable QQmlDataExtended *extendedData = nullptr; + + Q_NEVER_INLINE static QQmlData *createQQmlData(QObjectPrivate *priv); + Q_NEVER_INLINE static QQmlPropertyCache *createPropertyCache(QJSEngine *engine, QObject *object); +@@ -342,23 +342,31 @@ bool QQmlData::wasDeleted(const QObject *object) + return ddata && ddata->isQueuedForDeletion; + } + +-QQmlNotifierEndpoint *QQmlData::notify(int index) ++inline bool isIndexInConnectionMask(quint64 connectionMask, int index) ++{ ++ return connectionMask & (1ULL << quint64(index % 64)); ++} ++ ++QQmlNotifierEndpoint *QQmlData::notify(int index) const + { ++ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. ++ + Q_ASSERT(index <= 0xFFFF); + +- if (!notifyList || !(notifyList->connectionMask & (1ULL << quint64(index % 64)))) { ++ NotifyList *list = notifyList.loadRelaxed(); ++ if (!list || !isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index)) + return nullptr; +- } else if (index < notifyList->notifiesSize) { +- return notifyList->notifies[index]; +- } else if (index <= notifyList->maximumTodoIndex) { +- notifyList->layout(); +- } + +- if (index < notifyList->notifiesSize) { +- return notifyList->notifies[index]; +- } else { +- return nullptr; ++ if (index < list->notifiesSize) ++ return list->notifies[index]; ++ ++ if (index <= list->maximumTodoIndex) { ++ list->layout(); ++ if (index < list->notifiesSize) ++ return list->notifies[index]; + } ++ ++ return nullptr; + } + + /* +@@ -367,7 +375,19 @@ QQmlNotifierEndpoint *QQmlData::notify(int index) + */ + inline bool QQmlData::signalHasEndpoint(int index) const + { +- return notifyList && (notifyList->connectionMask & (1ULL << quint64(index % 64))); ++ // This can be called from any thread. ++ // We still use relaxed semantics. If we're on a thread different from the "home" thread ++ // of the QQmlData, two interesting things might happen: ++ // ++ // 1. The list might go away while we hold it. In that case we are dealing with an object whose ++ // QObject dtor is being executed concurrently. This is UB already without the notify lists. ++ // Therefore, we don't need to consider it. ++ // 2. The connectionMask may be amended or zeroed while we are looking at it. In that case ++ // we "misreport" the endpoint. Since ordering of events across threads is inherently ++ // nondeterministic, either result is correct in that case. We can accept it. ++ ++ NotifyList *list = notifyList.loadRelaxed(); ++ return list && isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index); + } + + bool QQmlData::hasBindingBit(int coreIndex) const +diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp +index 826a1a5ab4..fce8fe987f 100644 +--- a/src/qml/qml/qqmlengine.cpp ++++ b/src/qml/qml/qqmlengine.cpp +@@ -718,18 +718,15 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) + // Disconnect the notifiers now - during object destruction this would be too late, since + // the disconnect call wouldn't be able to call disconnectNotify(), as it isn't possible to + // get the metaobject anymore. +- d->disconnectNotifiers(); ++ d->disconnectNotifiers(QQmlData::DeleteNotifyList::No); + } + } + + QQmlData::QQmlData() + : ownedByQml1(false), ownMemory(true), indestructible(true), explicitIndestructibleSet(false), + hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), +- hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), +- bindingBitsArraySize(InlineBindingArraySize), notifyList(nullptr), +- bindings(nullptr), signalHandlers(nullptr), nextContextObject(nullptr), prevContextObject(nullptr), +- lineNumber(0), columnNumber(0), jsEngineId(0), +- propertyCache(nullptr), guards(nullptr), extendedData(nullptr) ++ hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), dummy(0), ++ bindingBitsArraySize(InlineBindingArraySize), propertyCache(nullptr) + { + memset(bindingBitsValue, 0, sizeof(bindingBitsValue)); + init(); +@@ -789,7 +786,10 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in + // QQmlEngine to emit signals from a different thread. These signals are then automatically + // marshalled back onto the QObject's thread and handled by QML from there. This is tested + // by the qqmlecmascript::threadSignal() autotest. +- if (!ddata->notifyList) ++ ++ // Relaxed semantics here. If we're on a different thread we might schedule a useless event, ++ // but that should be rare. ++ if (!ddata->notifyList.loadRelaxed()) + return; + + auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed(); +@@ -1835,49 +1835,73 @@ void QQmlData::releaseDeferredData() + + void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint) + { +- if (!notifyList) { +- notifyList = (NotifyList *)malloc(sizeof(NotifyList)); +- notifyList->connectionMask = 0; +- notifyList->maximumTodoIndex = 0; +- notifyList->notifiesSize = 0; +- notifyList->todo = nullptr; +- notifyList->notifies = nullptr; ++ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. ++ ++ NotifyList *list = notifyList.loadRelaxed(); ++ ++ if (!list) { ++ list = new NotifyList; ++ // We don't really care when this change takes effect on other threads. The notifyList can ++ // only become non-null once in the life time of a QQmlData. It becomes null again when the ++ // underlying QObject is deleted. At that point any interaction with the QQmlData is UB ++ // anyway. So, for all intents and purposese, the list becomes non-null once and then stays ++ // non-null "forever". We can apply relaxed semantics. ++ notifyList.storeRelaxed(list); + } + + Q_ASSERT(!endpoint->isConnected()); + + index = qMin(index, 0xFFFF - 1); +- notifyList->connectionMask |= (1ULL << quint64(index % 64)); + +- if (index < notifyList->notifiesSize) { ++ // Likewise, we don't really care _when_ the change in the connectionMask is propagated to other ++ // threads. Cross-thread event ordering is inherently nondeterministic. Therefore, when querying ++ // the conenctionMask in the presence of concurrent modification, any result is correct. ++ list->connectionMask.storeRelaxed( ++ list->connectionMask.loadRelaxed() | (1ULL << quint64(index % 64))); + +- endpoint->next = notifyList->notifies[index]; ++ if (index < list->notifiesSize) { ++ endpoint->next = list->notifies[index]; + if (endpoint->next) endpoint->next->prev = &endpoint->next; +- endpoint->prev = ¬ifyList->notifies[index]; +- notifyList->notifies[index] = endpoint; +- ++ endpoint->prev = &list->notifies[index]; ++ list->notifies[index] = endpoint; + } else { +- notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index); ++ list->maximumTodoIndex = qMax(int(list->maximumTodoIndex), index); + +- endpoint->next = notifyList->todo; ++ endpoint->next = list->todo; + if (endpoint->next) endpoint->next->prev = &endpoint->next; +- endpoint->prev = ¬ifyList->todo; +- notifyList->todo = endpoint; ++ endpoint->prev = &list->todo; ++ list->todo = endpoint; + } + } + +-void QQmlData::disconnectNotifiers() ++void QQmlData::disconnectNotifiers(QQmlData::DeleteNotifyList doDelete) + { +- if (notifyList) { +- while (notifyList->todo) +- notifyList->todo->disconnect(); +- for (int ii = 0; ii < notifyList->notifiesSize; ++ii) { +- while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii]) ++ // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. ++ if (NotifyList *list = notifyList.loadRelaxed()) { ++ while (QQmlNotifierEndpoint *todo = list->todo) ++ todo->disconnect(); ++ for (int ii = 0; ii < list->notifiesSize; ++ii) { ++ while (QQmlNotifierEndpoint *ep = list->notifies[ii]) + ep->disconnect(); + } +- free(notifyList->notifies); +- free(notifyList); +- notifyList = nullptr; ++ free(list->notifies); ++ ++ if (doDelete == DeleteNotifyList::Yes) { ++ // We can only get here from QQmlData::destroyed(), and that can only come from the ++ // the QObject dtor. If you're still sending signals at that point you have UB already ++ // without any threads. Therefore, it's enough to apply relaxed semantics. ++ notifyList.storeRelaxed(nullptr); ++ delete list; ++ } else { ++ // We can use relaxed semantics here. The worst thing that can happen is that some ++ // signal is falsely reported as connected. Signal connectedness across threads ++ // is not quite deterministic anyway. ++ list->connectionMask.storeRelaxed(0); ++ list->maximumTodoIndex = 0; ++ list->notifiesSize = 0; ++ list->notifies = nullptr; ++ ++ } + } + } + +@@ -1961,7 +1985,7 @@ void QQmlData::destroyed(QObject *object) + guard->objectDestroyed(object); + } + +- disconnectNotifiers(); ++ disconnectNotifiers(DeleteNotifyList::Yes); + + if (extendedData) + delete extendedData; diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 10c6c41338..39bfcdc999 100644 --- a/src/qml/qml/qqmlimport.cpp @@ -123,7 +422,7 @@ index 10c6c41338..39bfcdc999 100644 @@ -2120,9 +2120,12 @@ void QQmlImportDatabase::addImportPath(const QString& path) cPath.replace(Backslash, Slash); } - + - if (!cPath.isEmpty() - && !fileImportPath.contains(cPath)) - fileImportPath.prepend(cPath); @@ -134,7 +433,7 @@ index 10c6c41338..39bfcdc999 100644 + fileImportPath.prepend(cPath); + } } - + /*! diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 175de8b936..a6ba4b8cb3 100644 @@ -142,7 +441,7 @@ index 175de8b936..a6ba4b8cb3 100644 +++ 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); @@ -160,12 +459,12 @@ index aa9f4bc1bd..09503a7e99 100644 @@ -254,7 +254,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() if (!pd) return; - + - if (pd->notifyIndex() != -1) + if (pd->notifyIndex() != -1 && ctxt->engine) connect(target, pd->notifyIndex(), ctxt->engine); } - + diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 29ed62cd39..aba930dfe1 100644 --- a/src/qml/types/qqmlconnections.cpp @@ -212,7 +511,7 @@ index 4fcff70de6..5b7e767ae2 100644 @@ -1871,10 +1883,15 @@ void QQmlDelegateModelPrivate::emitChanges() for (int i = 1; i < m_groupCount; ++i) QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset); - + - auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache - for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) { - if (cacheItem->attached) @@ -228,11 +527,11 @@ index 4fcff70de6..5b7e767ae2 100644 + attached->emitChanges(); } } - + @@ -1974,6 +1991,38 @@ void QQmlDelegateModel::_q_rowsMoved( } } - + +void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end) +{ + Q_D(QQmlDelegateModel); @@ -270,7 +569,7 @@ index 4fcff70de6..5b7e767ae2 100644 Q_D(QQmlDelegateModel); @@ -2663,20 +2712,24 @@ void QQmlDelegateModelAttached::emitChanges() m_previousGroups = m_cacheItem->groups; - + int indexChanges = 0; - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) { + const int groupCount = m_cacheItem->metaType->groupCount; @@ -280,7 +579,7 @@ index 4fcff70de6..5b7e767ae2 100644 indexChanges |= (1 << i); } } - + + // Don't access m_cacheItem anymore once we've started sending signals. + // We don't own it and someone might delete it. + @@ -320,10 +619,10 @@ index ae1954ae8d..99e6eff7c3 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(); @@ -341,7 +640,7 @@ index ae1954ae8d..99e6eff7c3 100644 + + return window; } - + int QAccessibleQuickItem::childCount() const @@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const QAccessibleInterface *QAccessibleQuickItem::parent() const @@ -353,7 +652,7 @@ index ae1954ae8d..99e6eff7c3 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. @@ -370,7 +669,7 @@ index ae1954ae8d..99e6eff7c3 100644 @@ -193,7 +202,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; @@ -386,9 +685,9 @@ index ae1954ae8d..99e6eff7c3 100644 + } return state; } - + @@ -217,7 +230,7 @@ QAccessible::Role QAccessibleQuickItem::role() const - + QAccessible::Role role = QAccessible::NoRole; if (item()) - role = QQuickItemPrivate::get(item())->accessibleRole(); @@ -401,9 +700,9 @@ 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 { @@ -416,18 +715,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) { @@ -436,7 +735,7 @@ 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/qquickitem.cpp b/src/quick/items/qquickitem.cpp @@ -448,7 +747,7 @@ index 33da9762d3..9e8b289376 100644 #include #include +#include - + #include #include @@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent) @@ -456,12 +755,12 @@ index 33da9762d3..9e8b289376 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(). @@ -2398,7 +2400,7 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item) return true; - + #if QT_CONFIG(accessibility) - QAccessible::Role role = QQuickItemPrivate::get(item)->accessibleRole(); + QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole(); @@ -489,7 +788,7 @@ index 33da9762d3..9e8b289376 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) { @@ -500,9 +799,9 @@ index 33da9762d3..9e8b289376 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) @@ -510,16 +809,16 @@ index 33da9762d3..9e8b289376 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) @@ -541,7 +840,7 @@ index 33da9762d3..9e8b289376 100644 + } +#endif } - + QQuickStateGroup *QQuickItemPrivate::_states() @@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) QAccessible::updateAccessibility(&ev); @@ -555,12 +854,12 @@ index 33da9762d3..9e8b289376 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) { @@ -573,10 +872,10 @@ index 33da9762d3..9e8b289376 100644 +#endif emit q->enabledChanged(); } - + @@ -8974,13 +9000,20 @@ QQuickItemPrivate::ExtraData::ExtraData() - - + + #if QT_CONFIG(accessibility) -QAccessible::Role QQuickItemPrivate::accessibleRole() const +QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const @@ -593,7 +892,7 @@ index 33da9762d3..9e8b289376 100644 + role = accessibleRole(); + return role; +} - + +QAccessible::Role QQuickItemPrivate::accessibleRole() const +{ return QAccessible::NoRole; @@ -608,26 +907,26 @@ index 841d91bb40..6f329bd119 100644 bool touchEnabled:1; bool hasCursorHandler:1; + quint32 inDestructor:1; // has entered ~QQuickItem - + enum DirtyType { TransformOrigin = 0x00000001, @@ -574,7 +575,10 @@ public: virtual void implicitHeightChanged(); - + #if QT_CONFIG(accessibility) + QAccessible::Role effectiveAccessibleRole() const; +private: virtual QAccessible::Role accessibleRole() const; +public: #endif - + void setImplicitAntialiasing(bool antialiasing); 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; @@ -1023,17 +1322,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) +{ @@ -1050,7 +1349,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")); @@ -1058,7 +1357,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); @@ -1069,10 +1368,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(); @@ -1085,7 +1384,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(); @@ -1107,7 +1406,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) @@ -1126,7 +1425,7 @@ index 881f7f9220..1a946bcc71 100644 @@ -148,6 +148,14 @@ public: bool forceFullUpdate; }; - + +class QQuickWidgetOffscreenWindow: public QQuickWindow +{ + Q_OBJECT @@ -1136,7 +1435,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 @@ -1150,13 +1449,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/qqmldelegatemodel/data/deleteRace.qml b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml new file mode 100644 @@ -1237,7 +1536,7 @@ index 35f1e2c94d..f473cff75f 100644 +++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp @@ -27,6 +27,8 @@ ****************************************************************************/ - + #include +#include +#include @@ -1251,12 +1550,12 @@ index 35f1e2c94d..f473cff75f 100644 + void redrawUponColumnChange(); + void deleteRace(); }; - + class AbstractItemModel : public QAbstractItemModel @@ -186,6 +190,41 @@ void tst_QQmlDelegateModel::contextAccessedByHandler() QVERIFY(root->property("works").toBool()); } - + +void tst_QQmlDelegateModel::redrawUponColumnChange() +{ + QStandardItemModel m1; @@ -1293,7 +1592,7 @@ index 35f1e2c94d..f473cff75f 100644 +} + QTEST_MAIN(tst_QQmlDelegateModel) - + #include "tst_qqmldelegatemodel.moc" diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 9c865b3f73..1f788f7a7f 100644 @@ -1309,7 +1608,7 @@ index 9c865b3f73..1f788f7a7f 100644 + expectedImportPaths.move(expectedImportPaths.indexOf(qml2Imports), 0); + QCOMPARE(expectedImportPaths, engine.importPathList()); } - + Q_DECLARE_METATYPE(QQmlImports::ImportVersion) diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml new file mode 100644 @@ -1340,16 +1639,16 @@ index bffb62c59e..97cc64991f 100644 +++ 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; @@ -1366,7 +1665,7 @@ index bffb62c59e..97cc64991f 100644 +} + QTEST_MAIN(tst_qqmllanguage) - + #include "tst_qqmllanguage.moc" diff --git a/tests/auto/quick/qquickgridview/data/qtbug86255.qml b/tests/auto/quick/qquickgridview/data/qtbug86255.qml new file mode 100644 @@ -1438,13 +1737,13 @@ index 94ec4f44d5..7d0d9fa7a7 100644 void QTBUG_49218(); void QTBUG_48870_fastModelUpdates(); + void QTBUG_86255(); - + void keyNavigationEnabled(); void resizeDynamicCellWidthRtL(); @@ -6814,6 +6815,18 @@ void tst_QQuickGridView::resizeDynamicCellWidthRtL() QTRY_COMPARE(gridview->contentX(), 0.f); } - + +void tst_QQuickGridView::QTBUG_86255() +{ + QScopedPointer window(createView()); @@ -1488,13 +1787,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() +{ @@ -1548,7 +1847,7 @@ index aa55b42935..26e86672b0 100644 @@ -1734,6 +1735,16 @@ void tst_qquickstates::trivialWhen() QVERIFY(c.create()); } - + +void tst_qquickstates::jsValueWhen() +{ + QQmlEngine engine; @@ -1660,7 +1959,7 @@ index beeec88f07..2cb7653d65 100644 @@ -522,14 +522,7 @@ int main(int argc, char *argv[]) parser.addPositionalArgument("args", QCoreApplication::translate("main", "Arguments after '--' are ignored, but passed through to the application.arguments variable in QML."), "[-- args...]"); - + - if (!parser.parse(QCoreApplication::arguments())) { - qWarning() << parser.errorText(); - exit(1); diff --git a/desktop/toolkit/qt5/qt5-declarative/pspec.xml b/desktop/toolkit/qt5/qt5-declarative/pspec.xml index 24d05c68ae..090faaae8f 100755 --- a/desktop/toolkit/qt5/qt5-declarative/pspec.xml +++ b/desktop/toolkit/qt5/qt5-declarative/pspec.xml @@ -69,6 +69,13 @@ + + 2023-09-08 + 5.15.10 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2023-07-07 5.15.10 diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch b/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch index a8d1787668..4184b02c36 100644 --- a/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch +++ b/desktop/toolkit/qt5/qt5-wayland/files/qt_kde.patch @@ -85,6 +85,19 @@ index 69cc46a0..9091efbe 100644 }; class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate +diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp +index b6ee43c9..be0a31df 100644 +--- a/src/client/qwaylandabstractdecoration.cpp ++++ b/src/client/qwaylandabstractdecoration.cpp +@@ -122,7 +122,7 @@ const QImage &QWaylandAbstractDecoration::contentImage() + if (d->m_isDirty) { + // Update the decoration backingstore + +- const int bufferScale = waylandWindow()->scale(); ++ const qreal bufferScale = waylandWindow()->scale(); + const QSize imageSize = waylandWindow()->surfaceSize() * bufferScale; + d->m_decorationContentImage = QImage(imageSize, QImage::Format_ARGB32_Premultiplied); + // Only scale by buffer scale, not QT_SCALE_FACTOR etc. diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp index 81f48e05..14561c77 100644 --- a/src/client/qwaylandclipboard.cpp @@ -169,8 +182,49 @@ index ce14e124..bb52683d 100644 }; } +diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp +index e4eca9d4..ba76ba2d 100644 +--- a/src/client/qwaylandcursor.cpp ++++ b/src/client/qwaylandcursor.cpp +@@ -44,6 +44,7 @@ + #include "qwaylandshmbackingstore_p.h" + + #include ++#include + #include + + #include +@@ -250,7 +251,27 @@ QWaylandCursor::QWaylandCursor(QWaylandDisplay *display) + QSharedPointer QWaylandCursor::cursorBitmapBuffer(QWaylandDisplay *display, const QCursor *cursor) + { + Q_ASSERT(cursor->shape() == Qt::BitmapCursor); +- const QImage &img = cursor->pixmap().toImage(); ++ ++ const QBitmap mask = cursor->mask(Qt::ReturnByValue); ++ QImage img; ++ if (cursor->pixmap().isNull()) ++ img = cursor->bitmap(Qt::ReturnByValue).toImage(); ++ else ++ img = cursor->pixmap().toImage(); ++ ++ // convert to supported format if necessary ++ if (!display->shm()->formatSupported(img.format())) { ++ if (mask.isNull()) { ++ img.convertTo(QImage::Format_RGB32); ++ } else { ++ // preserve mask ++ img.convertTo(QImage::Format_ARGB32); ++ QPixmap pixmap = QPixmap::fromImage(img); ++ pixmap.setMask(mask); ++ img = pixmap.toImage(); ++ } ++ } ++ + QSharedPointer buffer(new QWaylandShmBuffer(display, img.size(), img.format())); + memcpy(buffer->image()->bits(), img.bits(), size_t(img.sizeInBytes())); + return buffer; diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp -index 7e2e3308..e3e60ed5 100644 +index 7e2e3308..e66ae880 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -72,6 +72,8 @@ QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWayl @@ -191,7 +245,7 @@ index 7e2e3308..e3e60ed5 100644 { auto *seat = m_display->currentInputDevice(); auto *origin = seat->pointerFocus(); -@@ -123,7 +125,28 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) +@@ -123,7 +125,31 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) } m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); @@ -202,6 +256,9 @@ index 7e2e3308..e3e60ed5 100644 connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled); + connect(m_dragSource.data(), &QWaylandDataSource::dndResponseUpdated, this, [this](bool accepted, Qt::DropAction action) { + auto drag = static_cast(QGuiApplicationPrivate::platformIntegration()->drag()); ++ if (!drag->currentDrag()) { ++ return; ++ } + // in old versions drop action is not set, so we guess + if (wl_data_source_get_version(m_dragSource->object()) < 3) { + drag->setResponse(accepted); @@ -220,7 +277,7 @@ index 7e2e3308..e3e60ed5 100644 start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); return true; -@@ -152,7 +175,7 @@ void QWaylandDataDevice::data_device_drop() +@@ -152,7 +178,7 @@ void QWaylandDataDevice::data_device_drop() supportedActions = drag->supportedActions(); } else if (m_dragOffer) { dragData = m_dragOffer->mimeData(); @@ -229,7 +286,7 @@ index 7e2e3308..e3e60ed5 100644 } else { return; } -@@ -162,7 +185,11 @@ void QWaylandDataDevice::data_device_drop() +@@ -162,7 +188,11 @@ void QWaylandDataDevice::data_device_drop() QGuiApplication::keyboardModifiers()); if (drag) { @@ -242,7 +299,7 @@ index 7e2e3308..e3e60ed5 100644 } } -@@ -186,7 +213,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, +@@ -186,7 +216,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, supportedActions = drag->supportedActions(); } else if (m_dragOffer) { dragData = m_dragOffer->mimeData(); @@ -251,7 +308,7 @@ index 7e2e3308..e3e60ed5 100644 } 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, +@@ -197,11 +227,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } @@ -264,7 +321,7 @@ index 7e2e3308..e3e60ed5 100644 } void QWaylandDataDevice::data_device_leave() -@@ -235,10 +258,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe +@@ -235,10 +261,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe supportedActions = drag->supportedActions(); } else { dragData = m_dragOffer->mimeData(); @@ -277,7 +334,7 @@ index 7e2e3308..e3e60ed5 100644 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); -@@ -246,11 +269,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe +@@ -246,11 +272,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe static_cast(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } @@ -290,7 +347,7 @@ index 7e2e3308..e3e60ed5 100644 } #endif // QT_CONFIG(draganddrop) -@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled() +@@ -277,14 +299,10 @@ void QWaylandDataDevice::selectionSourceCancelled() #if QT_CONFIG(draganddrop) void QWaylandDataDevice::dragSourceCancelled() { @@ -306,7 +363,7 @@ index 7e2e3308..e3e60ed5 100644 QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) const { QPoint pnt(wl_fixed_to_int(x), wl_fixed_to_int(y)); -@@ -297,6 +312,33 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con +@@ -297,6 +315,33 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con } return pnt; } @@ -587,7 +644,7 @@ index 25afff79..14d1542d 100644 } diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp -index 78e387bc..27f55965 100644 +index 78e387bc..ff9a0500 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -87,10 +87,203 @@ @@ -818,15 +875,18 @@ index 78e387bc..27f55965 100644 if (mSyncCallback) wl_callback_destroy(mSyncCallback); -@@ -189,6 +381,21 @@ QWaylandDisplay::~QWaylandDisplay(void) +@@ -187,10 +379,26 @@ QWaylandDisplay::~QWaylandDisplay(void) + #if QT_CONFIG(cursor) + qDeleteAll(mCursorThemes); #endif - if (mDisplay) - wl_display_disconnect(mDisplay); + + if (m_frameEventQueue) + wl_event_queue_destroy(m_frameEventQueue); -+} + + if (mDisplay) + wl_display_disconnect(mDisplay); + } + +// Steps which is called just after constructor. This separates registry_global() out of the constructor +// so that factory functions in integration can be overridden. +void QWaylandDisplay::initialize() @@ -837,10 +897,12 @@ index 78e387bc..27f55965 100644 + // Give wl_output.done and zxdg_output_v1.done events a chance to arrive + forceRoundTrip(); + } - } - ++} ++ void QWaylandDisplay::ensureScreen() -@@ -205,98 +412,37 @@ void QWaylandDisplay::ensureScreen() + { + if (!mScreens.empty() || mPlaceholderScreen) +@@ -205,98 +413,37 @@ void QWaylandDisplay::ensureScreen() void QWaylandDisplay::checkError() const { @@ -959,7 +1021,7 @@ index 78e387bc..27f55965 100644 } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const -@@ -347,7 +493,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin +@@ -347,7 +494,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin if (interface == QStringLiteral("wl_output")) { mWaitingScreens << new QWaylandScreen(this, version, id); } else if (interface == QStringLiteral("wl_compositor")) { @@ -968,7 +1030,7 @@ index 78e387bc..27f55965 100644 mCompositor.init(registry, id, mCompositorVersion); } else if (interface == QStringLiteral("wl_shm")) { mShm.reset(new QWaylandShm(this, version, id)); -@@ -356,7 +502,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin +@@ -356,7 +503,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mInputDevices.append(inputDevice); #if QT_CONFIG(wayland_datadevice) } else if (interface == QStringLiteral("wl_data_device_manager")) { @@ -977,7 +1039,7 @@ index 78e387bc..27f55965 100644 #endif } else if (interface == QStringLiteral("qt_surface_extension")) { mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1)); -@@ -373,6 +519,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin +@@ -373,6 +520,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)); @@ -986,7 +1048,7 @@ index 78e387bc..27f55965 100644 #endif } else if (interface == QStringLiteral("zwp_text_input_manager_v2") && !mClientSideInputContextRequested) { mTextInputManager.reset(new QtWayland::zwp_text_input_manager_v2(registry, id, 1)); -@@ -431,6 +579,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id) +@@ -431,6 +580,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id) inputDevice->setTextInput(nullptr); mWaylandIntegration->reconfigureInputContext(); } @@ -1000,7 +1062,7 @@ index 78e387bc..27f55965 100644 mGlobals.removeAt(i); break; } -@@ -456,9 +611,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) +@@ -456,9 +612,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) void QWaylandDisplay::removeListener(RegistryListener listener, void *data) { @@ -1012,7 +1074,7 @@ index 78e387bc..27f55965 100644 } uint32_t QWaylandDisplay::currentTimeMillisec() -@@ -471,50 +627,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() +@@ -471,50 +628,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec() return 0; } @@ -1064,7 +1126,7 @@ index 78e387bc..27f55965 100644 } bool QWaylandDisplay::supportsWindowDecoration() const -@@ -578,14 +693,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic +@@ -578,14 +694,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic if (mLastKeyboardFocus == keyboardFocus) return; @@ -1083,7 +1145,7 @@ index 78e387bc..27f55965 100644 mLastKeyboardFocus = keyboardFocus; } -@@ -604,6 +715,19 @@ void QWaylandDisplay::handleWaylandSync() +@@ -604,6 +716,19 @@ void QWaylandDisplay::handleWaylandSync() QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window(); if (activeWindow != QGuiApplication::focusWindow()) QWindowSystemInterface::handleWindowActivated(activeWindow); @@ -1103,7 +1165,7 @@ index 78e387bc..27f55965 100644 } const wl_callback_listener QWaylandDisplay::syncCallbackListener = { -@@ -630,6 +754,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const +@@ -630,6 +755,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const return mInputDevices.isEmpty() ? 0 : mInputDevices.first(); } @@ -1117,7 +1179,7 @@ index 78e387bc..27f55965 100644 #if QT_CONFIG(cursor) QWaylandCursor *QWaylandDisplay::waylandCursor() -@@ -656,4 +787,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p +@@ -656,4 +788,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p } // namespace QtWaylandClient @@ -1295,6 +1357,28 @@ index 474fe2ab..46f629ac 100644 private: QWaylandDisplay *m_display = nullptr; +diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp +index 84a34674..920a4222 100644 +--- a/src/client/qwaylandinputcontext.cpp ++++ b/src/client/qwaylandinputcontext.cpp +@@ -93,9 +93,14 @@ void QWaylandTextInput::reset() + void QWaylandTextInput::commit() + { + if (QObject *o = QGuiApplication::focusObject()) { +- QInputMethodEvent event; +- event.setCommitString(m_preeditCommit); +- QCoreApplication::sendEvent(o, &event); ++ if (!m_preeditCommit.isEmpty()) { ++ ++ QInputMethodEvent event; ++ event.setCommitString(m_preeditCommit); ++ m_preeditCommit = QString(); ++ ++ QCoreApplication::sendEvent(o, &event); ++ } + } + + reset(); diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index e931d1f5..9a0fe49d 100644 --- a/src/client/qwaylandinputdevice.cpp @@ -1544,7 +1628,7 @@ index df1c94f2..050cfdc0 100644 #if QT_CONFIG(cursor) diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp -index dc7ff670..41cffdf7 100644 +index dc7ff670..90e37e95 100644 --- a/src/client/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -52,6 +52,7 @@ @@ -1565,7 +1649,14 @@ index dc7ff670..41cffdf7 100644 #endif QT_BEGIN_NAMESPACE -@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, +@@ -68,14 +72,16 @@ QT_BEGIN_NAMESPACE + namespace QtWaylandClient { + + QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, +- const QSize &size, QImage::Format format, int scale) ++ const QSize &size, QImage::Format format, qreal scale) + { + int stride = size.width() * 4; int alloc = stride * size.height(); int fd = -1; @@ -1578,8 +1669,39 @@ index dc7ff670..41cffdf7 100644 #endif QScopedPointer filePointer; +@@ -108,7 +114,7 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + QWaylandShm* shm = display->shm(); + wl_shm_format wl_format = shm->formatFrom(format); + mImage = QImage(data, size.width(), size.height(), stride, format); +- mImage.setDevicePixelRatio(qreal(scale)); ++ mImage.setDevicePixelRatio(scale); + + mShmPool = wl_shm_create_pool(shm->object(), fd, alloc); + init(wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(), +@@ -271,7 +277,7 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size) + void QWaylandShmBackingStore::resize(const QSize &size) + { + QMargins margins = windowDecorationMargins(); +- int scale = waylandWindow()->scale(); ++ qreal scale = waylandWindow()->scale(); + QSize sizeWithMargins = (size + QSize(margins.left()+margins.right(),margins.top()+margins.bottom())) * scale; + + // We look for a free buffer to draw into. If the buffer is not the last buffer we used, +diff --git a/src/client/qwaylandshmbackingstore_p.h b/src/client/qwaylandshmbackingstore_p.h +index e01632da..f3fae438 100644 +--- a/src/client/qwaylandshmbackingstore_p.h ++++ b/src/client/qwaylandshmbackingstore_p.h +@@ -71,7 +71,7 @@ class QWaylandWindow; + class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer { + public: + QWaylandShmBuffer(QWaylandDisplay *display, +- const QSize &size, QImage::Format format, int scale = 1); ++ const QSize &size, QImage::Format format, qreal scale = 1); + ~QWaylandShmBuffer() override; + QSize size() const override { return mImage.size(); } + int scale() const override { return int(mImage.devicePixelRatio()); } diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp -index df2dcdaa..3b700002 100644 +index df2dcdaa..07d8f8f1 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr; @@ -1600,6 +1722,15 @@ index df2dcdaa..3b700002 100644 delete mWindowDecoration; if (mSurface) +@@ -189,7 +185,7 @@ void QWaylandWindow::initWindow() + // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() + // to inform the compositor that high-resolution buffers will be provided. + if (mDisplay->compositorVersion() >= 3) +- mSurface->set_buffer_scale(scale()); ++ mSurface->set_buffer_scale(mScale); + + if (QScreen *s = window()->screen()) + setOrientationMask(s->orientationUpdateMask()); @@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const void QWaylandWindow::reset() @@ -1731,29 +1862,39 @@ index df2dcdaa..3b700002 100644 handleUpdate(); buffer->setBusy(); -@@ -583,7 +572,11 @@ void QWaylandWindow::damage(const QRect &rect) +@@ -583,7 +572,16 @@ 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) -+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); -+ else ++ const qreal s = scale(); ++ if (mDisplay->compositorVersion() >= 4) { ++ const QRect bufferRect = ++ QRectF(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()) ++ .toAlignedRect(); ++ mSurface->damage_buffer(bufferRect.x(), bufferRect.y(), bufferRect.width(), ++ bufferRect.height()); ++ } 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) +@@ -619,8 +617,19 @@ 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()); + if (mDisplay->compositorVersion() >= 4) { -+ const int s = scale(); -+ for (const QRect &rect: damage) -+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); ++ const qreal s = scale(); ++ for (const QRect &rect : damage) { ++ const QRect bufferRect = ++ QRectF(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()) ++ .toAlignedRect(); ++ mSurface->damage_buffer(bufferRect.x(), bufferRect.y(), bufferRect.width(), ++ bufferRect.height()); ++ } + } else { + for (const QRect &rect: damage) + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); @@ -1761,7 +1902,7 @@ index df2dcdaa..3b700002 100644 Q_ASSERT(!buffer->committed()); buffer->setCommitted(); mSurface->commit(); -@@ -635,42 +634,53 @@ void QWaylandWindow::commit() +@@ -635,42 +644,53 @@ void QWaylandWindow::commit() const wl_callback_listener QWaylandWindow::callbackListener = { [](void *data, wl_callback *callback, uint32_t time) { @@ -1832,7 +1973,7 @@ index df2dcdaa..3b700002 100644 if (mWaitingForFrameCallback) { qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; -@@ -874,7 +884,11 @@ bool QWaylandWindow::createDecoration() +@@ -874,7 +894,11 @@ bool QWaylandWindow::createDecoration() // size and are not redrawn, leaving the new buffer empty. As a simple // work-around, we trigger a full extra update whenever the client-side // window decorations are toggled while the window is showing. @@ -1845,7 +1986,7 @@ index df2dcdaa..3b700002 100644 } return mWindowDecoration; -@@ -1028,8 +1042,17 @@ void QWaylandWindow::handleScreensChanged() +@@ -1028,8 +1052,17 @@ void QWaylandWindow::handleScreensChanged() if (newScreen == mLastReportedScreen) return; @@ -1863,7 +2004,25 @@ index df2dcdaa..3b700002 100644 int scale = newScreen->isPlaceholder() ? 1 : static_cast(newScreen)->scale(); if (scale != mScale) { -@@ -1101,10 +1124,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab) +@@ -1080,14 +1113,14 @@ bool QWaylandWindow::isActive() const + return mDisplay->isWindowActivated(this); + } + +-int QWaylandWindow::scale() const ++qreal QWaylandWindow::scale() const + { +- return mScale; ++ return devicePixelRatio(); + } + + qreal QWaylandWindow::devicePixelRatio() const + { +- return mScale; ++ return qreal(mScale); + } + + bool QWaylandWindow::setMouseGrabEnabled(bool grab) +@@ -1101,10 +1134,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab) return true; } @@ -1883,7 +2042,7 @@ index df2dcdaa..3b700002 100644 mLastReportedWindowStates = states; } -@@ -1146,19 +1177,24 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) +@@ -1146,19 +1187,24 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) if (event->timerId() != mFrameCallbackCheckIntervalTimerId) return; @@ -1919,7 +2078,7 @@ index df2dcdaa..3b700002 100644 } void QWaylandWindow::requestUpdate() -@@ -1167,8 +1203,11 @@ void QWaylandWindow::requestUpdate() +@@ -1167,8 +1213,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 @@ -1933,7 +2092,7 @@ index df2dcdaa..3b700002 100644 // 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 -@@ -1181,7 +1220,12 @@ void QWaylandWindow::requestUpdate() +@@ -1181,7 +1230,12 @@ void QWaylandWindow::requestUpdate() // so use invokeMethod to delay the delivery a bit. QMetaObject::invokeMethod(this, [this] { // Things might have changed in the meantime @@ -1947,7 +2106,7 @@ index df2dcdaa..3b700002 100644 deliverUpdateRequest(); }, Qt::QueuedConnection); } -@@ -1192,19 +1236,18 @@ void QWaylandWindow::requestUpdate() +@@ -1192,19 +1246,18 @@ void QWaylandWindow::requestUpdate() void QWaylandWindow::handleUpdate() { qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread(); @@ -1972,7 +2131,7 @@ index df2dcdaa..3b700002 100644 mFrameCallback = wl_surface_frame(wrappedSurface); wl_proxy_wrapper_destroy(wrappedSurface); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); -@@ -1214,6 +1257,8 @@ void QWaylandWindow::handleUpdate() +@@ -1214,6 +1267,8 @@ void QWaylandWindow::handleUpdate() // Start a timer for handling the case when the compositor stops sending frame callbacks. if (mFrameCallbackTimeout > 0) { QMetaObject::invokeMethod(this, [this] { @@ -1981,7 +2140,7 @@ index df2dcdaa..3b700002 100644 if (mWaitingForFrameCallback) { if (mFrameCallbackCheckIntervalTimerId < 0) mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout); -@@ -1274,6 +1319,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) +@@ -1274,6 +1329,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) wl_region_destroy(region); } @@ -2003,7 +2162,7 @@ index df2dcdaa..3b700002 100644 QT_END_NAMESPACE diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h -index 01337cff..2f219d8c 100644 +index 01337cff..741f9e5c 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -98,6 +98,9 @@ public: @@ -2016,7 +2175,7 @@ index 01337cff..2f219d8c 100644 virtual WindowType windowType() const = 0; virtual void ensureSize(); WId winId() const override; -@@ -148,6 +151,7 @@ public: +@@ -148,13 +151,14 @@ public: void setWindowState(Qt::WindowStates states) override; void setWindowFlags(Qt::WindowFlags flags) override; void handleWindowStatesChanged(Qt::WindowStates states); @@ -2024,6 +2183,14 @@ index 01337cff..2f219d8c 100644 void raise() override; void lower() override; + + void setMask(const QRegion ®ion) override; + +- int scale() const; ++ qreal scale() const; + qreal devicePixelRatio() const override; + + void requestActivateWindow() override; @@ -206,6 +210,10 @@ public: void handleUpdate(); void deliverUpdateRequest() override; @@ -2227,6 +2394,19 @@ index 6c8f04ec..94c56325 100644 }; } +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +index c1f45fa6..bbc63444 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +@@ -195,7 +195,7 @@ public: + QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context()); + + QSize surfaceSize = window->surfaceSize(); +- int scale = window->scale() ; ++ qreal scale = window->scale() ; + glViewport(0, 0, surfaceSize.width() * scale, surfaceSize.height() * scale); + + //Draw Decoration 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 --- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h diff --git a/desktop/toolkit/qt5/qt5-wayland/pspec.xml b/desktop/toolkit/qt5/qt5-wayland/pspec.xml index 39cad7a325..1e78f164e2 100755 --- a/desktop/toolkit/qt5/qt5-wayland/pspec.xml +++ b/desktop/toolkit/qt5/qt5-wayland/pspec.xml @@ -85,6 +85,13 @@ + + 2023-09-08 + 5.15.10 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2023-06-17 5.15.10