Make Nheko compile on Qt6

qt66
Nicolas Werner 1 year ago
parent 0ac46ea209
commit b518f6902e
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 3
      CMakeLists.txt
  2. 15
      src/Cache.cpp
  3. 12
      src/ChatPage.cpp
  4. 2
      src/CompletionProxyModel.cpp
  5. 10
      src/GridImagePackModel.cpp
  6. 2
      src/InviteesModel.h
  7. 6
      src/JdenticonProvider.h
  8. 7
      src/LoginPage.cpp
  9. 33
      src/MainWindow.cpp
  10. 23
      src/MatrixClient.cpp
  11. 8
      src/MxcImageProvider.cpp
  12. 6
      src/MxcImageProvider.h
  13. 2
      src/SingleImagePackModel.cpp
  14. 20
      src/UserSettingsPage.cpp
  15. 2
      src/Utils.cpp
  16. 1
      src/dbus/NhekoDBusApi.h
  17. 1
      src/emoji/Provider.h
  18. 14
      src/main.cpp
  19. 3
      src/timeline/CommunitiesModel.cpp
  20. 4
      src/timeline/DelegateChooser.cpp
  21. 4
      src/timeline/DelegateChooser.h
  22. 14
      src/timeline/EventStore.cpp
  23. 9
      src/timeline/EventStore.h
  24. 86
      src/timeline/InputBar.cpp
  25. 20
      src/timeline/InputBar.h
  26. 3
      src/timeline/RoomlistModel.cpp
  27. 1
      src/timeline/TimelineModel.cpp
  28. 4
      src/timeline/TimelineModel.h
  29. 2
      src/timeline/TimelineViewManager.cpp
  30. 8
      src/timeline/TimelineViewManager.h
  31. 4
      src/ui/MxcAnimatedImage.cpp
  32. 2
      src/ui/MxcAnimatedImage.h
  33. 65
      src/ui/MxcMediaProxy.cpp
  34. 13
      src/ui/MxcMediaProxy.h
  35. 28
      src/ui/NhekoGlobalObject.cpp
  36. 2
      src/ui/Theme.cpp
  37. 27
      src/voip/CallManager.cpp
  38. 1
      src/voip/ScreenCastPortal.cpp
  39. 6
      src/voip/WebRTCSession.cpp

