Hello community, here is the log from the commit of package libqmatrixclient for openSUSE:Factory checked in at 2020-01-29 13:21:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqmatrixclient (Old) and /work/SRC/openSUSE:Factory/.libqmatrixclient.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqmatrixclient" Wed Jan 29 13:21:54 2020 rev:5 rq:768264 version:0.5.2 Changes: -------- --- /work/SRC/openSUSE:Factory/libqmatrixclient/libqmatrixclient.changes 2019-06-12 13:10:49.373035394 +0200 +++ /work/SRC/openSUSE:Factory/.libqmatrixclient.new.26092/libqmatrixclient.changes 2020-01-29 13:23:09.602316447 +0100 @@ -1,0 +2,10 @@ +Wed Jan 29 09:01:29 UTC 2020 - ec...@opensuse.org + +- Update to 0.5.2 + This is the last version of libqmatrixclient. + Only for quaternion and other packages wich need that. + Problem is that libqmatrixclient was renamed, but quaternion from + same developer use still old libnames. +- Add 0001-Compatibility-with-Qt-5.14.patch from upstream. + +------------------------------------------------------------------- @@ -11,0 +22 @@ +- Run spec-cleaner. Old: ---- libqmatrixclient-0.5.1.2.tar.gz New: ---- 0001-Compatibility-with-Qt-5.14.patch libqmatrixclient-0.5.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqmatrixclient.spec ++++++ --- /var/tmp/diff_new_pack.STUNii/_old 2020-01-29 13:23:10.266316786 +0100 +++ /var/tmp/diff_new_pack.STUNii/_new 2020-01-29 13:23:10.270316788 +0100 @@ -1,7 +1,7 @@ # # spec file for package libqmatrixclient # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,33 +12,38 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # # %define soname libQMatrixClient %define soversion 0_5_1 +%define sname libQuotient Name: libqmatrixclient -Version: 0.5.1.2 +Version: 0.5.2 Release: 0 Summary: Library for Qt Matrix Clients License: LGPL-2.1-only Group: Development/Libraries/C and C++ -Url: https://github.com/QMatrixClient/libqmatrixclient -Source0: https://github.com/QMatrixClient/libqmatrixclient/archive/%{version}/%{name}-%{version}.tar.gz +URL: https://github.com/quotient-im/libQuotient/ +Source0: https://github.com/quotient-im/libQuotient/archive/%{version}/%{name}-%{version}.tar.gz +# Old SourceUrl for documentation. +#Source0: https://github.com/QMatrixClient/libqmatrixclient/archive/%%{version}/%%{name}-%%{version}.tar.gz +# PATCH-FIX-UPSTREAM +Patch0: 0001-Compatibility-with-Qt-5.14.patch BuildRequires: cmake -%if 0%{?suse_version} < 1500 -BuildRequires: gcc7-c++ -%else -BuildRequires: gcc-c++ -%endif BuildRequires: pkgconfig BuildRequires: pkgconfig(Qt5Core) >= 5.6 BuildRequires: pkgconfig(Qt5Gui) BuildRequires: pkgconfig(Qt5Multimedia) BuildRequires: pkgconfig(Qt5Network) +%if 0%{?suse_version} < 1500 +BuildRequires: gcc7-c++ +%else +BuildRequires: gcc-c++ +%endif %description Library for Qt-based Matrix chat clients. It is required by @@ -62,14 +67,17 @@ developing applications that use %{name}. %prep -%setup -q +%setup -q -n %{sname}-%{version} +%patch0 -p1 %build %if 0%{?suse_version} < 1500 export CC="gcc-7" export CXX="g++-7" %endif -%cmake +%cmake \ + -DCMAKE_INSTALL_INCLUDEDIR=%{_includedir}/%{name} \ + -DBUILD_SHARED_LIBS=ON %install %cmake_install @@ -91,23 +99,7 @@ %{_libdir}/pkgconfig/QMatrixClient.pc %{_libdir}/libQMatrixClient.so %{_libdir}/cmake/QMatrixClient/ -%dir %{_includedir}/csapi -%dir %{_includedir}/csapi/definitions -%dir %{_includedir}/csapi/definitions/wellknown -%dir %{_includedir}/application-service -%dir %{_includedir}/application-service/definitions -%dir %{_includedir}/identity -%dir %{_includedir}/identity/definitions -%dir %{_includedir}/jobs -%dir %{_includedir}/events -%{_includedir}/*.h -%{_includedir}/application-service/definitions/*.h -%{_includedir}/csapi/*.h -%{_includedir}/csapi/definitions/*h -%{_includedir}/csapi/definitions/wellknown/*h -%{_includedir}/events/*.h -%{_includedir}/identity/definitions/*.h -%{_includedir}/jobs/*.h +%{_includedir}/%{name} %{_bindir}/qmc-example %changelog ++++++ 0001-Compatibility-with-Qt-5.14.patch ++++++ >From 0db8cd8772155f8f6f412c754b15552c5f244a0b Mon Sep 17 00:00:00 2001 From: Kitsune Ral <kitsune-...@users.sf.net> Date: Sat, 2 Nov 2019 16:20:57 +0900 Subject: [PATCH] Compatibility with Qt 5.14 --- lib/converters.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/converters.h b/lib/converters.h index af2be64..b06b414 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -37,6 +37,7 @@ template <typename T> using optional = std::experimental::optional<T>; #endif +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) // Enable std::unordered_map<QString, T> namespace std { @@ -44,14 +45,12 @@ namespace std { size_t operator()(const QString& s) const Q_DECL_NOEXCEPT { - return qHash(s -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - , uint(qGlobalQHashSeed()) -#endif + return qHash(s, uint(qGlobalQHashSeed()) ); } }; } +#endif class QVariant; -- 2.25.0 ++++++ libqmatrixclient-0.5.1.2.tar.gz -> libqmatrixclient-0.5.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqmatrixclient-0.5.1.2/CMakeLists.txt new/libQuotient-0.5.2/CMakeLists.txt --- old/libqmatrixclient-0.5.1.2/CMakeLists.txt 2019-04-17 11:53:24.000000000 +0200 +++ new/libQuotient-0.5.2/CMakeLists.txt 2019-05-22 01:23:06.000000000 +0200 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.1) set(API_VERSION "0.5.1") # Normally it should just include major.minor -project(qmatrixclient VERSION "${API_VERSION}.2" LANGUAGES CXX) +project(qmatrixclient VERSION "0.5.2" LANGUAGES CXX) option(QMATRIXCLIENT_INSTALL_EXAMPLE "install qmc-example application" ON) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqmatrixclient-0.5.1.2/lib/connection.cpp new/libQuotient-0.5.2/lib/connection.cpp --- old/libqmatrixclient-0.5.1.2/lib/connection.cpp 2019-04-17 11:53:24.000000000 +0200 +++ new/libQuotient-0.5.2/lib/connection.cpp 2019-05-22 01:23:06.000000000 +0200 @@ -73,8 +73,7 @@ : data(move(connection)) { } Q_DISABLE_COPY(Private) - Private(Private&&) = delete; - Private operator=(Private&&) = delete; + DISABLE_MOVE(Private) Connection* q = nullptr; std::unique_ptr<ConnectionData> data; @@ -91,6 +90,10 @@ QMap<QString, User*> userMap; DirectChatsMap directChats; DirectChatUsersMap directChatUsers; + // The below two variables track local changes between sync completions. + // See also: https://github.com/QMatrixClient/libqmatrixclient/wiki/Handling-direct-chat-events + DirectChatsMap dcLocalAdditions; + DirectChatsMap dcLocalRemovals; std::unordered_map<QString, EventPtr> accountData; QString userId; int syncLoopTimeout = -1; @@ -107,8 +110,6 @@ void connectWithToken(const QString& user, const QString& accessToken, const QString& deviceId); - void broadcastDirectChatUpdates(const DirectChatsMap& additions, - const DirectChatsMap& removals); template <typename EventT> EventT* unpackAccountData() const @@ -373,6 +374,20 @@ syncLoopIteration(); // initial sync to start the loop } +QJsonObject toJson(const Connection::DirectChatsMap& directChats) +{ + QJsonObject json; + for (auto it = directChats.begin(); it != directChats.end();) + { + QJsonArray roomIds; + const auto* user = it.key(); + for (; it != directChats.end() && it.key() == user; ++it) + roomIds.append(*it); + json.insert(user->id(), roomIds); + } + return json; +} + void Connection::onSyncSuccess(SyncData &&data, bool fromCache) { d->data->setLastEvent(data.nextBatch()); for (auto&& roomData: data.takeRoomData()) @@ -407,62 +422,90 @@ // Let UI update itself after updating each room QCoreApplication::processEvents(); } - for (auto&& accountEvent: data.takeAccountData()) - { - if (is<DirectChatEvent>(*accountEvent)) - { - const auto usersToDCs = ptrCast<DirectChatEvent>(move(accountEvent)) - ->usersToDirectChats(); - DirectChatsMap removals = - erase_if(d->directChats, [&usersToDCs] (auto it) { - return !usersToDCs.contains(it.key()->id(), it.value()); - }); - erase_if(d->directChatUsers, [&usersToDCs] (auto it) { - return !usersToDCs.contains(it.value()->id(), it.key()); - }); - if (MAIN().isDebugEnabled()) - for (auto it = removals.begin(); it != removals.end(); ++it) - qCDebug(MAIN) << it.value() - << "is no more a direct chat with" << it.key()->id(); - - DirectChatsMap additions; - for (auto it = usersToDCs.begin(); it != usersToDCs.end(); ++it) - { - if (auto* u = user(it.key())) - { - if (!d->directChats.contains(u, it.value())) - { - Q_ASSERT(!d->directChatUsers.contains(it.value(), u)); - additions.insert(u, it.value()); - d->directChats.insert(u, it.value()); - d->directChatUsers.insert(it.value(), u); - qCDebug(MAIN) << "Marked room" << it.value() + // After running this loop, the account data events not saved in + // d->accountData (see the end of the loop body) are auto-cleaned away + for (auto& eventPtr : data.takeAccountData()) + { + visit(*eventPtr, + [this](const DirectChatEvent& dce) { + // See https://github.com/QMatrixClient/libqmatrixclient/wiki/Handling-direct-chat-events + const auto& usersToDCs = dce.usersToDirectChats(); + DirectChatsMap remoteRemovals = + erase_if(d->directChats, [&usersToDCs, this](auto it) { + return !(usersToDCs.contains(it.key()->id(), it.value()) + || d->dcLocalAdditions.contains(it.key(), + it.value())); + }); + erase_if(d->directChatUsers, [&remoteRemovals](auto it) { + return remoteRemovals.contains(it.value(), it.key()); + }); + // Remove from dcLocalRemovals what the server already has. + erase_if(d->dcLocalRemovals, [&remoteRemovals](auto it) { + return remoteRemovals.contains(it.key(), it.value()); + }); + if (MAIN().isDebugEnabled()) + for (auto it = remoteRemovals.begin(); + it != remoteRemovals.end(); ++it) { + qCDebug(MAIN) + << it.value() << "is no more a direct chat with" + << it.key()->id(); + } + + DirectChatsMap remoteAdditions; + for (auto it = usersToDCs.begin(); it != usersToDCs.end(); + ++it) { + if (auto* u = user(it.key())) { + if (!d->directChats.contains(u, it.value()) + && !d->dcLocalRemovals.contains(u, it.value())) + { + Q_ASSERT( + !d->directChatUsers.contains(it.value(), u)); + remoteAdditions.insert(u, it.value()); + d->directChats.insert(u, it.value()); + d->directChatUsers.insert(it.value(), u); + qCDebug(MAIN) + << "Marked room" << it.value() << "as a direct chat with" << u->id(); - } - } else - qCWarning(MAIN) - << "Couldn't get a user object for" << it.key(); - } - if (!additions.isEmpty() || !removals.isEmpty()) - emit directChatsListChanged(additions, removals); - - continue; - } - if (is<IgnoredUsersEvent>(*accountEvent)) - qCDebug(MAIN) << "Users ignored by" << d->userId << "updated:" - << QStringList::fromSet(ignoredUsers()).join(','); - - auto& currentData = d->accountData[accountEvent->matrixType()]; - // A polymorphic event-specific comparison might be a bit more - // efficient; maaybe do it another day - if (!currentData || - currentData->contentJson() != accountEvent->contentJson()) - { - currentData = std::move(accountEvent); - qCDebug(MAIN) << "Updated account data of type" - << currentData->matrixType(); - emit accountDataChanged(currentData->matrixType()); - } + } + } else + qCWarning(MAIN) << "Couldn't get a user object for" + << it.key(); + } + // Remove from dcLocalAdditions what the server already has. + erase_if(d->dcLocalAdditions, [&remoteAdditions](auto it) { + return remoteAdditions.contains(it.key(), it.value()); + }); + if (!remoteAdditions.isEmpty() || !remoteRemovals.isEmpty()) + emit directChatsListChanged(remoteAdditions, remoteRemovals); + }, + // catch-all, passing eventPtr for a possible take-over + [this, &eventPtr](const Event& accountEvent) { + if (is<IgnoredUsersEvent>(accountEvent)) + qCDebug(MAIN) + << "Users ignored by" << d->userId << "updated:" + << QStringList::fromSet(ignoredUsers()).join(','); + + auto& currentData = d->accountData[accountEvent.matrixType()]; + // A polymorphic event-specific comparison might be a bit more + // efficient; maaybe do it another day + if (!currentData + || currentData->contentJson() + != accountEvent.contentJson()) { + currentData = std::move(eventPtr); + qCDebug(MAIN) << "Updated account data of type" + << currentData->matrixType(); + emit accountDataChanged(currentData->matrixType()); + } + }); + } + if (!d->dcLocalAdditions.isEmpty() || !d->dcLocalRemovals.isEmpty()) { + qDebug(MAIN) << "Sending updated direct chats to the server:" + << d->dcLocalRemovals.size() << "removal(s)," + << d->dcLocalAdditions.size() << "addition(s)"; + callApi<SetAccountDataJob>(d->userId, QStringLiteral("m.direct"), + toJson(d->directChats)); + d->dcLocalAdditions.clear(); + d->dcLocalRemovals.clear(); } } @@ -658,8 +701,8 @@ { Q_ASSERT(u); const auto& userId = u->id(); - // There can be more than one DC; find the first valid, and delete invalid - // (left/forgotten) ones along the way. + // There can be more than one DC; find the first valid (existing and + // not left), and delete inexistent (forgotten?) ones along the way. DirectChatsMap removals; for (auto it = d->directChats.find(u); it != d->directChats.end() && it.key() == u; ++it) @@ -696,6 +739,8 @@ << roomId << "is not valid and will be discarded"; // Postpone actual deletion until we finish iterating d->directChats. removals.insert(it.key(), it.value()); + // Add to the list of updates to send to the server upon the next sync. + d->dcLocalRemovals.insert(it.key(), it.value()); } if (!removals.isEmpty()) { @@ -705,7 +750,7 @@ d->directChatUsers.remove(it.value(), const_cast<User*>(it.key())); // FIXME } - d->broadcastDirectChatUpdates({}, removals); + emit directChatsListChanged({}, removals); } auto j = createDirectChat(userId); @@ -1006,28 +1051,6 @@ return d->directChats; } -QJsonObject toJson(const Connection::DirectChatsMap& directChats) -{ - QJsonObject json; - for (auto it = directChats.begin(); it != directChats.end();) - { - QJsonArray roomIds; - const auto* user = it.key(); - for (; it != directChats.end() && it.key() == user; ++it) - roomIds.append(*it); - json.insert(user->id(), roomIds); - } - return json; -} - -void Connection::Private::broadcastDirectChatUpdates(const DirectChatsMap& additions, - const DirectChatsMap& removals) -{ - q->callApi<SetAccountDataJob>(userId, QStringLiteral("m.direct"), - toJson(directChats)); - emit q->directChatsListChanged(additions, removals); -} - void Connection::addToDirectChats(const Room* room, User* user) { Q_ASSERT(room != nullptr && user != nullptr); @@ -1036,8 +1059,8 @@ Q_ASSERT(!d->directChatUsers.contains(room->id(), user)); d->directChats.insert(user, room->id()); d->directChatUsers.insert(room->id(), user); - DirectChatsMap additions { { user, room->id() } }; - d->broadcastDirectChatUpdates(additions, {}); + d->dcLocalAdditions.insert(user, room->id()); + emit directChatsListChanged({ { user, room->id() } }, {}); } void Connection::removeFromDirectChats(const QString& roomId, User* user) @@ -1050,15 +1073,17 @@ DirectChatsMap removals; if (user != nullptr) { - removals.insert(user, roomId); d->directChats.remove(user, roomId); d->directChatUsers.remove(roomId, user); + removals.insert(user, roomId); + d->dcLocalRemovals.insert(user, roomId); } else { removals = erase_if(d->directChats, [&roomId] (auto it) { return it.value() == roomId; }); d->directChatUsers.remove(roomId); + d->dcLocalRemovals += removals; } - d->broadcastDirectChatUpdates({}, removals); + emit directChatsListChanged({}, removals); } bool Connection::isDirectChat(const QString& roomId) const diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqmatrixclient-0.5.1.2/lib/events/event.h new/libQuotient-0.5.2/lib/events/event.h --- old/libqmatrixclient-0.5.1.2/lib/events/event.h 2019-04-17 11:53:24.000000000 +0200 +++ new/libQuotient-0.5.2/lib/events/event.h 2019-05-22 01:23:06.000000000 +0200 @@ -32,19 +32,23 @@ template <typename EventT> using event_ptr_tt = std::unique_ptr<EventT>; + /// Unwrap a plain pointer from a smart pointer template <typename EventT> - inline EventT* rawPtr(const event_ptr_tt<EventT>& ptr) // unwrap + inline EventT* rawPtr(const event_ptr_tt<EventT>& ptr) { return ptr.get(); } + /// Unwrap a plain pointer and downcast it to the specified type template <typename TargetEventT, typename EventT> inline TargetEventT* weakPtrCast(const event_ptr_tt<EventT>& ptr) { return static_cast<TargetEventT*>(rawPtr(ptr)); } + /// Re-wrap a smart pointer to base into a smart pointer to derived template <typename TargetT, typename SourceT> + [[deprecated("Consider using eventCast() or visit() instead")]] inline event_ptr_tt<TargetT> ptrCast(event_ptr_tt<SourceT>&& ptr) { return unique_ptr_cast<TargetT>(ptr);