diff --git a/src/core/micamaterial.cpp b/src/core/micamaterial.cpp index 22bcf63d..558aeec2 100644 --- a/src/core/micamaterial.cpp +++ b/src/core/micamaterial.cpp @@ -27,6 +27,13 @@ #if FRAMELESSHELPER_CONFIG(mica_material) +#if QT_CONFIG(thread) +# define FRAMELESSHELPER_HAS_THREAD + using FramelessHelperThreadClass = QThread; +#else + using FramelessHelperThreadClass = QObject; +#endif + #include "framelessmanager.h" #include "utils.h" #include "framelessconfig_p.h" @@ -35,8 +42,10 @@ #include #include #include -#include -#include +#ifdef FRAMELESSHELPER_HAS_THREAD +# include +# include +#endif #include #include #include @@ -80,7 +89,9 @@ struct ImageData { QPixmap blurredWallpaper = {}; bool graphicsResourcesReady = false; +#ifdef FRAMELESSHELPER_HAS_THREAD QMutex mutex{}; +#endif }; Q_GLOBAL_STATIC(ImageData, g_imageData) @@ -479,20 +490,25 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality return {x, y, w, h}; } -class WallpaperThread : public QThread +class WallpaperThread : public FramelessHelperThreadClass { Q_OBJECT FRAMELESSHELPER_QT_CLASS(WallpaperThread) public: - explicit WallpaperThread(QObject *parent = nullptr) : QThread(parent) {} + explicit WallpaperThread(QObject *parent = nullptr) : FramelessHelperThreadClass(parent) {} ~WallpaperThread() override = default; Q_SIGNALS: void imageUpdated(); +#ifdef FRAMELESSHELPER_HAS_THREAD protected: void run() override +#else +public: + void start() +#endif { const QString wallpaperFilePath = Utils::getWallpaperFilePath(); if (wallpaperFilePath.isEmpty()) { @@ -565,7 +581,9 @@ class WallpaperThread : public QThread bufferPainter.drawImage(rect.topLeft(), image); } { +#ifdef FRAMELESSHELPER_HAS_THREAD const QMutexLocker locker(&g_imageData()->mutex); +#endif g_imageData()->blurredWallpaper = QPixmap(wallpaperSize); g_imageData()->blurredWallpaper.fill(kDefaultTransparentColor); QPainter painter(&g_imageData()->blurredWallpaper); @@ -586,11 +604,13 @@ class WallpaperThread : public QThread struct ThreadData { std::unique_ptr thread = nullptr; +#ifdef FRAMELESSHELPER_HAS_THREAD QMutex mutex{}; +#endif }; - Q_GLOBAL_STATIC(ThreadData, g_threadData) +#ifdef FRAMELESSHELPER_HAS_THREAD static inline void threadCleaner() { const QMutexLocker locker(&g_threadData()->mutex); @@ -600,6 +620,7 @@ static inline void threadCleaner() g_threadData()->thread->wait(); } } +#endif MicaMaterialPrivate::MicaMaterialPrivate(MicaMaterial *q) : QObject(q) { @@ -633,11 +654,16 @@ const MicaMaterialPrivate *MicaMaterialPrivate::get(const MicaMaterial *q) void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force) { +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.lock(); +#endif if (!g_imageData()->blurredWallpaper.isNull() && !force) { +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); +#endif return; } +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); const QMutexLocker locker(&g_threadData()->mutex); if (g_threadData()->thread->isRunning()) { @@ -646,6 +672,9 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force) g_threadData()->thread->wait(); } g_threadData()->thread->start(QThread::LowPriority); +#else + g_threadData()->thread->start(); +#endif } void MicaMaterialPrivate::updateMaterialBrush() @@ -685,10 +714,14 @@ void MicaMaterialPrivate::forceRebuildWallpaper() void MicaMaterialPrivate::initialize() { +#ifdef FRAMELESSHELPER_HAS_THREAD g_threadData()->mutex.lock(); +#endif if (!g_threadData()->thread) { g_threadData()->thread = std::make_unique(); +#ifdef FRAMELESSHELPER_HAS_THREAD qAddPostRoutine(threadCleaner); +#endif } connect(g_threadData()->thread.get(), &WallpaperThread::imageUpdated, this, [this](){ if (initialized) { @@ -696,7 +729,9 @@ void MicaMaterialPrivate::initialize() Q_EMIT q->shouldRedraw(); } }); +#ifdef FRAMELESSHELPER_HAS_THREAD g_threadData()->mutex.unlock(); +#endif wallpaperSize = QGuiApplication::primaryScreen()->size(); @@ -724,13 +759,19 @@ void MicaMaterialPrivate::initialize() void MicaMaterialPrivate::prepareGraphicsResources() { +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.lock(); +#endif if (g_imageData()->graphicsResourcesReady) { +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); +#endif return; } g_imageData()->graphicsResourcesReady = true; +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); +#endif maybeGenerateBlurredWallpaper(); } @@ -911,25 +952,35 @@ void MicaMaterial::paint(QPainter *painter, const QRect &rect, const bool active painter->setRenderHint(QPainter::SmoothPixmapTransform, false); if (active) { const QRect intersectedRect = wallpaperRect.intersected(mappedRect); +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.lock(); +#endif painter->drawPixmap(originPoint, g_imageData()->blurredWallpaper, intersectedRect); +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); +#endif if (intersectedRect != mappedRect) { static constexpr const auto xOffset = QPoint{ 1, 0 }; if (mappedRect.y() + mappedRect.height() <= wallpaperRect.height()) { const QRect outerRect = { intersectedRect.topRight() + xOffset, QSize{ mappedRect.width() - intersectedRect.width(), intersectedRect.height() } }; const QPoint outerRectOriginPoint = originPoint + QPoint{ intersectedRect.width(), 0 } + xOffset; const QRect mappedOuterRect = d->mapToWallpaper(outerRect); +#ifdef FRAMELESSHELPER_HAS_THREAD const QMutexLocker locker(&g_imageData()->mutex); +#endif painter->drawPixmap(outerRectOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRect); } else { static constexpr const auto yOffset = QPoint{ 0, 1 }; const QRect outerRectBottom = { intersectedRect.bottomLeft() + yOffset, QSize{ intersectedRect.width(), mappedRect.height() - intersectedRect.height() } }; const QPoint outerRectBottomOriginPoint = originPoint + QPoint{ 0, intersectedRect.height() } + yOffset; const QRect mappedOuterRectBottom = d->mapToWallpaper(outerRectBottom); +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.lock(); +#endif painter->drawPixmap(outerRectBottomOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectBottom); +#ifdef FRAMELESSHELPER_HAS_THREAD g_imageData()->mutex.unlock(); +#endif if (mappedRect.x() + mappedRect.width() > wallpaperRect.width()) { const QRect outerRectRight = { intersectedRect.topRight() + xOffset, QSize{ mappedRect.width() - intersectedRect.width(), intersectedRect.height() } }; const QPoint outerRectRightOriginPoint = originPoint + QPoint{ intersectedRect.width(), 0 } + xOffset; @@ -937,7 +988,9 @@ void MicaMaterial::paint(QPainter *painter, const QRect &rect, const bool active const QRect outerRectCorner = { intersectedRect.bottomRight() + xOffset + yOffset, QSize{ outerRectRight.width(), outerRectBottom.height() } }; const QPoint outerRectCornerOriginPoint = originPoint + QPoint{ intersectedRect.width(), intersectedRect.height() } + xOffset + yOffset; const QRect mappedOuterRectCorner = d->mapToWallpaper(outerRectCorner); +#ifdef FRAMELESSHELPER_HAS_THREAD const QMutexLocker locker(&g_imageData()->mutex); +#endif painter->drawPixmap(outerRectRightOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectRight); painter->drawPixmap(outerRectCornerOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectCorner); }