Releases: quotient-im/libQuotient
0.9.0
A new stable release and a new branch of libQuotient are out the door, a year and 3+ months since 0.8.0, and a bit over 6 months after the last stable release, 0.8.2, getting almost 400 commits in this half a year. Thanks to the NeoChat team (@TobiasFella and @nvrWhere, namely) actively participating in the library development, we are now in condition to release roughly one new stable branch a year, and a stable release every few months.
Same as with 0.8.0, make sure to read the beta release notes if you're looking for the list of most important changes. We also had a few additions through several release candidates since, covered in the respective (much shorter) release notes (you can find them all at https://github.com/quotient-im/libQuotient/releases, below this text). Key things introduced in 0.9 are:
- Qt 6 only (see more about this below)
- cross-signing support (requires UI to match on the client side; NeoChat already has it)
- Matrix 1.12 API, including, most importantly, content repo functionality switching to authenticated media
- completed separation of room member functionality previously delivered by the
User
class, to a dedicatedRoomMember
class - introduction of futures to replace signals for one-off asynchronous calls, especially relevant for calls returning job pointers; the migration to this new way will continue through the next cycle
- refactoring of the event content API to make transition to extensible events easier in the future
The link to the full changelog is at the bottom of these release notes, as always.
Toolchain and compatibility
As anticipated in 0.8.0 release notes, 0.9 goes Qt 6-only - specifically, requires Qt 6.4 or newer. Despite all the tweaks and improvements made to Qt 5.15 across the last years it really shows its age now; Qt 6 has quite a few features (much better STL integration and futures, to name a couple) that Qt 5.15 will never have.
Otherwise, we're fully in the C++20 land, and we started using elements of C++23 supported by recent toolchains across the platforms - see the "C++ feature set" section in CONTRIBUTING.md
for details.
In line with our practice so far, 0.9 API is not backwards compatible with 0.8 - a lot of deprecated and even some not previously deprecated pieces have been removed to give way to new functionality. Migration should still be a straightforward exercise, especially if you heeded deprecation warnings while compiling with 0.8.x. Building with 0.8.2, eliminating deprecation warnings, and then going to 0.9 is a good way to reduce the migration effort.
E2EE dependencies now mandatory
The dependency on libolm and OpenSSL was introduced in version 0.7, conditional on E2EE support CMake switch. This CMake switch is now gone; you can't opt out of E2EE support at build time any more, and the two libraries are now required to build libQuotient in any configuration. That might not hold for long though, as Olm is now entirely deprecated; the next stable branch will likely replace the E2EE internals altogether. Read on about our plans with respect to that.
What's next
That's a very good question :) First of all, continuing on the dependencies subject - @TobiasFella has already started working on the replacement of our current E2EE backend (just a branch, no PR yet) that will use https://github.com/matrix-org/matrix-rust-sdk instead of libolm and OpenSSL. Given the deprecated state of libolm, it is very likely that the next .0 release will have that new backend instead. That will mean a considerable complication for Linux packagers as libQuotient will now effectively rely on Rust crates - unfortunately, it's unavoidable as we really don't want to reimplement Matrix crypto things and Vodozemac is the new official library for that.
Yet another thing that industrious @TobiasFella has set in motion is the work on OIDC integration. This will bring the long awaited feature to libQuotient - ability to carry out user registration without having to directly call the low-level Matrix API and navigate the UIA flows. This is the last feature from the proto-roadmap created in very early project days (you can still look at it in the Quaternion wiki); once it is done, we can officially call libQuotient feature-complete and cut version 1.0. Whether the next stable branch will be 0.10.x or 1.x depends on whether we manage to get OIDC integration merged in the next, say, half a year (which is quite realistic but not entirely guaranteed).
On top of these two, the smaller stuff certainly on the radar is storing recent timeline events in the database, refresh tokens support, spaces support improvements and a lot of other things, some of those deliverable in 0.9.x without breaking back-compat. All our plans can be found at this board.
Thanks for flying with us!
Full Changelog: 0.8.2...0.9.0
0.9 RC3
This is (hopefully) the last 0.9 release candidate, with a few final changes around FileContentBase
and RoomMessageEvent
APIs (#812 by @KitsuneRal). Thanks to @nvrWhere for testing things as they were going out of my machine.
0.9 RC2
The changes in RoomMessageEvent
API warranted a round of rework and therefore here's another RC, with the following notable changes:
- @nvrWhere introduced ability to reply with any message event, not just text one (#805)
- @nvrWhere and @KitsuneRal reworked the
RoomMessageEvent
content API; the content object is always loaded on the fly from the event JSON, rather than created along with the event, reducing the memory footprint (#807 and #809) - @KitsuneRal refreshed the library backend to build on the released Matrix 1.12 CS API (#808)
Full Changelog: 0.9-rc1...0.9-rc2
0.9 RC
On the heels of 0.9 beta, the Release Candidate comes with a bunch of fixes (#794,#798, #803 by @KitsuneRal; #795, #801 by @nvrWhere) and general codebase improvements (#791 by @KitsuneRal). On top of that:
- @KitsuneRal reintroduced
QImage
-returningavatar()
API toRoomMember
that has previously been dropped inUser
, as porting of Quaternion to libQuotient 0.9 needed that (#796) - @nvrWhere added helper functions for replies and threads to
RoomMessageEvent
(#789) - @KitsuneRal (with a lot of input from @nvrWhere) started work on API to facilitate power level checking (#799); expect more awesome API in 0.9.x cycle later on
- As a last minute change, the Matrix API backend has been upgraded to Matrix (pre-)1.12; this required small improvements in GTAD, so those who generate API files should make sure to update the respective Git submodule (#804 by @KitsuneRal)
Full Changelog: 0.9-beta1...0.9-rc1
0.9 beta
The project continues to get to steadier releases, so here we are with 0.9 beta, just over 4 months after 0.8.2. The amount of changes is comparable with 0.8, and we haven't finished yet; expect a few more things to land before 0.9 gets out, hopefully in time for the very first Matrix Conference later in September!
Toolchain and compatibility
Quotient 0.9 will only build and run with Qt 6 - no Qt 5 any more (#709 by @TobiasFella). In fact, the oldest supported version is Qt 6.4, and we already use quite a few things introduced in that version. The compiler and standard library versions have been bumped up as well: it's GCC 13, Clang 16, MSVC :2022 - we now require solid C++20 support and first elements of C++23 are already used, too (#744 and #748 by @KitsuneRal). We still don't use C++ modules.
If things go as we'd like, 0.9 will be the last version using Olm for E2EE. Although still solid, Olm is now officially deprecated by the Matrix project in favour of Vodozemac, and that will likely be our new E2EE foundation, too. This will mean adding Rust to our dependencies - while this is unfortunate (we try to keep deps to a minimum, to facilitate porting), our project is not equipped to take over Olm or otherwise reimplement E2EE in C++. On the other hand, Rust code is usually very good at performance and memory footprint, which is what we at Quotient care about. As of this writing, valiant @TobiasFella already commenced the work - if you know something about Rust-C++ bindings, you're welcome to help.
Highlights
The most prominent feature added in this cycle is (finally!) cross-signing support (#630 and #765 by @TobiasFella, #755 by @KitsuneRal). Tobias has been driving and polishing it for quite some time, using NeoChat as the testbed - all thanks go to him for making it happen.
The library is now based on Matrix API 1.11 (#763 by @KitsuneRal), and thanks to that it is possible to support authenticated media requests (#776 by @KitsuneRal and #784 by @TobiasFella). You don't need to do anything in the client, the library will automatically add the access tokens to media requests if it detects a compliant homeserver.
While not a new feature, one major refactoring in the library stands out that started back in 0.8.x: taking the room member API from somewhat heavy, QObject
-based User
to the separate much lighter RoomMember
class. @nvrWhere has done most of the heavy-lifting - many thanks for that! With this refactoring the library won't make thousands of User
instances on the heap any more, one for almost each and every MXID it learns of, without much use for it as most room members are never interacted with or even displayed. Overall, that means faster processing of sync batches (especially initial syncs). Most of the new API was introduced in 0.8.x, with the old API deprecated; and in 0.9, this deprecated API will be entirely gone (#743 and #746 by @nvrWhere). If you're missing some calls, bring up an issue and we'll sort it out.
With the library entirely flying Qt 6 now, another refactoring is in progress, and will likely continue into post-0.9 cycle: using futures instead of signals for asynchronous communication, in particular in the context of network requests (aka jobs). Using job pointers and signal-slot connections has always had caveats: e.g. you have to take extra care to connect to the signal before it has any chance of being emitted; the job type is not passed in the signal (to avoid making every single job type a Q_OBJECT
, which would inflate build times greatly) so you have to use side channels to pass that type into the handler; signals for non-job single-shot processes (e.g. file downloads) need extra filtering for the identifier associated with the process (e.g. file path or a Matrix event); and so on. Futures provide a more straightforward, typesafe interface to achieve the same goal. To facilitate the transition, a new JobHandle
template class is introduced that behaves both as a future and as a QPointer
to the underlying job (#754 and #764 by @KitsuneRal). Eventually, we will likely stop using job pointers completely and switch to futures (especially as and when Qt gets better support for futures in QML).
Other notable changes
Quotient_ENABLE_E2EE
CMake flag is not there anymore; the library is always built with E2EE support, useConnection
facilities to turn it on/off (#741 by @TobiasFella)- With the new toolchains,
std::optional
is good enough thatOmittable
is not needed any more (#745 by @KitsuneRal) RoomMember
is a bit more convenient to use now (#747 by @KitsuneRal)- Matrix API structures are now exported with
QUOTIENT_API
(#749 by @KitsuneRal) - Cleanup/deprecation of old code and backport of
Room::requestedHistorySize()
from Quaternion (#750, #778 and #786 by @KitsuneRal) - The library doesn't run database queries twice any more (#751 by @TobiasFella)
- Auth data can have non-objects now (#752 by @KitsuneRal)
- Update membersTyping by @nvrWhere in #753
- E2EE tweaks and improvements (#756, #757, #758 and #761 by @TobiasFella)
- Small convenience facilities:
findIndirect()
range algorithm,editSubobject()
/replaceSubvalue()
for JSON manipulation,QUO_CHECK
,QUO_ALARM
andQUO_ALARM_X
macros for data checking (#760 by @KitsuneRal, with additional fixes in #778 already mentioned above) - Exposing member power levels in
RoomMember
(#768 by @nvrWhere, #769 by @KitsuneRal) - Deserialize CBOR data without one allocation per value (#772 by @vkrause)
- Add a promise/future pair to
PendingEventItem
(#767 by @KitsuneRal) - Code modernisation + newer Synapse for autotests (#775 by @KitsuneRal)
- Prepare libQuotient for operating without being able to reach the server (#777 by @TobiasFella)
- Unified event id accessor for pending and normal events (#787 by @nvrWhere)
New Contributors
Thanks, and congratulations with the first contribution, go to @teohhanhui for fixing a dead link to the NeoChat page (#785).
Full Changelog: 0.8.2...0.9-beta1
0.8.2
A new 0.8.x release is here; unlike the previous one, it includes more changes than usual due to significant contributions from NeoChat community (big thanks to @nvrWhere and @TobiasFella!).
This is meant to be the last (significant) 0.8.x release; active work on 0.9 will commence from now on the development branch, with the first big change - dropping Qt 5 support - coming immediately after 0.8.2 is released. Incremental, compat-preserving changes can still arrive for 0.8.x in the dedicated branch, with 0.8.3 potentially rolling them up in a few months.
Most notable changes:
- Historical encrypted messages can now be decrypted with old megolm keys retrieved from SSSS (@TobiasFella, #687)
- The
User
library API is getting prepared to be split into that for room members (RoomMember
) and user profiles (stays inUser
for now) in 0.9, deprecating most ofUser
methods that acceptRoom
for the member context (@nvrWhere, #695, #724, and #725) - Along the same lines: functions to (un)ignore users by userid rather than
User*
are introduced; the old signatures are deprecated now and will be removed in 0.9 (@TobiasFella, #718) - More efficient (less cache-wasting) avatar retrieval (@KitsuneRal, #711)
- Property for querying connection's
account_data
(@TobiasFella, #719) - Fix brain-split when checking event types on some Linux distributions (@KitsuneRal, #726, fixes #692)
- A new event class for
m.room.server_acl
(@nvrWhere, #729) - The library supports defaulting direct chats to E2EE now (@nvrWhere, #730)
Full Changelog: 0.8.1.2...0.8.2
0.8.1.2
Thanks to the vigilant eye of @antonio-rojas, it turned out that version 0.8.1 is not entirely ABI compatible with 0.8.0 as it should. This release is made solely to fix it; there are no other changes.
0.8.1(.1)
(Version 0.8.1 missed an important PR that actually changes the advertised version and updates the documentation - so it was re-released as 0.8.1.1 with the PR merged.)
The first maintenance release in the 0.8.x branch is here now. Notable changes:
- @KitsuneRal got rid of deprecated
RoomPinnedEvent
name in #680 - @TobiasFella fixed session verification in #682
- @nvrWhere constified
Room::userIdsAtEvent()
in #686 (first contribution - thanks, and looking forward to more!) - @TobiasFella enhanced logging around key verification in #690
- @KitsuneRal made it possible to use the key backup client-server API in the backend (#693)
- @KitsuneRal also constrained the e-mail logic in linkifyUrl() so that it doesn't trigger in the middle of another URL (#698)
Full Changelog: 0.8.0...0.8.1.1
0.8.0
Took much less than 0.7, right? Just over half a year passed since 0.7.0 has been released, and 0.7.2 came out just a couple months ago. The whole changeset since 0.7.2 is just over a hundred commits, compared to more than a thousand between 0.6.x and 0.7.0. Hopefully, we'll be able to continue this steadier, more evolutionary pace from now on, and then 0.9 will come out by the end of the year.
Most of the changes are already described in release notes for 0.8 beta - you're welcome to read them.
Since RC went out, we’ve got just two substantial changes: @vkrause fixed AccountRegistry::invokeLogin()
in #675 to still add Connection
objects after successfully connecting them to the homeserver; and @KitsuneRal made pinned events actually follow the specification (and therefore, interoperable) in #677.
On top of that - a few formal things that we used to add to announcements: the toolchain updates, and notes on compatibility and maintenance.
Toolchain and compatibility
Well, in fact there are not many updates here. We're still using C++20 and building with the same compiler versions as libQuotient 0.7.0 used: GCC 11, Clang 11, MSVC 2019 and Apple Clang 12 are our baseline. We also continue building with Qt 5 as well as Qt 6 - but as we warned before, Qt 5 may be dropped any time soon, with Qt 6.5 already out there and being in quite a good shape. By now we have to jump through some hoops and limit our use of the new Qt 6 API - so the pressure is already there to switch over to Qt 6 entirely as soon as version 0.9 starts coming together - meaning that 0.8.x will very probably be the last one to officially build with Qt 5.
Also, the next version will bump compiler requirements - in particular, we're going to require Clang 13 and Apple Clang 14, to take advantage of even more C++20 features (particularly the ranges framework). If your toolchains are older, take effort to update them.
Despite not a lot of time behind, libQuotient 0.8 API is not compatible with 0.7; if you didn't try 0.8 beta before, you now have to rebuild your code with the new version and see what breaks. We try to play soft and deprecate things before dropping them; but that's not always possible. Be aware that if the compilation already spits out deprecation warnings with an older version, these are the most likely places to get broken when building with the next "sub-major" (0.8->0.9, that is) version.
Understanding that the install base for libQuotient 0.6 is comparatively large, 0.6 remains on "sustained support" (i.e. updating it on request). There were not many requests to update it since 0.7 though so this is likely to only be there for another month or two.
Thanks
As always, many thanks to all who use libQuotient and help us with the development!
0.8 RC
The release candidate for 0.8 is a relatively incremental change, as beta seemed to be doing generally fine, with only minor (and not even that necessary) tweaks here and there and the documentation update.
What's changed in code
- asKeyValueRange: support accepting rvalues (by @KitsuneRal in #671)
- Tighten up logging categories stuff (by @KitsuneRal in #672)
Full Changelog: 0.8-beta1...0.8-rc1