mica material: minor fixes of previous implementation

This commit is contained in:
Yuhang Zhao 2023-07-02 11:44:54 +08:00
parent 7c0d8c4b11
commit 617a015b97
8 changed files with 79 additions and 40 deletions

View File

@ -39,16 +39,23 @@ Dialog::~Dialog() = default;
void Dialog::closeEvent(QCloseEvent *event)
{
if (!parent()) {
Settings::set({}, kGeometry, geometry());
Settings::set({}, kDevicePixelRatio, devicePixelRatioF());
const QString id = objectName();
Settings::set(id, kGeometry, geometry());
Settings::set(id, kDevicePixelRatio, devicePixelRatioF());
}
FramelessDialog::closeEvent(event);
}
void Dialog::setupUi()
{
setWindowTitle(tr("Qt Dialog demo"));
setWindowTitle(tr("FramelessHelper demo application - QDialog"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(this, &Dialog::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
titleBar = new StandardTitleBar(this);
titleBar->setWindowIconVisible(true);
@ -142,9 +149,10 @@ void Dialog::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
const QString id = objectName();
const auto savedGeometry = Settings::get<QRect>(id, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
const auto savedDpr = Settings::get<qreal>(id, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);

View File

@ -29,6 +29,12 @@
FRAMELESSHELPER_USE_NAMESPACE
#define CREATE_WINDOW(Name) \
const auto Name = std::make_unique<Dialog>(); \
Name->setObjectName(FRAMELESSHELPER_STRING_LITERAL(#Name)); \
Name->waitReady(); \
Name->show();
int main(int argc, char *argv[])
{
Log::setup(FRAMELESSHELPER_STRING_LITERAL("dialog"));
@ -51,11 +57,11 @@ int main(int argc, char *argv[])
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const auto dialog = std::make_unique<Dialog>();
dialog->waitReady();
dialog->show();
CREATE_WINDOW(dialog1)
CREATE_WINDOW(dialog2)
CREATE_WINDOW(dialog3)
return QCoreApplication::exec();
}

View File

@ -29,6 +29,12 @@
FRAMELESSHELPER_USE_NAMESPACE
#define CREATE_WINDOW(Name) \
const auto Name = std::make_unique<MainWindow>(); \
Name->setObjectName(FRAMELESSHELPER_STRING_LITERAL(#Name)); \
Name->waitReady(); \
Name->show();
int main(int argc, char *argv[])
{
Log::setup(FRAMELESSHELPER_STRING_LITERAL("mainwindow"));
@ -51,11 +57,11 @@ int main(int argc, char *argv[])
FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
const auto mainWindow = std::make_unique<MainWindow>();
mainWindow->waitReady();
mainWindow->show();
CREATE_WINDOW(mainWindow1)
CREATE_WINDOW(mainWindow2)
CREATE_WINDOW(mainWindow3)
return QCoreApplication::exec();
}

View File

@ -60,9 +60,10 @@ MainWindow::~MainWindow() = default;
void MainWindow::closeEvent(QCloseEvent *event)
{
if (!parent()) {
Settings::set({}, kGeometry, geometry());
Settings::set({}, kState, saveState());
Settings::set({}, kDevicePixelRatio, devicePixelRatioF());
const QString id = objectName();
Settings::set(id, kGeometry, geometry());
Settings::set(id, kState, saveState());
Settings::set(id, kDevicePixelRatio, devicePixelRatioF());
}
FramelessMainWindow::closeEvent(event);
}
@ -108,8 +109,14 @@ QMenuBar::item:pressed {
#endif // Q_OS_MACOS
helper->setHitTestVisible(mb); // IMPORTANT!
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
setWindowTitle(tr("FramelessHelper demo application - QMainWindow"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
connect(this, &MainWindow::objectNameChanged, this, [this](const QString &name){
if (name.isEmpty()) {
return;
}
setWindowTitle(windowTitle() + FRAMELESSHELPER_STRING_LITERAL(" [%1]").arg(name));
});
connect(m_mainWindow->pushButton, &QPushButton::clicked, this, [this]{
const auto dialog = new Dialog(this);
dialog->waitReady();
@ -128,9 +135,10 @@ void MainWindow::waitReady()
{
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->waitForReady();
const auto savedGeometry = Settings::get<QRect>({}, kGeometry);
const QString id = objectName();
const auto savedGeometry = Settings::get<QRect>(id, kGeometry);
if (savedGeometry.isValid() && !parent()) {
const auto savedDpr = Settings::get<qreal>({}, kDevicePixelRatio);
const auto savedDpr = Settings::get<qreal>(id, kDevicePixelRatio);
// Qt doesn't support dpr < 1.
const qreal oldDpr = std::max(savedDpr, qreal(1));
const qreal scale = (devicePixelRatioF() / oldDpr);
@ -138,7 +146,7 @@ void MainWindow::waitReady()
} else {
helper->moveWindowToDesktopCenter();
}
const QByteArray savedState = Settings::get<QByteArray>({}, kState);
const QByteArray savedState = Settings::get<QByteArray>(id, kState);
if (!savedState.isEmpty() && !parent()) {
restoreState(savedState);
}

View File

@ -59,10 +59,9 @@ int main(int argc, char *argv[])
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
//FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
CREATE_WINDOW(window1)
CREATE_WINDOW(window2)
CREATE_WINDOW(window3)
CREATE_WINDOW(window4)
CREATE_WINDOW(widget1)
CREATE_WINDOW(widget2)
CREATE_WINDOW(widget3)
return QCoreApplication::exec();
}

View File

@ -80,7 +80,7 @@ void Widget::closeEvent(QCloseEvent *event)
void Widget::initialize()
{
setWindowTitle(tr("FramelessHelper demo application - Qt Widgets"));
setWindowTitle(tr("FramelessHelper demo application - QWidget"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
resize(800, 600);
m_titleBar = new StandardTitleBar(this);

View File

@ -65,8 +65,8 @@ private:
QBrush micaBrush = {};
bool initialized = false;
struct {
qreal x = 0;
qreal y = 0;
qreal horizontal = 0;
qreal vertical = 0;
} transform = {};
};

View File

@ -29,6 +29,7 @@
#include "framelessconfig_p.h"
#include <QtCore/qsysinfo.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qmutex.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qimage.h>
#include <QtGui/qimagereader.h>
@ -77,6 +78,7 @@ struct MicaMaterialData
{
QPixmap blurredWallpaper = {};
bool graphicsResourcesReady = false;
QMutex mutex;
};
Q_GLOBAL_STATIC(MicaMaterialData, g_micaMaterialData)
@ -529,15 +531,25 @@ const MicaMaterialPrivate *MicaMaterialPrivate::get(const MicaMaterial *q)
void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
{
g_micaMaterialData()->mutex.lock();
if (!g_micaMaterialData()->blurredWallpaper.isNull() && !force) {
g_micaMaterialData()->mutex.unlock();
return;
}
g_micaMaterialData()->mutex.unlock();
// ### FIXME: Ideally, we should not use virtual desktop size here.
QSize monitorSize = QGuiApplication::primaryScreen()->virtualSize();
if (monitorSize.isEmpty()) {
WARNING << "Failed to retrieve the monitor size. Using default size (1920x1080) instead ...";
monitorSize = kMaximumPictureSize;
}
const QSize imageSize = (monitorSize > kMaximumPictureSize ? kMaximumPictureSize : monitorSize);
if (imageSize == monitorSize) {
transform = {};
} else {
transform.horizontal = (qreal(imageSize.width()) / qreal(monitorSize.width()));
transform.vertical = (qreal(imageSize.height()) / qreal(monitorSize.height()));
}
const QString wallpaperFilePath = Utils::getWallpaperFilePath();
if (wallpaperFilePath.isEmpty()) {
WARNING << "Failed to retrieve the wallpaper file path.";
@ -554,23 +566,17 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
return;
}
const QSize correctedSize = (actualSize > kMaximumPictureSize ? kMaximumPictureSize : actualSize);
if (actualSize == correctedSize) {
transform = {};
} else {
if (correctedSize != actualSize) {
DEBUG << "The wallpaper picture size is greater than 1920x1080, it will be shrinked to reduce memory consumption.";
reader.setScaledSize(correctedSize);
transform.x = qreal(correctedSize.width()) / qreal(actualSize.width());
transform.y = qreal(correctedSize.height()) / qreal(actualSize.height());
}
QImage image(correctedSize, kDefaultImageFormat);
if (!reader.read(&image)) {
WARNING << "Failed to read the wallpaper image:" << reader.errorString();
transform = {};
return;
}
if (image.isNull()) {
WARNING << "The obtained image data is null.";
transform = {};
return;
}
WallpaperAspectStyle aspectStyle = Utils::getWallpaperAspectStyle();
@ -607,6 +613,7 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
const QRect rect = alignedRect(Qt::LeftToRight, Qt::AlignCenter, image.size(), desktopRect);
bufferPainter.drawImage(rect.topLeft(), image);
}
g_micaMaterialData()->mutex.lock();
g_micaMaterialData()->blurredWallpaper = QPixmap(imageSize);
g_micaMaterialData()->blurredWallpaper.fill(kDefaultTransparentColor);
QPainter painter(&g_micaMaterialData()->blurredWallpaper);
@ -617,6 +624,7 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
#else // !FRAMELESSHELPER_CORE_NO_PRIVATE
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
#endif // FRAMELESSHELPER_CORE_NO_PRIVATE
g_micaMaterialData()->mutex.unlock();
if (initialized) {
Q_Q(MicaMaterial);
Q_EMIT q->shouldRedraw();
@ -661,18 +669,19 @@ void MicaMaterialPrivate::paint(QPainter *painter, const QSize &size, const QPoi
static constexpr const QPointF originPoint = {0, 0};
QPointF correctedPos = pos;
QSizeF correctedSize = size;
if (!qFuzzyIsNull(transform.x) && (transform.x > qreal(0)) && !qFuzzyCompare(transform.x, qreal(1))) {
correctedPos.setX(correctedPos.x() * transform.x);
correctedSize.setWidth(correctedSize.width() * transform.x);
if (!qFuzzyIsNull(transform.horizontal) && (transform.horizontal > qreal(0)) && !qFuzzyCompare(transform.horizontal, qreal(1))) {
correctedPos.setX(correctedPos.x() * transform.horizontal);
correctedSize.setWidth(correctedSize.width() * transform.horizontal);
}
if (!qFuzzyIsNull(transform.y) && (transform.y > qreal(0)) && !qFuzzyCompare(transform.y, qreal(1))) {
correctedPos.setY(correctedPos.y() * transform.y);
correctedSize.setHeight(correctedSize.height() * transform.y);
if (!qFuzzyIsNull(transform.vertical) && (transform.vertical > qreal(0)) && !qFuzzyCompare(transform.vertical, qreal(1))) {
correctedPos.setY(correctedPos.y() * transform.vertical);
correctedSize.setHeight(correctedSize.height() * transform.vertical);
}
painter->save();
painter->setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
if (active) {
const QMutexLocker locker(&g_micaMaterialData()->mutex);
painter->drawPixmap(originPoint, g_micaMaterialData()->blurredWallpaper, QRectF{correctedPos, correctedSize});
}
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
@ -715,10 +724,13 @@ void MicaMaterialPrivate::initialize()
void MicaMaterialPrivate::prepareGraphicsResources()
{
g_micaMaterialData()->mutex.lock();
if (g_micaMaterialData()->graphicsResourcesReady) {
g_micaMaterialData()->mutex.unlock();
return;
}
g_micaMaterialData()->graphicsResourcesReady = true;
g_micaMaterialData()->mutex.unlock();
maybeGenerateBlurredWallpaper();
}