Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
mica material: fix multi monitor scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
wangwenx190 committed Aug 7, 2023
1 parent 8d3ef93 commit 177e377
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 204 deletions.
14 changes: 1 addition & 13 deletions include/FramelessHelper/Quick/private/quickmicamaterial_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,10 @@

#include <FramelessHelper/Quick/framelesshelperquick_global.h>

QT_BEGIN_NAMESPACE
class QQuickRectangle;
QT_END_NAMESPACE

FRAMELESSHELPER_BEGIN_NAMESPACE

class MicaMaterial;
class QuickMicaMaterial;
class WallpaperImageNode;

class FRAMELESSHELPER_QUICK_API QuickMicaMaterialPrivate : public QObject
{
Expand All @@ -51,23 +46,16 @@ class FRAMELESSHELPER_QUICK_API QuickMicaMaterialPrivate : public QObject

public Q_SLOTS:
void rebindWindow();
void forceRegenerateWallpaperImageCache();
void appendNode(WallpaperImageNode *node);
void removeNode(WallpaperImageNode *node);
void updateFallbackColor();
void repaint(QPainter *painter);

private:
void initialize();

private:
friend class WallpaperImageNode;

QuickMicaMaterial *q_ptr = nullptr;
QMetaObject::Connection m_rootWindowXChangedConnection = {};
QMetaObject::Connection m_rootWindowYChangedConnection = {};
QMetaObject::Connection m_rootWindowActiveChangedConnection = {};
QList<QPointer<WallpaperImageNode>> m_nodes = {};
QQuickRectangle *m_fallbackColorItem = nullptr;
MicaMaterial *m_micaMaterial = nullptr;
};

Expand Down
7 changes: 4 additions & 3 deletions include/FramelessHelper/Quick/quickmicamaterial.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
#pragma once

#include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickpainteditem.h>

FRAMELESSHELPER_BEGIN_NAMESPACE

class QuickMicaMaterialPrivate;

class FRAMELESSHELPER_QUICK_API QuickMicaMaterial : public QQuickItem
class FRAMELESSHELPER_QUICK_API QuickMicaMaterial : public QQuickPaintedItem
{
Q_OBJECT
#ifdef QML_NAMED_ELEMENT
Expand All @@ -50,6 +50,8 @@ class FRAMELESSHELPER_QUICK_API QuickMicaMaterial : public QQuickItem
explicit QuickMicaMaterial(QQuickItem *parent = nullptr);
~QuickMicaMaterial() override;

void paint(QPainter *painter) override;

Q_NODISCARD QColor tintColor() const;
void setTintColor(const QColor &value);

Expand All @@ -74,7 +76,6 @@ class FRAMELESSHELPER_QUICK_API QuickMicaMaterial : public QQuickItem

protected:
void itemChange(const ItemChange change, const ItemChangeData &value) override;
[[nodiscard]] QSGNode *updatePaintNode(QSGNode *old, UpdatePaintNodeData *data) override;
void classBegin() override;
void componentComplete() override;

Expand Down
49 changes: 37 additions & 12 deletions src/core/micamaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,15 +704,47 @@ void MicaMaterialPrivate::paint(QPainter *painter, const QRect &rect, const bool
}
prepareGraphicsResources();
static constexpr const QPoint originPoint = {0, 0};
const QRect wallpaperRect = { originPoint, wallpaperSize() };
const QRect mappedRect = mapToWallpaper(rect);
painter->save();
// Same as above. Speed is more important here.
painter->setRenderHint(QPainter::Antialiasing, false);
painter->setRenderHint(QPainter::TextAntialiasing, false);
painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
if (active) {
const QMutexLocker locker(&g_imageData()->mutex);
painter->drawPixmap(originPoint, g_imageData()->blurredWallpaper, mappedRect);
const QRect intersectedRect = wallpaperRect.intersected(mappedRect);
g_imageData()->mutex.lock();
painter->drawPixmap(originPoint, g_imageData()->blurredWallpaper, intersectedRect);
g_imageData()->mutex.unlock();
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 = mapToWallpaper(outerRect);
const QMutexLocker locker(&g_imageData()->mutex);
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 = mapToWallpaper(outerRectBottom);
g_imageData()->mutex.lock();
painter->drawPixmap(outerRectBottomOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectBottom);
g_imageData()->mutex.unlock();
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;
const QRect mappedOuterRectRight = mapToWallpaper(outerRectRight);
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 = mapToWallpaper(outerRectCorner);
const QMutexLocker locker(&g_imageData()->mutex);
painter->drawPixmap(outerRectRightOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectRight);
painter->drawPixmap(outerRectCornerOriginPoint, g_imageData()->blurredWallpaper, mappedOuterRectCorner);
}
}
}
}
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->setOpacity(qreal(1));
Expand Down Expand Up @@ -854,13 +886,13 @@ QPoint MicaMaterialPrivate::mapToWallpaper(const QPoint &pos) const
while (result.x() < qreal(0)) {
result.setX(result.x() + imageSize.width());
}
while (result.x() > imageSize.width()) {
while ((result.x() > imageSize.width()) || qFuzzyCompare(result.x(), imageSize.width())) {
result.setX(result.x() - imageSize.width());
}
while (result.y() < qreal(0)) {
result.setY(result.y() + imageSize.height());
}
while (result.y() > imageSize.height()) {
while ((result.y() > imageSize.height()) || qFuzzyCompare(result.y(), imageSize.height())) {
result.setY(result.y() - imageSize.height());
}
return result.toPoint();
Expand Down Expand Up @@ -899,14 +931,7 @@ QRect MicaMaterialPrivate::mapToWallpaper(const QRect &rect) const
WARNING << "The calculated mapped rectangle is not valid.";
return wallpaperRect.toRect();
}
// Make sure we don't get something outside of the wallpaper area.
const QRectF intersectedRect = wallpaperRect.intersected(mappedRect);
// OK, the two rectangles are not intersected, just draw the whole wallpaper.
if (!Utils::isValidGeometry(intersectedRect)) {
WARNING << "The mapped rectangle and the wallpaper rectangle are not intersected.";
return wallpaperRect.toRect();
}
return intersectedRect.toRect();
return mappedRect.toRect();
}

MicaMaterial::MicaMaterial(QObject *parent)
Expand Down
Loading

0 comments on commit 177e377

Please sign in to comment.