@ -239,7 +239,7 @@ endif()
# #
# Discover Qt dependencies. # Discover Qt dependencies.
# #
find_package(Qt6 6.5 COMPONENTS Core Widgets LinguistTools Svg Multimedia Qml QuickControls2 REQUIRED) find_package(Qt6 6.5 COMPONENTS Core Widgets Gui LinguistTools Svg Multimedia Qml QuickControls2 REQUIRED)
#find_package(Qt6QuickCompiler) #find_package(Qt6QuickCompiler)
find_package(Qt6DBus) find_package(Qt6DBus)
@ -747,6 +747,7 @@ target_link_libraries(nheko PRIVATE
spdlog::spdlog spdlog::spdlog
Qt::Widgets Qt::Widgets
Qt::Svg Qt::Svg
Qt::Gui
Qt::Multimedia Qt::Multimedia
Qt::Qml Qt::Qml
Qt::QuickControls2 Qt::QuickControls2

@ -93,11 +93,6 @@ static constexpr auto MEGOLM_SESSIONS_DATA_DB("megolm_sessions_data_db");
using CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>; using CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
using Receipts = std::map<std::string, std::map<std::string, uint64_t>>; using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
Q_DECLARE_METATYPE(RoomMember)
Q_DECLARE_METATYPE(mtx::responses::Timeline)
Q_DECLARE_METATYPE(RoomInfo)
Q_DECLARE_METATYPE(mtx::responses::QueryKeys)
namespace { namespace {
std::unique_ptr<Cache> instance_ = nullptr; std::unique_ptr<Cache> instance_ = nullptr;
} }
@ -4429,7 +4424,8 @@ Cache::displayName(const QString &room_id, const QString &user_id)
static bool static bool
isDisplaynameSafe(const std::string &s) isDisplaynameSafe(const std::string &s)
{ {
for (QChar c : QString::fromStdString(s).toStdU32String()) { for (std::uint32_t cc : QString::fromStdString(s).toStdU32String()) {
auto c = QChar(cc);
if (c.isPrint() && !c.isSpace()) if (c.isPrint() && !c.isSpace())
return false; return false;
} }
@ -5293,13 +5289,6 @@ namespace cache {
void void
init(const QString &user_id) init(const QString &user_id)
{ {
qRegisterMetaType<RoomMember>();
qRegisterMetaType<RoomInfo>();
qRegisterMetaType<QMap<QString, RoomInfo>>();
qRegisterMetaType<std::map<QString, RoomInfo>>();
qRegisterMetaType<std::map<QString, mtx::responses::Timeline>>();
qRegisterMetaType<mtx::responses::QueryKeys>();
instance_ = std::make_unique<Cache>(user_id); instance_ = std::make_unique<Cache>(user_id);
} }

@ -36,12 +36,6 @@ static constexpr int CHECK_CONNECTIVITY_INTERVAL = 15'000;
static constexpr int RETRY_TIMEOUT = 5'000; static constexpr int RETRY_TIMEOUT = 5'000;
static constexpr size_t MAX_ONETIME_KEYS = 50; static constexpr size_t MAX_ONETIME_KEYS = 50;
Q_DECLARE_METATYPE(std::optional<mtx::crypto::EncryptedFile>)
Q_DECLARE_METATYPE(std::optional<RelatedInfo>)
Q_DECLARE_METATYPE(mtx::presence::PresenceState)
Q_DECLARE_METATYPE(mtx::secret_storage::AesHmacSha2KeyDescription)
Q_DECLARE_METATYPE(SecretsToDecrypt)
ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent) ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
: QObject(parent) : QObject(parent)
, isConnected_(true) , isConnected_(true)
@ -53,12 +47,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
instance_ = this; instance_ = this;
qRegisterMetaType<std::optional<mtx::crypto::EncryptedFile>>();
qRegisterMetaType<std::optional<RelatedInfo>>();
qRegisterMetaType<mtx::presence::PresenceState>();
qRegisterMetaType<mtx::secret_storage::AesHmacSha2KeyDescription>();
qRegisterMetaType<SecretsToDecrypt>();
view_manager_ = new TimelineViewManager(callManager_, this); view_manager_ = new TimelineViewManager(callManager_, this);
connect(this, connect(this,

@ -29,7 +29,7 @@ CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
finder.toNextBoundary(); finder.toNextBoundary();
auto end = finder.position(); auto end = finder.position();
auto ref = str.midRef(start, end - start).trimmed(); auto ref = QStringView(str).mid(start, end - start).trimmed();
if (!ref.isEmpty()) if (!ref.isEmpty())
trie_.insert<ElementRank::second>(ref.toUcs4(), id); trie_.insert<ElementRank::second>(ref.toUcs4(), id);
} while (finder.position() < str.size()); } while (finder.position() < str.size());

@ -13,10 +13,6 @@
#include "Cache_p.h" #include "Cache_p.h"
#include "emoji/Provider.h" #include "emoji/Provider.h"
Q_DECLARE_METATYPE(StickerImage)
Q_DECLARE_METATYPE(TextEmoji)
Q_DECLARE_METATYPE(SectionDescription)
Q_DECLARE_METATYPE(QList<SectionDescription>)
QString QString
emoji::categoryToName(emoji::Emoji::Category cat) emoji::categoryToName(emoji::Emoji::Category cat)
@ -73,10 +69,6 @@ GridImagePackModel::GridImagePackModel(const std::string &roomId, bool stickers,
, room_id(roomId) , room_id(roomId)
, columns(stickers ? 3 : 7) , columns(stickers ? 3 : 7)
{ {
[[maybe_unused]] static auto id = qRegisterMetaType<StickerImage>();
[[maybe_unused]] static auto id2 = qRegisterMetaType<TextEmoji>();
[[maybe_unused]] static auto id3 = qRegisterMetaType<SectionDescription>();
[[maybe_unused]] static auto id4 = qRegisterMetaType<QList<SectionDescription>>();
if (!stickers) { if (!stickers) {
for (const auto &category : { for (const auto &category : {
@ -144,7 +136,7 @@ GridImagePackModel::GridImagePackModel(const std::string &roomId, bool stickers,
finder.toNextBoundary(); finder.toNextBoundary();
auto end = finder.position(); auto end = finder.position();
auto ref = str.midRef(start, end - start).trimmed(); auto ref = QStringView(str).mid(start, end - start).trimmed();
if (!ref.isEmpty()) if (!ref.isEmpty())
trie_.insert<ElementRank::second>(ref.toUcs4(), id); trie_.insert<ElementRank::second>(ref.toUcs4(), id);
} while (finder.position() < str.size()); } while (finder.position() < str.size());

@ -8,7 +8,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QVector> #include <QVector>
class TimelineModel; #include "timeline/TimelineModel.h"
class Invitee final : public QObject class Invitee final : public QObject
{ {

@ -54,10 +54,6 @@ public:
class JdenticonProvider class JdenticonProvider
: :
#if QT_VERSION < 0x60000
public QObject
,
#endif
public QQuickAsyncImageProvider public QQuickAsyncImageProvider
{ {
Q_OBJECT Q_OBJECT
@ -77,7 +73,7 @@ public slots:
if (queryStart != -1) { if (queryStart != -1) {
id_ = id.left(queryStart); id_ = id.left(queryStart);
auto query = id.mid(queryStart + 1); auto query = id.mid(queryStart + 1);
auto queryBits = query.splitRef('&'); auto queryBits = QStringView(query).split('&');
for (const auto &b : queryBits) { for (const auto &b : queryBits) {
if (b.startsWith(QStringView(u"radius="))) { if (b.startsWith(QStringView(u"radius="))) {

@ -19,19 +19,12 @@
#include "SSOHandler.h" #include "SSOHandler.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
Q_DECLARE_METATYPE(LoginPage::LoginMethod)
Q_DECLARE_METATYPE(SSOProvider)
using namespace mtx::identifiers; using namespace mtx::identifiers;
LoginPage::LoginPage(QObject *parent) LoginPage::LoginPage(QObject *parent)
: QObject(parent) : QObject(parent)
, inferredServerAddress_() , inferredServerAddress_()
{ {
[[maybe_unused]] static auto ignored =
qRegisterMetaType<LoginPage::LoginMethod>("LoginPage::LoginMethod");
[[maybe_unused]] static auto ignored2 = qRegisterMetaType<SSOProvider>();
connect(this, &LoginPage::versionOkCb, this, &LoginPage::versionOk, Qt::QueuedConnection); connect(this, &LoginPage::versionOkCb, this, &LoginPage::versionOk, Qt::QueuedConnection);
connect(this, &LoginPage::versionErrorCb, this, &LoginPage::versionError, Qt::QueuedConnection); connect(this, &LoginPage::versionErrorCb, this, &LoginPage::versionError, Qt::QueuedConnection);
connect( connect(

@ -7,6 +7,7 @@
#include <mtx/requests.hpp> #include <mtx/requests.hpp>
#include <mtx/responses/login.hpp> #include <mtx/responses/login.hpp>
#include <mtx/events/collections.hpp>
#include "AliasEditModel.h" #include "AliasEditModel.h"
#include "BlurhashProvider.h" #include "BlurhashProvider.h"
@ -63,13 +64,6 @@
#include "dbus/NhekoDBusApi.h" #include "dbus/NhekoDBusApi.h"
#endif #endif
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
Q_DECLARE_METATYPE(std::vector<mtx::responses::PublicRoomsChunk>)
Q_DECLARE_METATYPE(mtx::responses::PublicRoom)
Q_DECLARE_METATYPE(mtx::responses::Profile)
Q_DECLARE_METATYPE(mtx::responses::User)
MainWindow *MainWindow::instance_ = nullptr; MainWindow *MainWindow::instance_ = nullptr;
MainWindow::MainWindow(QWindow *parent) MainWindow::MainWindow(QWindow *parent)
@ -138,27 +132,8 @@ MainWindow::MainWindow(QWindow *parent)
void void
MainWindow::registerQmlTypes() MainWindow::registerQmlTypes()
{ {
qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>();
qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>();
qRegisterMetaType<mtx::events::msg::KeyVerificationDone>();
qRegisterMetaType<mtx::events::msg::KeyVerificationKey>();
qRegisterMetaType<mtx::events::msg::KeyVerificationMac>();
qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
qRegisterMetaType<mtx::responses::PublicRoom>();
qRegisterMetaType<mtx::responses::User>();
qRegisterMetaType<mtx::responses::Profile>();
qRegisterMetaType<CombinedImagePackModel *>();
qRegisterMetaType<GridImagePackModel *>();
qRegisterMetaType<RoomSettingsAllowedRoomsModel *>();
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qRegisterMetaType<std::vector<DeviceInfo>>();
qRegisterMetaType<std::vector<mtx::responses::PublicRoomsChunk>>();
qRegisterMetaType<std::vector<mtx::responses::User>>();
qRegisterMetaType<mtx::responses::User>();
qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject,
"im.nheko", "im.nheko",
1, 1,
@ -278,8 +253,6 @@ MainWindow::registerQmlTypes()
qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", userSettings_.data()); qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", userSettings_.data());
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qRegisterMetaType<std::vector<DeviceInfo>>();
qmlRegisterUncreatableType<FilteredCommunitiesModel>( qmlRegisterUncreatableType<FilteredCommunitiesModel>(
"im.nheko", "im.nheko",

@ -15,18 +15,7 @@
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
#include <mtx/responses.hpp> #include <mtx/responses.hpp>
Q_DECLARE_METATYPE(mtx::responses::Login)
Q_DECLARE_METATYPE(mtx::responses::Messages)
Q_DECLARE_METATYPE(mtx::responses::Notifications)
Q_DECLARE_METATYPE(mtx::responses::Rooms)
Q_DECLARE_METATYPE(mtx::responses::Sync)
Q_DECLARE_METATYPE(mtx::responses::StateEvents)
// Q_DECLARE_METATYPE(nlohmann::json)
Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(std::vector<std::string>)
Q_DECLARE_METATYPE(std::vector<QString>)
Q_DECLARE_METATYPE(std::set<QString>)
namespace http { namespace http {
@ -52,18 +41,6 @@ is_logged_in()
void void
init() init()
{ {
qRegisterMetaType<mtx::responses::Login>();
qRegisterMetaType<mtx::responses::Messages>();
qRegisterMetaType<mtx::responses::Notifications>();
qRegisterMetaType<mtx::responses::Rooms>();
qRegisterMetaType<mtx::responses::Sync>();
qRegisterMetaType<mtx::responses::StateEvents>();
qRegisterMetaType<std::string>();
// qRegisterMetaType<nlohmann::json>();
qRegisterMetaType<std::vector<std::string>>();
qRegisterMetaType<std::vector<QString>>();
qRegisterMetaType<std::map<QString, bool>>("std::map<QString, bool>");
qRegisterMetaType<std::set<QString>>();
} }
} // namespace http } // namespace http

@ -24,12 +24,8 @@
QHash<QString, mtx::crypto::EncryptedFile> infos; QHash<QString, mtx::crypto::EncryptedFile> infos;
MxcImageProvider::MxcImageProvider(QObject *parent) MxcImageProvider::MxcImageProvider()
#if QT_VERSION < 0x60000 : QQuickAsyncImageProvider()
: QObject(parent)
#else
: QQuickAsyncImageProvider(parent)
#endif
{ {
auto timer = new QTimer(this); auto timer = new QTimer(this);
timer->setInterval(std::chrono::hours(1)); timer->setInterval(std::chrono::hours(1));

@ -72,16 +72,12 @@ public:
class MxcImageProvider class MxcImageProvider
: :
#if QT_VERSION < 0x60000
public QObject
,
#endif
public QQuickAsyncImageProvider public QQuickAsyncImageProvider
{ {
Q_OBJECT Q_OBJECT
public: public:
MxcImageProvider(QObject *parent = nullptr); MxcImageProvider();
public slots: public slots:
QQuickImageResponse * QQuickImageResponse *

@ -20,7 +20,6 @@
#include "timeline/Permissions.h" #include "timeline/Permissions.h"
#include "timeline/TimelineModel.h" #include "timeline/TimelineModel.h"
Q_DECLARE_METATYPE(mtx::common::ImageInfo)
SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
@ -30,7 +29,6 @@ SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
, pack(std::move(pack_.pack)) , pack(std::move(pack_.pack))
, fromSpace_(pack_.from_space) , fromSpace_(pack_.from_space)
{ {
[[maybe_unused]] static auto imageInfoType = qRegisterMetaType<mtx::common::ImageInfo>();
if (!pack.pack) if (!pack.pack)
pack.pack = mtx::events::msc2545::ImagePack::PackDescription{}; pack.pack = mtx::events::msc2545::ImagePack::PackDescription{};

@ -1585,8 +1585,6 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
l.push_back(QString::fromStdString(d)); l.push_back(QString::fromStdString(d));
return l; return l;
}; };
static QFontDatabase fontDb;
switch (index.row()) { switch (index.row()) {
case Theme: case Theme:
return QStringList{ return QStringList{
@ -1605,9 +1603,9 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
i->camera().toStdString(), i->cameraResolution().toStdString())); i->camera().toStdString(), i->cameraResolution().toStdString()));
case Font: case Font:
return fontDb.families(); return QFontDatabase::families();
case EmojiFont: case EmojiFont:
return fontDb.families(QFontDatabase::WritingSystem::Symbol); return QFontDatabase::families(QFontDatabase::WritingSystem::Symbol);
case Ringtone: { case Ringtone: {
QStringList l{ QStringList l{
QStringLiteral("Mute"), QStringLiteral("Mute"),
@ -1651,8 +1649,6 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
bool bool
UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role) UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{ {
static QFontDatabase fontDb;
auto i = UserSettings::instance(); auto i = UserSettings::instance();
if (role == Value) { if (role == Value) {
switch (index.row()) { switch (index.row()) {
@ -1677,7 +1673,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
return false; return false;
} }
case ScaleFactor: { case ScaleFactor: {
if (value.canConvert(QMetaType::Double)) { if (value.canConvert(QMetaType::fromType<double>())) {
utils::setScaleFactor(static_cast<float>(value.toDouble())); utils::setScaleFactor(static_cast<float>(value.toDouble()));
return true; return true;
} else } else
@ -1782,7 +1778,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
return false; return false;
} }
case TimelineMaxWidth: { case TimelineMaxWidth: {
if (value.canConvert(QMetaType::Int)) { if (value.canConvert(QMetaType::fromType<int>())) {
i->setTimelineMaxWidth(value.toInt()); i->setTimelineMaxWidth(value.toInt());
return true; return true;
} else } else
@ -1880,7 +1876,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
return false; return false;
} }
case PrivacyScreenTimeout: { case PrivacyScreenTimeout: {
if (value.canConvert(QMetaType::Int)) { if (value.canConvert(QMetaType::fromType<int>())) {
i->setPrivacyScreenTimeout(value.toInt()); i->setPrivacyScreenTimeout(value.toInt());
return true; return true;
} else } else
@ -1894,7 +1890,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
return false; return false;
} }
case FontSize: { case FontSize: {
if (value.canConvert(QMetaType::Double)) { if (value.canConvert(QMetaType::fromType<double>())) {
i->setFontSize(value.toDouble()); i->setFontSize(value.toDouble());
return true; return true;
} else } else
@ -1902,7 +1898,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
} }
case Font: { case Font: {
if (value.userType() == QMetaType::Int) { if (value.userType() == QMetaType::Int) {
i->setFontFamily(fontDb.families().at(value.toInt())); i->setFontFamily(QFontDatabase::families().at(value.toInt()));
return true; return true;
} else } else
return false; return false;
@ -1910,7 +1906,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
case EmojiFont: { case EmojiFont: {
if (value.userType() == QMetaType::Int) { if (value.userType() == QMetaType::Int) {
i->setEmojiFontFamily( i->setEmojiFontFamily(
fontDb.families(QFontDatabase::WritingSystem::Symbol).at(value.toInt())); QFontDatabase::families(QFontDatabase::WritingSystem::Symbol).at(value.toInt()));
return true; return true;
} else } else
return false; return false;

@ -290,7 +290,7 @@ utils::firstChar(const QString &input)
return QString::fromUcs4(&c, 1).toUpper(); return QString::fromUcs4(&c, 1).toUpper();
} }
return QString::fromUcs4(&input.toUcs4().at(0), 1).toUpper(); return QString::fromUcs4(&input.toStdU32String().at(0), 1).toUpper();
} }
QString QString

@ -92,7 +92,6 @@ operator<<(QDBusArgument &arg, const RoomInfoItem &item);
const QDBusArgument & const QDBusArgument &
operator>>(const QDBusArgument &arg, RoomInfoItem &item); operator>>(const QDBusArgument &arg, RoomInfoItem &item);
} // nheko::dbus } // nheko::dbus
Q_DECLARE_METATYPE(nheko::dbus::RoomInfoItem)
QDBusArgument & QDBusArgument &
operator<<(QDBusArgument &arg, const QImage &image); operator<<(QDBusArgument &arg, const QImage &image);

@ -94,4 +94,3 @@ public:
QString QString
categoryToName(emoji::Emoji::Category cat); categoryToName(emoji::Emoji::Category cat);
} // namespace emoji } // namespace emoji
Q_DECLARE_METATYPE(emoji::Emoji)

@ -154,8 +154,6 @@ main(int argc, char *argv[])
QCoreApplication::setApplicationVersion(nheko::version); QCoreApplication::setApplicationVersion(nheko::version);
QCoreApplication::setOrganizationName(QStringLiteral("nheko")); QCoreApplication::setOrganizationName(QStringLiteral("nheko"));
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
// Disable the qml disk cache by default to prevent crashes on updates. See // Disable the qml disk cache by default to prevent crashes on updates. See
// https://github.com/Nheko-Reborn/nheko/issues/1383 // https://github.com/Nheko-Reborn/nheko/issues/1383
@ -332,16 +330,16 @@ main(int argc, char *argv[])
QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom));
QTranslator qtTranslator; QTranslator qtTranslator;
qtTranslator.load(QLocale(), if(qtTranslator.load(QLocale(),
QStringLiteral("qt"), QStringLiteral("qt"),
QStringLiteral("_"), QStringLiteral("_"),
QLibraryInfo::location(QLibraryInfo::TranslationsPath)); QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
app.installTranslator(&qtTranslator); app.installTranslator(&qtTranslator);
QTranslator appTranslator; QTranslator appTranslator;
appTranslator.load( if(appTranslator.load(
QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations")); QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations")))
app.installTranslator(&appTranslator); app.installTranslator(&appTranslator);
MainWindow w; MainWindow w;
// QQuickView w; // QQuickView w;

@ -17,15 +17,12 @@
#include "Utils.h" #include "Utils.h"
#include "timeline/TimelineModel.h" #include "timeline/TimelineModel.h"
Q_DECLARE_METATYPE(SpaceItem)
CommunitiesModel::CommunitiesModel(QObject *parent) CommunitiesModel::CommunitiesModel(QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, hiddenTagIds_{UserSettings::instance()->hiddenTags()} , hiddenTagIds_{UserSettings::instance()->hiddenTags()}
, mutedTagIds_{UserSettings::instance()->mutedTags()} , mutedTagIds_{UserSettings::instance()->mutedTags()}
{ {
static auto ignore = qRegisterMetaType<SpaceItem>();
(void)ignore;
} }
QHash<int, QByteArray> QHash<int, QByteArray>

@ -77,13 +77,13 @@ DelegateChooser::appendChoice(QQmlListProperty<DelegateChoice> *p, DelegateChoic
dc->choices_.append(c); dc->choices_.append(c);
} }
int qsizetype
DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p) DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p)
{ {
return static_cast<DelegateChooser *>(p->object)->choices_.count(); return static_cast<DelegateChooser *>(p->object)->choices_.count();
} }
DelegateChoice * DelegateChoice *
DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, int index) DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, qsizetype index)
{ {
return static_cast<DelegateChooser *>(p->object)->choices_.at(index); return static_cast<DelegateChooser *>(p->object)->choices_.at(index);
} }

@ -86,7 +86,7 @@ private:
DelegateIncubator incubator{*this}; DelegateIncubator incubator{*this};
static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *); static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *);
static int choiceCount(QQmlListProperty<DelegateChoice> *); static qsizetype choiceCount(QQmlListProperty<DelegateChoice> *);
static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, int index); static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, qsizetype index);
static void clearChoices(QQmlListProperty<DelegateChoice> *); static void clearChoices(QQmlListProperty<DelegateChoice> *);
}; };

@ -15,11 +15,9 @@
#include "EventAccessors.h" #include "EventAccessors.h"
#include "Logging.h" #include "Logging.h"
#include "MatrixClient.h" #include "MatrixClient.h"
#include "TimelineModel.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
#include "Utils.h" #include "Utils.h"
Q_DECLARE_METATYPE(Reaction)
QCache<EventStore::IdIndex, olm::DecryptionResult> EventStore::decryptedEvents_{1000}; QCache<EventStore::IdIndex, olm::DecryptionResult> EventStore::decryptedEvents_{1000};
QCache<EventStore::IdIndex, mtx::events::collections::TimelineEvents> EventStore::events_by_id_{ QCache<EventStore::IdIndex, mtx::events::collections::TimelineEvents> EventStore::events_by_id_{
@ -29,8 +27,6 @@ QCache<EventStore::Index, mtx::events::collections::TimelineEvents> EventStore::
EventStore::EventStore(std::string room_id, QObject *) EventStore::EventStore(std::string room_id, QObject *)
: room_id_(std::move(room_id)) : room_id_(std::move(room_id))
{ {
static auto reactionType = qRegisterMetaType<Reaction>();
(void)reactionType;
auto range = cache::client()->getTimelineRange(room_id_); auto range = cache::client()->getTimelineRange(room_id_);
@ -293,12 +289,12 @@ EventStore::EventStore(std::string room_id, QObject *)
} }
void void
EventStore::addPending(mtx::events::collections::TimelineEvents event) EventStore::addPending(const mtx::events::collections::TimelineEvents& event)
{ {
if (this->thread() != QThread::currentThread()) if (this->thread() != QThread::currentThread())
nhlog::db()->warn("{} called from a different thread!", __func__); nhlog::db()->warn("{} called from a different thread!", __func__);
cache::client()->savePendingMessage(this->room_id_, {event}); cache::client()->savePendingMessage(this->room_id_, event);
mtx::responses::Timeline events; mtx::responses::Timeline events;
events.limited = false; events.limited = false;
events.events.emplace_back(event); events.events.emplace_back(event);
@ -761,11 +757,11 @@ EventStore::decryptEvent(const IdIndex &idx,
} }
void void
EventStore::refetchOnlineKeyBackupKeys(TimelineModel *room) EventStore::refetchOnlineKeyBackupKeys()
{ {
for (const auto &[session_id, request] : room->events.pending_key_requests) { for (const auto &[session_id, request] : this->pending_key_requests) {
(void)request; (void)request;
olm::lookup_keybackup(room->events.room_id_, session_id); olm::lookup_keybackup(this->room_id_, session_id);
} }
} }

@ -14,12 +14,11 @@
#include <mtx/events/collections.hpp> #include <mtx/events/collections.hpp>
#include <mtx/responses/messages.hpp> #include <mtx/responses/messages.hpp>
#include <mtx/responses/sync.hpp> #include <mtx/responses/sync.hpp>
#include <mtx/common.hpp>
#include "Reaction.h" #include "Reaction.h"
#include "encryption/Olm.h" #include "encryption/Olm.h"
class TimelineModel;
class EventStore final : public QObject class EventStore final : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -27,7 +26,7 @@ class EventStore final : public QObject
public: public:
EventStore(std::string room_id, QObject *parent); EventStore(std::string room_id, QObject *parent);
static void refetchOnlineKeyBackupKeys(TimelineModel *room); void refetchOnlineKeyBackupKeys();
// taken from QtPrivate::QHashCombine // taken from QtPrivate::QHashCombine
static uint hashCombine(uint hash, uint seed) static uint hashCombine(uint hash, uint seed)
@ -108,7 +107,7 @@ signals:
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo); void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
void eventFetched(std::string id, void eventFetched(std::string id,
std::string relatedTo, std::string relatedTo,
mtx::events::collections::TimelineEvents timeline); const mtx::events::collections::TimelineEvents& timeline);
void oldMessagesRetrieved(const mtx::responses::Messages &); void oldMessagesRetrieved(const mtx::responses::Messages &);
void fetchedMore(); void fetchedMore();
@ -120,7 +119,7 @@ signals:
void updateFlowEventId(std::string event_id); void updateFlowEventId(std::string event_id);
public slots: public slots:
void addPending(mtx::events::collections::TimelineEvents event); void addPending(const mtx::events::collections::TimelineEvents& event);
void receivedSessionKey(const std::string &session_id); void receivedSessionKey(const std::string &session_id);
void clearTimeline(); void clearTimeline();
void enableKeyRequests(bool suppressKeyRequests_); void enableKeyRequests(bool suppressKeyRequests_);

@ -16,6 +16,8 @@
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTextBoundaryFinder> #include <QTextBoundaryFinder>
#include <QVideoFrame>
#include <QVideoSink>
#include <QRegularExpression> #include <QRegularExpression>
#include <mtx/responses/common.hpp> #include <mtx/responses/common.hpp>
@ -74,55 +76,6 @@ MediaUpload::thumbnailDataUrl() const
return QString("data:image/png;base64,") + base64; return QString("data:image/png;base64,") + base64;
} }
bool
InputVideoSurface::present(const QVideoFrame &frame)
{
QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat());
if (format == QImage::Format_Invalid) {
emit newImage({});
return false;
} else {
QVideoFrame frametodraw(frame);
if (!frametodraw.map(QAbstractVideoBuffer::ReadOnly)) {
emit newImage({});
return false;
}
// this is a shallow operation. it just refer the frame buffer
QImage image(qAsConst(frametodraw).bits(),
frametodraw.width(),
frametodraw.height(),
frametodraw.bytesPerLine(),
format);
image.detach();
frametodraw.unmap();
emit newImage(std::move(image));
return true;
}
}
QList<QVideoFrame::PixelFormat>
InputVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
{
if (type == QAbstractVideoBuffer::NoHandle) {
return {
QVideoFrame::Format_ARGB32,
QVideoFrame::Format_ARGB32_Premultiplied,
QVideoFrame::Format_RGB24,
QVideoFrame::Format_BGR24,
QVideoFrame::Format_RGB32,
QVideoFrame::Format_RGB565,
QVideoFrame::Format_RGB555,
};
} else {
return {};
}
}
bool bool
InputBar::tryPasteAttachment(bool fromMouse) InputBar::tryPasteAttachment(bool fromMouse)
{ {
@ -536,7 +489,7 @@ InputBar::message(const QString &msg, MarkdownOverride useMarkdown, bool rainbow
if (!related.quoted_user.startsWith("@room:")) { if (!related.quoted_user.startsWith("@room:")) {
QString body; QString body;
bool firstLine = true; bool firstLine = true;
auto lines = related.quoted_body.splitRef(u'\n'); auto lines = QStringView(related.quoted_body).split(u'\n');
for (auto line : qAsConst(lines)) { for (auto line : qAsConst(lines)) {
if (firstLine) { if (firstLine) {
firstLine = false; firstLine = false;
@ -1036,21 +989,20 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_,
blurhash_ = blurhash_ =
QString::fromStdString(blurhash::encode(data_.data(), img.width(), img.height(), 4, 3)); QString::fromStdString(blurhash::encode(data_.data(), img.width(), img.height(), 4, 3));
} else if (mimeClass_ == u"video" || mimeClass_ == u"audio") { } else if (mimeClass_ == u"video" || mimeClass_ == u"audio") {
auto mediaPlayer = new QMediaPlayer( auto mediaPlayer = new QMediaPlayer( this);
this, mediaPlayer->setAudioOutput(nullptr);
mimeClass_ == u"video" ? QFlags{QMediaPlayer::VideoSurface} : QMediaPlayer::Flags{});
mediaPlayer->setMuted(true);
if (mimeClass_ == u"video") { if (mimeClass_ == u"video") {
auto newSurface = new InputVideoSurface(this); auto newSurface = new QVideoSink(this);
connect( connect(
newSurface, &InputVideoSurface::newImage, this, [this, mediaPlayer](QImage img) { newSurface, &QVideoSink::videoFrameChanged, this, [this, mediaPlayer](const QVideoFrame& frame) {
QImage img = frame.toImage();
if (img.size().isEmpty()) if (img.size().isEmpty())
return; return;
mediaPlayer->stop(); mediaPlayer->stop();
auto orientation = mediaPlayer->metaData(QMediaMetaData::Orientation).toInt(); auto orientation = mediaPlayer->metaData().value(QMediaMetaData::Orientation).toInt();
if (orientation == 90 || orientation == 270 || orientation == 180) { if (orientation == 90 || orientation == 270 || orientation == 180) {
img = img =
img.transformed(QTransform().rotate(orientation), Qt::SmoothTransformation); img.transformed(QTransform().rotate(orientation), Qt::SmoothTransformation);
@ -1081,11 +1033,11 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_,
} }
connect(mediaPlayer, connect(mediaPlayer,
qOverload<QMediaPlayer::Error>(&QMediaPlayer::error), &QMediaPlayer::error,
this, this,
[mediaPlayer](QMediaPlayer::Error error) { [mediaPlayer]() {
nhlog::ui()->debug("Media player error {} and errorStr {}", nhlog::ui()->debug("Media player error {} and errorStr {}",
error, mediaPlayer->error(),
mediaPlayer->errorString().toStdString()); mediaPlayer->errorString().toStdString());
}); });
connect(mediaPlayer, connect(mediaPlayer,
@ -1095,19 +1047,19 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_,
"Media player status {} and error {}", status, mediaPlayer->error()); "Media player status {} and error {}", status, mediaPlayer->error());
}); });
connect(mediaPlayer, connect(mediaPlayer,
qOverload<const QString &, const QVariant &>(&QMediaPlayer::metaDataChanged), &QMediaPlayer::metaDataChanged,
this, this,
[this, mediaPlayer](const QString &t, const QVariant &) { [this, mediaPlayer]() {
nhlog::ui()->debug("Got metadata {}", t.toStdString()); nhlog::ui()->debug("Got metadata {}");
if (mediaPlayer->duration() > 0) if (mediaPlayer->duration() > 0)
this->duration_ = mediaPlayer->duration(); this->duration_ = mediaPlayer->duration();
auto dimensions = mediaPlayer->metaData(QMediaMetaData::Resolution).toSize(); auto dimensions = mediaPlayer->metaData().value(QMediaMetaData::Resolution).toSize();
if (!dimensions.isEmpty()) { if (!dimensions.isEmpty()) {
dimensions_ = dimensions; dimensions_ = dimensions;
auto orientation = auto orientation =
mediaPlayer->metaData(QMediaMetaData::Orientation).toInt(); mediaPlayer->metaData().value(QMediaMetaData::Orientation).toInt();
if (orientation == 90 || orientation == 270) { if (orientation == 90 || orientation == 270) {
dimensions_.transpose(); dimensions_.transpose();
} }
@ -1125,8 +1077,8 @@ MediaUpload::MediaUpload(std::unique_ptr<QIODevice> source_,
auto originalFile = qobject_cast<QFile *>(source.get()); auto originalFile = qobject_cast<QFile *>(source.get());
mediaPlayer->setMedia( mediaPlayer->setSourceDevice(source.get(),
QMediaContent(originalFile ? originalFile->fileName() : originalFilename_), source.get()); QUrl(originalFile ? originalFile->fileName() : originalFilename_));
mediaPlayer->play(); mediaPlayer->play();
} }

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <QAbstractVideoSurface>
#include <QIODevice> #include <QIODevice>
#include <QImage> #include <QImage>
#include <QObject> #include <QObject>
@ -41,25 +40,6 @@ enum class MarkdownOverride
CMARK, CMARK,
}; };
class InputVideoSurface final : public QAbstractVideoSurface
{
Q_OBJECT
public:
InputVideoSurface(QObject *parent)
: QAbstractVideoSurface(parent)
{
}
bool present(const QVideoFrame &frame) override;
QList<QVideoFrame::PixelFormat>
supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override;
signals:
void newImage(QImage img);
};
class MediaUpload final : public QObject class MediaUpload final : public QObject
{ {
Q_OBJECT Q_OBJECT

@ -28,7 +28,6 @@ RoomlistModel::RoomlistModel(TimelineViewManager *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, manager(parent) , manager(parent)
{ {
[[maybe_unused]] static auto id = qRegisterMetaType<RoomPreview>();
connect(ChatPage::instance(), &ChatPage::decryptSidebarChanged, this, [this]() { connect(ChatPage::instance(), &ChatPage::decryptSidebarChanged, this, [this]() {
auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar(); auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar();
@ -819,7 +818,7 @@ RoomlistModel::refetchOnlineKeyBackupKeys()
auto ptr = i.value(); auto ptr = i.value();
if (!ptr.isNull()) { if (!ptr.isNull()) {
EventStore::refetchOnlineKeyBackupKeys(ptr.data()); ptr->refetchOnlineKeyBackupKeys();
} }
} }
} }

@ -31,7 +31,6 @@
#include "Utils.h" #include "Utils.h"
#include "encryption/Olm.h" #include "encryption/Olm.h"
Q_DECLARE_METATYPE(QModelIndex)
namespace std { namespace std {
inline uint // clazy:exclude=qhash-namespace inline uint // clazy:exclude=qhash-namespace

@ -374,6 +374,8 @@ public:
return std::nullopt; return std::nullopt;
} }
void refetchOnlineKeyBackupKeys() { events.refetchOnlineKeyBackupKeys(); };
public slots: public slots:
void setCurrentIndex(int index); void setCurrentIndex(int index);
int currentIndex() const { return idToIndex(currentId); } int currentIndex() const { return idToIndex(currentId); }
@ -537,8 +539,6 @@ private:
std::unique_ptr<RoomSummary, DeleteLaterDeleter> parentSummary = nullptr; std::unique_ptr<RoomSummary, DeleteLaterDeleter> parentSummary = nullptr;
bool parentChecked = false; bool parentChecked = false;
friend void EventStore::refetchOnlineKeyBackupKeys(TimelineModel *room);
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(TimelineModel::SpecialEffects) Q_DECLARE_OPERATORS_FOR_FLAGS(TimelineModel::SpecialEffects)

@ -280,7 +280,7 @@ TimelineViewManager::saveMedia(QString mxcUrl)
{ {
const QString downloadsFolder = const QString downloadsFolder =
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
const QString openLocation = downloadsFolder + "/" + mxcUrl.splitRef(u'/').constLast(); const QString openLocation = downloadsFolder + "/" + mxcUrl.split(u'/').constLast();
const QString filename = QFileDialog::getSaveFileName(nullptr, {}, openLocation); const QString filename = QFileDialog::getSaveFileName(nullptr, {}, openLocation);

@ -131,11 +131,3 @@ private:
QHash<QPair<QString, quint64>, QColor> userColors; QHash<QPair<QString, quint64>, QColor> userColors;
}; };
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationAccept)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationCancel)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationDone)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationKey)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationMac)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationReady)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationRequest)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationStart)

@ -152,9 +152,9 @@ MxcAnimatedImage::startDownload()
} }
void void
MxcAnimatedImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) MxcAnimatedImage::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{ {
QQuickItem::geometryChanged(newGeometry, oldGeometry); QQuickItem::geometryChange(newGeometry, oldGeometry);
if (newGeometry.size() != oldGeometry.size()) { if (newGeometry.size() != oldGeometry.size()) {
if (height() != 0 && width() != 0) { if (height() != 0 && width() != 0) {

@ -59,7 +59,7 @@ public:
} }
} }
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
QSGNode *updatePaintNode(QSGNode *oldNode, QSGNode *updatePaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;

@ -8,17 +8,11 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QMediaMetaData> #include <QMediaMetaData>
#include <QMediaObject>
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QStandardPaths> #include <QStandardPaths>
#include <QUrl> #include <QUrl>
#if defined(Q_OS_MACOS)
// TODO (red_sky): Remove for Qt6. See other ifdef below
#include <QTemporaryFile>
#endif
#include "ChatPage.h" #include "ChatPage.h"
#include "EventAccessors.h" #include "EventAccessors.h"
#include "Logging.h" #include "Logging.h"
@ -32,19 +26,18 @@ MxcMediaProxy::MxcMediaProxy(QObject *parent)
connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload); connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload);
connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload); connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload);
connect(this, connect(this,
qOverload<QMediaPlayer::Error>(&MxcMediaProxy::error), &MxcMediaProxy::error,
[this](QMediaPlayer::Error error) { [this]() {
nhlog::ui()->info("Media player error {} and errorStr {}", nhlog::ui()->info("Media player error {} and errorStr {}",
error, error(),
this->errorString().toStdString()); this->errorString().toStdString());
}); });
connect(this, &MxcMediaProxy::mediaStatusChanged, [this](QMediaPlayer::MediaStatus status) { connect(this, &MxcMediaProxy::mediaStatusChanged, [this](QMediaPlayer::MediaStatus status) {
nhlog::ui()->info("Media player status {} and error {}", status, this->error()); nhlog::ui()->info("Media player status {} and error {}", status, this->error());
}); });
connect(this, connect(this,
qOverload<const QString &, const QVariant &>(&MxcMediaProxy::metaDataChanged), &MxcMediaProxy::metaDataChanged,
[this](const QString &t, const QVariant &) { [this]() {
if (t == QMediaMetaData::Orientation)
emit orientationChanged(); emit orientationChanged();
}); });
@ -53,28 +46,12 @@ MxcMediaProxy::MxcMediaProxy(QObject *parent)
this, this,
&MxcMediaProxy::pause); &MxcMediaProxy::pause);
} }
void
MxcMediaProxy::setVideoSurface(QAbstractVideoSurface *surface)
{
if (surface != m_surface) {
qDebug() << "Changing surface";
m_surface = surface;
setVideoOutput(m_surface);
emit videoSurfaceChanged();
}
}
QAbstractVideoSurface *
MxcMediaProxy::getVideoSurface()
{
return m_surface;
}
int int
MxcMediaProxy::orientation() const MxcMediaProxy::orientation() const
{ {
nhlog::ui()->debug("metadata: {}", availableMetaData().join(QStringLiteral(",")).toStdString()); //nhlog::ui()->debug("metadata: {}", availableMetaData().join(QStringLiteral(",")).toStdString());
auto orientation = metaData(QMediaMetaData::Orientation).toInt(); auto orientation = metaData().value(QMediaMetaData::Orientation).toInt();
nhlog::ui()->debug("Video orientation: {}", orientation); nhlog::ui()->debug("Video orientation: {}", orientation);
return orientation; return orientation;
} }
@ -135,34 +112,10 @@ MxcMediaProxy::startDownload()
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
buffer.reset(); buffer.reset();
QTimer::singleShot(0, this, [this, filename, suffix, encryptionInfo] { QTimer::singleShot(0, this, [this, filename] {
#if defined(Q_OS_MACOS)
if (encryptionInfo) {
// macOS has issues reading from a buffer in setMedia for whatever reason.
// Instead, write the buffer to a temporary file and read from that.
// This should be fixed in Qt6, so update this when we do that!
// TODO: REMOVE IN QT6
QTemporaryFile tempFile;
tempFile.setFileTemplate(tempFile.fileTemplate() + QLatin1Char('.') + suffix);
tempFile.open();
tempFile.write(buffer.data());
tempFile.close();
nhlog::ui()->debug("Playing media from temp buffer file: {}. Remove in QT6!",
filename.filePath().toStdString());
this->setMedia(QUrl::fromLocalFile(tempFile.fileName()));
} else {
nhlog::ui()->info(
"Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen());
this->setMedia(QUrl::fromLocalFile(filename.filePath()));
}
#else
Q_UNUSED(suffix)
Q_UNUSED(encryptionInfo)
nhlog::ui()->info( nhlog::ui()->info(
"Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen()); "Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen());
this->setMedia(QMediaContent(filename.fileName()), &buffer); this->setSourceDevice(&buffer, QUrl(filename.fileName()));
#endif
emit loadedChanged(); emit loadedChanged();
}); });
}; };

@ -4,9 +4,9 @@
#pragma once #pragma once
#include <QAbstractVideoSurface> #include <QVideoSink>
#include <QBuffer> #include <QBuffer>
#include <QMediaContent> #include <QUrl>
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QObject> #include <QObject>
#include <QPointer> #include <QPointer>
@ -23,8 +23,6 @@ class MxcMediaProxy : public QMediaPlayer
Q_OBJECT Q_OBJECT
Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED)
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
Q_PROPERTY(QAbstractVideoSurface *videoSurface READ getVideoSurface WRITE setVideoSurface NOTIFY
videoSurfaceChanged)
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged) Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged)
@ -44,16 +42,13 @@ public:
room_ = room; room_ = room;
emit roomChanged(); emit roomChanged();
} }
void setVideoSurface(QAbstractVideoSurface *surface);
QAbstractVideoSurface *getVideoSurface();
int orientation() const; int orientation() const;
signals: signals:
void roomChanged(); void roomChanged();
void eventIdChanged(); void eventIdChanged();
void loadedChanged(); void loadedChanged();
void newBuffer(QMediaContent, QIODevice *buf); void newBuffer(QUrl, QIODevice *buf);
void orientationChanged(); void orientationChanged();
void videoSurfaceChanged(); void videoSurfaceChanged();
@ -66,5 +61,5 @@ private:
QString eventId_; QString eventId_;
QString filename_; QString filename_;
QBuffer buffer; QBuffer buffer;
QAbstractVideoSurface *m_surface = nullptr; QObject *m_surface = nullptr;
}; };

@ -5,16 +5,12 @@
#include "NhekoGlobalObject.h" #include "NhekoGlobalObject.h"
#include <QApplication> #include <QApplication>
#include <QGuiApplication>
#include <QDesktopServices> #include <QDesktopServices>
#include <QStyle> #include <QStyle>
#include <QUrl> #include <QUrl>
#include <QWindow> #include <QWindow>
// for some reason that is not installed in our macOS env...
#ifndef Q_OS_MAC
#include <QtPlatformHeaders/QXcbWindowFunctions>
#endif
#include "Cache_p.h" #include "Cache_p.h"
#include "ChatPage.h" #include "ChatPage.h"
#include "Logging.h" #include "Logging.h"
@ -22,6 +18,8 @@
#include "Utils.h" #include "Utils.h"
#include "voip/WebRTCSession.h" #include "voip/WebRTCSession.h"
#include <xcb/xproto.h>
Nheko::Nheko() Nheko::Nheko()
{ {
connect( connect(
@ -186,7 +184,21 @@ Nheko::createRoom(bool space,
void void
Nheko::setWindowRole([[maybe_unused]] QWindow *win, [[maybe_unused]] QString newRole) const Nheko::setWindowRole([[maybe_unused]] QWindow *win, [[maybe_unused]] QString newRole) const
{ {
#ifndef Q_OS_MAC const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
QXcbWindowFunctions::setWmWindowRole(win, newRole.toUtf8());
#endif if (!x11Interface) return;
auto connection = x11Interface->connection();
auto role = newRole.toStdString();
char WM_WINDOW_ROLE[] = "WM_WINDOW_ROLE";
auto cookie = xcb_intern_atom(connection, false, std::size(WM_WINDOW_ROLE) - 1, WM_WINDOW_ROLE);
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, nullptr);
auto atom = reply ->atom;
free(reply);
xcb_change_property(connection, XCB_PROP_MODE_REPLACE, win->winId(),
atom, XCB_ATOM_STRING, 8,
role.size(), role.data());
} }

@ -4,12 +4,10 @@
#include "Theme.h" #include "Theme.h"
Q_DECLARE_METATYPE(Theme)
QPalette QPalette
Theme::paletteFromTheme(QStringView theme) Theme::paletteFromTheme(QStringView theme)
{ {
[[maybe_unused]] static auto meta = qRegisterMetaType<Theme>("Theme");
static QPalette original; static QPalette original;
if (theme == u"light") { if (theme == u"light") {
static QPalette lightActive = [] { static QPalette lightActive = [] {

@ -10,7 +10,6 @@
#include <memory> #include <memory>
#include <QGuiApplication> #include <QGuiApplication>
#include <QMediaPlaylist>
#include <QUrl> #include <QUrl>
#include "Cache.h" #include "Cache.h"
@ -42,9 +41,6 @@ extern "C"
} }
#endif #endif
Q_DECLARE_METATYPE(std::vector<mtx::events::voip::CallCandidates::Candidate>)
Q_DECLARE_METATYPE(mtx::events::voip::CallCandidates::Candidate)
Q_DECLARE_METATYPE(mtx::responses::TurnServer)
using namespace mtx::events; using namespace mtx::events;
using namespace mtx::events::voip; using namespace mtx::events::voip;
@ -64,9 +60,6 @@ CallManager::CallManager(QObject *parent)
, session_(WebRTCSession::instance()) , session_(WebRTCSession::instance())
, turnServerTimer_(this) , turnServerTimer_(this)
{ {
qRegisterMetaType<std::vector<mtx::events::voip::CallCandidates::Candidate>>();
qRegisterMetaType<mtx::events::voip::CallCandidates::Candidate>();
qRegisterMetaType<mtx::responses::TurnServer>();
#ifdef GSTREAMER_AVAILABLE #ifdef GSTREAMER_AVAILABLE
std::string errorMessage; std::string errorMessage;
@ -180,11 +173,11 @@ CallManager::CallManager(QObject *parent)
}); });
connect(&player_, connect(&player_,
QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error), &QMediaPlayer::error,
this, this,
[this](QMediaPlayer::Error error) { [this]() {
stopRingtone(); stopRingtone();
switch (error) { switch (player_.error()) {
case QMediaPlayer::FormatError: case QMediaPlayer::FormatError:
case QMediaPlayer::ResourceError: case QMediaPlayer::ResourceError:
nhlog::ui()->error("WebRTC: valid ringtone file not found"); nhlog::ui()->error("WebRTC: valid ringtone file not found");
@ -827,19 +820,17 @@ CallManager::retrieveTurnServer()
void void
CallManager::playRingtone(const QUrl &ringtone, bool repeat) CallManager::playRingtone(const QUrl &ringtone, bool repeat)
{ {
static QMediaPlaylist playlist; player_.setLoops(repeat ? QMediaPlayer::Infinite :
playlist.clear(); 1);
playlist.setPlaybackMode(repeat ? QMediaPlaylist::CurrentItemInLoop player_.setSource(ringtone);
: QMediaPlaylist::CurrentItemOnce); //player_.audioOutput()->setVolume(100);
playlist.addMedia(ringtone); player_.play();
player_.setVolume(100);
player_.setPlaylist(&playlist);
} }
void void
CallManager::stopRingtone() CallManager::stopRingtone()
{ {
player_.setPlaylist(nullptr); player_.stop();
} }
bool bool

@ -438,7 +438,6 @@ struct PipeWireStream
QVariantMap map; QVariantMap map;
}; };
Q_DECLARE_METATYPE(PipeWireStream)
const QDBusArgument & const QDBusArgument &
operator>>(const QDBusArgument &argument, PipeWireStream &stream) operator>>(const QDBusArgument &argument, PipeWireStream &stream)

@ -41,9 +41,6 @@ extern "C"
// https://github.com/vector-im/riot-web/issues/10173 // https://github.com/vector-im/riot-web/issues/10173
#define STUN_SERVER "stun://turn.matrix.org:3478" #define STUN_SERVER "stun://turn.matrix.org:3478"
Q_DECLARE_METATYPE(webrtc::CallType)
Q_DECLARE_METATYPE(webrtc::ScreenShareType)
Q_DECLARE_METATYPE(webrtc::State)
using webrtc::CallType; using webrtc::CallType;
using webrtc::ScreenShareType; using webrtc::ScreenShareType;
@ -52,7 +49,6 @@ using webrtc::State;
WebRTCSession::WebRTCSession() WebRTCSession::WebRTCSession()
: devices_(CallDevices::instance()) : devices_(CallDevices::instance())
{ {
qRegisterMetaType<webrtc::CallType>();
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko", "im.nheko",
1, 1,
@ -60,7 +56,6 @@ WebRTCSession::WebRTCSession()
"CallType", "CallType",
QStringLiteral("Can't instantiate enum")); QStringLiteral("Can't instantiate enum"));
qRegisterMetaType<webrtc::ScreenShareType>();
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko", "im.nheko",
1, 1,
@ -68,7 +63,6 @@ WebRTCSession::WebRTCSession()
"ScreenShareType", "ScreenShareType",
QStringLiteral("Can't instantiate enum")); QStringLiteral("Can't instantiate enum"));
qRegisterMetaType<webrtc::State>();
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko", "im.nheko",
1, 1,

Loading…
Cancel
Save