mica material: fix drawing on multi-monitor scenario
This commit is contained in:
parent
43f632f261
commit
d71dc75b77
|
@ -54,7 +54,7 @@ option(FRAMELESSHELPER_ENABLE_CFGUARD "Enable Control Flow Guard (CFG)." OFF)
|
|||
option(FRAMELESSHELPER_EXAMPLES_STANDALONE "Build the demo projects as standalone CMake projects." OFF)
|
||||
cmake_dependent_option(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD "macOS only: build universal library/example for Mac." ON APPLE OFF)
|
||||
option(FRAMELESSHELPER_FORCE_LTO "Force enable LTO/LTCG even when building static libraries." OFF)
|
||||
option(FRAMELESSHELPER_REPRODUCIBLE_OUTPUT "Don't update the build commit and date dynamically." OFF)
|
||||
option(FRAMELESSHELPER_REPRODUCIBLE_OUTPUT "Don't update the build commit and date dynamically." ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui)
|
||||
|
|
|
@ -57,29 +57,33 @@ target_sources(${DEMO_NAME} PRIVATE
|
|||
|
||||
if(WIN32)
|
||||
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Dialog"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
if(NOT EXISTS "${__rc_path}")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Dialog"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
endif()
|
||||
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Dialog"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
if(NOT EXISTS "${__manifest_path}")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Dialog"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
endif()
|
||||
target_sources(${DEMO_NAME} PRIVATE
|
||||
"${__rc_path}"
|
||||
"${__manifest_path}"
|
||||
|
|
|
@ -62,29 +62,33 @@ target_sources(${DEMO_NAME} PRIVATE
|
|||
|
||||
if(WIN32)
|
||||
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: MainWindow"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
if(NOT EXISTS "${__rc_path}")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: MainWindow"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
endif()
|
||||
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.MainWindow"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
if(NOT EXISTS "${__manifest_path}")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.MainWindow"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
endif()
|
||||
target_sources(${DEMO_NAME} PRIVATE
|
||||
"${__rc_path}"
|
||||
"${__manifest_path}"
|
||||
|
|
|
@ -65,29 +65,33 @@ target_sources(${DEMO_NAME} PRIVATE
|
|||
|
||||
if(WIN32)
|
||||
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: OpenGLWidget"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
if(NOT EXISTS "${__rc_path}")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: OpenGLWidget"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
endif()
|
||||
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.OpenGLWidget"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
if(NOT EXISTS "${__manifest_path}")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.OpenGLWidget"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
endif()
|
||||
target_sources(${DEMO_NAME} PRIVATE
|
||||
"${__rc_path}"
|
||||
"${__manifest_path}"
|
||||
|
|
|
@ -57,29 +57,33 @@ target_sources(${DEMO_NAME} PRIVATE
|
|||
|
||||
if(WIN32)
|
||||
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Quick"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
if(NOT EXISTS "${__rc_path}")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Quick"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
endif()
|
||||
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Quick"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
if(NOT EXISTS "${__manifest_path}")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Quick"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
endif()
|
||||
target_sources(${DEMO_NAME} PRIVATE
|
||||
"${__rc_path}"
|
||||
"${__manifest_path}"
|
||||
|
|
|
@ -57,29 +57,33 @@ target_sources(${DEMO_NAME} PRIVATE
|
|||
|
||||
if(WIN32)
|
||||
set(__rc_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.rc")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Widget"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
if(NOT EXISTS "${__rc_path}")
|
||||
generate_win32_rc_file(
|
||||
PATH "${__rc_path}"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPANY "wangwenx190"
|
||||
DESCRIPTION "FramelessHelper Demo Application: Widget"
|
||||
COPYRIGHT "MIT License"
|
||||
PRODUCT "FramelessHelper Demo"
|
||||
ICONS "../shared/example.ico"
|
||||
)
|
||||
endif()
|
||||
set(__manifest_path "${PROJECT_BINARY_DIR}/${DEMO_NAME}.manifest")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Widget"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
if(NOT EXISTS "${__manifest_path}")
|
||||
generate_win32_manifest_file(
|
||||
PATH "${__manifest_path}"
|
||||
ID "org.wangwenx190.demo.Widget"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
VISTA_COMPAT
|
||||
WIN7_COMPAT
|
||||
WIN8_COMPAT
|
||||
WIN8_1_COMPAT
|
||||
WIN10_COMPAT
|
||||
WIN11_COMPAT
|
||||
XAML_ISLANDS_COMPAT
|
||||
UTF8_CODEPAGE
|
||||
)
|
||||
endif()
|
||||
target_sources(${DEMO_NAME} PRIVATE
|
||||
"${__rc_path}"
|
||||
"${__manifest_path}"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
||||
#include <QtCore/qrect.h>
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -62,7 +63,13 @@ public:
|
|||
void setFallbackEnabled(const bool value);
|
||||
|
||||
public Q_SLOTS:
|
||||
void paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active = true);
|
||||
void paint(QPainter *painter, const QRect &rect, const bool active = true);
|
||||
|
||||
[[deprecated("Use another overload instead.")]]
|
||||
void paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active = true)
|
||||
{
|
||||
paint(painter, QRect{ pos, size }, active);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void tintColorChanged();
|
||||
|
|
|
@ -103,3 +103,21 @@ FRAMELESSHELPER_CORE_API void registerInitializeHook(const InitializeHookCallbac
|
|||
FRAMELESSHELPER_CORE_API void registerUninitializeHook(const UninitializeHookCallback &cb);
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#define DECLARE_SIZE_COMPARE_OPERATORS(Type1, Type2) \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return ((lhs.width() * lhs.height()) > (rhs.width() * rhs.height())); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator>(lhs, rhs) || operator==(lhs, rhs)); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator!=(lhs, rhs) && !operator>(lhs, rhs)); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator<(lhs, rhs) || operator==(lhs, rhs)); \
|
||||
}
|
||||
|
|
|
@ -52,10 +52,18 @@ public:
|
|||
|
||||
Q_NODISCARD static QColor systemFallbackColor();
|
||||
|
||||
Q_NODISCARD static QSize monitorSize();
|
||||
Q_NODISCARD static QSize wallpaperSize();
|
||||
|
||||
Q_NODISCARD QPoint mapToWallpaper(const QPoint &pos) const;
|
||||
Q_NODISCARD QSize mapToWallpaper(const QSize &size) const;
|
||||
Q_NODISCARD QRect mapToWallpaper(const QRect &rect) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void maybeGenerateBlurredWallpaper(const bool force = false);
|
||||
void updateMaterialBrush();
|
||||
void paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active = true);
|
||||
void paint(QPainter *painter, const QRect &rect, const bool active = true);
|
||||
void forceRebuildWallpaper();
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
|
|
|
@ -81,7 +81,9 @@ FRAMELESSHELPER_CORE_API void registerThemeChangeNotification();
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint fromNativeGlobalPosition(const QWindow *window, const QPoint &point);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API int horizontalAdvance(const QFontMetrics &fm, const QString &str);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API qreal getRelativeScaleFactor(const quint32 oldDpi, const quint32 newDpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QSizeF rescaleSize(const QSizeF &oldSize, const quint32 oldDpi, const quint32 newDpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QSize rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint32 newDpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidGeometry(const QRectF &rect);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidGeometry(const QRect &rect);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi();
|
||||
|
|
|
@ -56,7 +56,7 @@ private:
|
|||
void fromImage(const QImage &value, QPainter *painter) const;
|
||||
void fromPixmap(const QPixmap &value, QPainter *painter) const;
|
||||
void fromIcon(const QIcon &value, QPainter *painter) const;
|
||||
Q_NODISCARD QRect paintArea() const;
|
||||
Q_NODISCARD QRectF paintArea() const;
|
||||
|
||||
private:
|
||||
QuickImageItem *q_ptr = nullptr;
|
||||
|
|
|
@ -53,6 +53,7 @@ public Q_SLOTS:
|
|||
void rebindWindow();
|
||||
void forceRegenerateWallpaperImageCache();
|
||||
void appendNode(WallpaperImageNode *node);
|
||||
void removeNode(WallpaperImageNode *node);
|
||||
void updateFallbackColor();
|
||||
|
||||
private:
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "framelessmanager.h"
|
||||
#include "utils.h"
|
||||
#include "framelessconfig_p.h"
|
||||
#include "framelesshelpercore_global_p.h"
|
||||
#include <QtCore/qsysinfo.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
|
@ -57,6 +58,11 @@ static Q_LOGGING_CATEGORY(lcMicaMaterial, "wangwenx190.framelesshelper.core.mica
|
|||
# define CRITICAL qCCritical(lcMicaMaterial)
|
||||
#endif
|
||||
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSize)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSize)
|
||||
|
||||
using namespace Global;
|
||||
|
||||
[[maybe_unused]] static constexpr const QSize kMaximumPictureSize = { 1920, 1080 };
|
||||
|
@ -75,34 +81,22 @@ using namespace Global;
|
|||
FRAMELESSHELPER_STRING_CONSTANT2(NoiseImageFilePath, ":/org.wangwenx190.FramelessHelper/resources/images/noise.png")
|
||||
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
|
||||
|
||||
struct MicaMaterialData
|
||||
struct ImageData
|
||||
{
|
||||
QPixmap blurredWallpaper = {};
|
||||
bool graphicsResourcesReady = false;
|
||||
QMutex mutex{};
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(MicaMaterialData, g_micaMaterialData)
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>(const QSize &lhs, const QSize &rhs) noexcept
|
||||
struct MetricsData
|
||||
{
|
||||
return ((lhs.width() * lhs.height()) > (rhs.width() * rhs.height()));
|
||||
}
|
||||
std::optional<QSize> monitorSize = std::nullopt;
|
||||
std::optional<QSize> wallpaperSize = std::nullopt;
|
||||
QMutex mutex{};
|
||||
};
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>=(const QSize &lhs, const QSize &rhs) noexcept
|
||||
{
|
||||
return (operator>(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<(const QSize &lhs, const QSize &rhs) noexcept
|
||||
{
|
||||
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<=(const QSize &lhs, const QSize &rhs) noexcept
|
||||
{
|
||||
return (operator<(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
Q_GLOBAL_STATIC(ImageData, g_imageData)
|
||||
Q_GLOBAL_STATIC(MetricsData, g_metricsData)
|
||||
|
||||
#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||
template<const int shift>
|
||||
|
@ -516,13 +510,10 @@ protected:
|
|||
void run() override
|
||||
{
|
||||
Transform transform = {};
|
||||
// ### 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);
|
||||
const QSize monitorSize = MicaMaterialPrivate::monitorSize();
|
||||
const QSize imageSize = MicaMaterialPrivate::wallpaperSize();
|
||||
// If we scaled the image size, record the scale factor and we need it to map our clip rect
|
||||
// to the real (unscaled) rect.
|
||||
if (imageSize != monitorSize) {
|
||||
transform.Horizontal = (qreal(imageSize.width()) / qreal(monitorSize.width()));
|
||||
transform.Vertical = (qreal(imageSize.height()) / qreal(monitorSize.height()));
|
||||
|
@ -532,6 +523,8 @@ protected:
|
|||
WARNING << "Failed to retrieve the wallpaper file path.";
|
||||
return;
|
||||
}
|
||||
// QImageReader allows us read the image size before we actually loading it, this behavior
|
||||
// can help us avoid consume too much memory if the image resolution is very large, eg, 4K.
|
||||
QImageReader reader(wallpaperFilePath);
|
||||
if (!reader.canRead()) {
|
||||
WARNING << "Qt can't read the wallpaper file:" << reader.errorString();
|
||||
|
@ -590,18 +583,19 @@ protected:
|
|||
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);
|
||||
painter.setRenderHints(QPainter::Antialiasing |
|
||||
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
{
|
||||
const QMutexLocker locker(&g_imageData()->mutex);
|
||||
g_imageData()->blurredWallpaper = QPixmap(imageSize);
|
||||
g_imageData()->blurredWallpaper.fill(kDefaultTransparentColor);
|
||||
QPainter painter(&g_imageData()->blurredWallpaper);
|
||||
painter.setRenderHints(QPainter::Antialiasing |
|
||||
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||
painter.drawImage(desktopOriginPoint, buffer);
|
||||
painter.drawImage(desktopOriginPoint, buffer);
|
||||
#else // !FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
|
||||
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
|
||||
#endif // FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||
g_micaMaterialData()->mutex.unlock();
|
||||
}
|
||||
Q_EMIT imageUpdated(transform);
|
||||
}
|
||||
};
|
||||
|
@ -656,12 +650,12 @@ 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();
|
||||
g_imageData()->mutex.lock();
|
||||
if (!g_imageData()->blurredWallpaper.isNull() && !force) {
|
||||
g_imageData()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_micaMaterialData()->mutex.unlock();
|
||||
g_imageData()->mutex.unlock();
|
||||
const QMutexLocker locker(&g_threadData()->mutex);
|
||||
if (g_threadData()->thread->isRunning()) {
|
||||
g_threadData()->thread->requestInterruption();
|
||||
|
@ -698,37 +692,25 @@ void MicaMaterialPrivate::updateMaterialBrush()
|
|||
}
|
||||
}
|
||||
|
||||
void MicaMaterialPrivate::paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active)
|
||||
void MicaMaterialPrivate::paint(QPainter *painter, const QRect &rect, const bool active)
|
||||
{
|
||||
Q_ASSERT(painter);
|
||||
Q_ASSERT(!size.isEmpty());
|
||||
if (!painter || size.isEmpty()) {
|
||||
if (!painter) {
|
||||
return;
|
||||
}
|
||||
prepareGraphicsResources();
|
||||
static constexpr const QPointF originPoint = {0, 0};
|
||||
QPointF correctedPos = pos;
|
||||
QSizeF correctedSize = size;
|
||||
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.Vertical) && (transform.Vertical > qreal(0))
|
||||
&& !qFuzzyCompare(transform.Vertical, qreal(1))) {
|
||||
correctedPos.setY(correctedPos.y() * transform.Vertical);
|
||||
correctedSize.setHeight(correctedSize.height() * transform.Vertical);
|
||||
}
|
||||
static constexpr const QPoint originPoint = {0, 0};
|
||||
const QRect mappedRect = mapToWallpaper(rect);
|
||||
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});
|
||||
const QMutexLocker locker(&g_imageData()->mutex);
|
||||
painter->drawPixmap(originPoint, g_imageData()->blurredWallpaper, mappedRect);
|
||||
}
|
||||
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
painter->setOpacity(qreal(1));
|
||||
painter->fillRect(QRectF{originPoint, correctedSize}, [this, active]() -> QBrush {
|
||||
painter->fillRect(QRect{originPoint, mappedRect.size()}, [this, active]() -> QBrush {
|
||||
if (!fallbackEnabled || active) {
|
||||
return micaBrush;
|
||||
}
|
||||
|
@ -740,6 +722,15 @@ void MicaMaterialPrivate::paint(QPainter *painter, const QSize &size, const QPoi
|
|||
painter->restore();
|
||||
}
|
||||
|
||||
void MicaMaterialPrivate::forceRebuildWallpaper()
|
||||
{
|
||||
g_metricsData()->mutex.lock();
|
||||
g_metricsData()->monitorSize = std::nullopt;
|
||||
g_metricsData()->wallpaperSize = std::nullopt;
|
||||
g_metricsData()->mutex.unlock();
|
||||
maybeGenerateBlurredWallpaper(true);
|
||||
}
|
||||
|
||||
void MicaMaterialPrivate::initialize()
|
||||
{
|
||||
g_threadData()->mutex.lock();
|
||||
|
@ -767,9 +758,9 @@ void MicaMaterialPrivate::initialize()
|
|||
connect(FramelessManager::instance(), &FramelessManager::systemThemeChanged,
|
||||
this, &MicaMaterialPrivate::updateMaterialBrush);
|
||||
connect(FramelessManager::instance(), &FramelessManager::wallpaperChanged,
|
||||
this, [this](){
|
||||
maybeGenerateBlurredWallpaper(true);
|
||||
});
|
||||
this, &MicaMaterialPrivate::forceRebuildWallpaper);
|
||||
connect(qGuiApp, &QGuiApplication::primaryScreenChanged,
|
||||
this, &MicaMaterialPrivate::forceRebuildWallpaper);
|
||||
|
||||
if (FramelessConfig::instance()->isSet(Option::DisableLazyInitializationForMicaMaterial)) {
|
||||
prepareGraphicsResources();
|
||||
|
@ -780,13 +771,13 @@ void MicaMaterialPrivate::initialize()
|
|||
|
||||
void MicaMaterialPrivate::prepareGraphicsResources()
|
||||
{
|
||||
g_micaMaterialData()->mutex.lock();
|
||||
if (g_micaMaterialData()->graphicsResourcesReady) {
|
||||
g_micaMaterialData()->mutex.unlock();
|
||||
g_imageData()->mutex.lock();
|
||||
if (g_imageData()->graphicsResourcesReady) {
|
||||
g_imageData()->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
g_micaMaterialData()->graphicsResourcesReady = true;
|
||||
g_micaMaterialData()->mutex.unlock();
|
||||
g_imageData()->graphicsResourcesReady = true;
|
||||
g_imageData()->mutex.unlock();
|
||||
maybeGenerateBlurredWallpaper();
|
||||
}
|
||||
|
||||
|
@ -795,6 +786,123 @@ QColor MicaMaterialPrivate::systemFallbackColor()
|
|||
return ((FramelessManager::instance()->systemTheme() == SystemTheme::Dark) ? kDefaultFallbackColorDark : kDefaultFallbackColorLight);
|
||||
}
|
||||
|
||||
QSize MicaMaterialPrivate::monitorSize()
|
||||
{
|
||||
g_metricsData()->mutex.lock();
|
||||
if (!g_metricsData()->monitorSize.has_value()) {
|
||||
g_metricsData()->mutex.unlock();
|
||||
const QScreen * const monitor = QGuiApplication::primaryScreen();
|
||||
Q_ASSERT(monitor);
|
||||
// We do not use the virtual desktop size here, instead, we only calculate the primary
|
||||
// monitor size to simplify the logic, otherwise we will need a lot more code to take
|
||||
// every case into account.
|
||||
QSize size = (monitor ? monitor->size() : kMaximumPictureSize);
|
||||
if (Q_UNLIKELY(size.isEmpty())) {
|
||||
WARNING << "Failed to retrieve the monitor size. Using default size (1920x1080) instead ...";
|
||||
size = kMaximumPictureSize;
|
||||
}
|
||||
g_metricsData()->mutex.lock();
|
||||
g_metricsData()->monitorSize = size;
|
||||
// Don't unlock the mutex here, we'll unlock it from outside.
|
||||
DEBUG << "Primary monitor size:" << size * (monitor ? monitor->devicePixelRatio() : qreal(1));
|
||||
}
|
||||
const QSize result = g_metricsData()->monitorSize.value();
|
||||
g_metricsData()->mutex.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
QSize MicaMaterialPrivate::wallpaperSize()
|
||||
{
|
||||
g_metricsData()->mutex.lock();
|
||||
if (!g_metricsData()->wallpaperSize.has_value()) {
|
||||
g_metricsData()->mutex.unlock();
|
||||
const QSize desktopSize = monitorSize();
|
||||
// It's observed that QImage consumes too much memory if the image resolution is very large.
|
||||
const QSize size = (desktopSize > kMaximumPictureSize ? kMaximumPictureSize : desktopSize);
|
||||
g_metricsData()->mutex.lock();
|
||||
g_metricsData()->wallpaperSize = size;
|
||||
// Don't unlock the mutex here, we'll unlock it from outside.
|
||||
DEBUG << "Wallpaper size:" << size;
|
||||
}
|
||||
const QSize result = g_metricsData()->wallpaperSize.value();
|
||||
g_metricsData()->mutex.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
QPoint MicaMaterialPrivate::mapToWallpaper(const QPoint &pos) const
|
||||
{
|
||||
if (pos.isNull()) {
|
||||
return {};
|
||||
}
|
||||
QPointF result = pos;
|
||||
if (!qFuzzyIsNull(transform.Horizontal) && (transform.Horizontal > qreal(0))
|
||||
&& !qFuzzyCompare(transform.Horizontal, qreal(1))) {
|
||||
result.setX(result.x() * transform.Horizontal);
|
||||
}
|
||||
if (!qFuzzyIsNull(transform.Vertical) && (transform.Vertical > qreal(0))
|
||||
&& !qFuzzyCompare(transform.Vertical, qreal(1))) {
|
||||
result.setY(result.y() * transform.Vertical);
|
||||
}
|
||||
const QSizeF imageSize = wallpaperSize();
|
||||
// Make sure the position is always inside the wallpaper rectangle.
|
||||
while (result.x() < qreal(0)) {
|
||||
result.setX(result.x() + imageSize.width());
|
||||
}
|
||||
while (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()) {
|
||||
result.setY(result.y() - imageSize.height());
|
||||
}
|
||||
return result.toPoint();
|
||||
}
|
||||
|
||||
QSize MicaMaterialPrivate::mapToWallpaper(const QSize &size) const
|
||||
{
|
||||
if (size.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
QSizeF result = size;
|
||||
if (!qFuzzyIsNull(transform.Horizontal) && (transform.Horizontal > qreal(0))
|
||||
&& !qFuzzyCompare(transform.Horizontal, qreal(1))) {
|
||||
result.setWidth(result.width() * transform.Horizontal);
|
||||
}
|
||||
if (!qFuzzyIsNull(transform.Vertical) && (transform.Vertical > qreal(0))
|
||||
&& !qFuzzyCompare(transform.Vertical, qreal(1))) {
|
||||
result.setHeight(result.height() * transform.Vertical);
|
||||
}
|
||||
const QSizeF imageSize = wallpaperSize();
|
||||
// Make sure we don't get a size larger than the wallpaper's size.
|
||||
if (result.width() > imageSize.width()) {
|
||||
result.setWidth(imageSize.width());
|
||||
}
|
||||
if (result.height() > imageSize.height()) {
|
||||
result.setHeight(imageSize.height());
|
||||
}
|
||||
return result.toSize();
|
||||
}
|
||||
|
||||
QRect MicaMaterialPrivate::mapToWallpaper(const QRect &rect) const
|
||||
{
|
||||
const auto wallpaperRect = QRectF{ QPointF{ 0, 0 }, wallpaperSize() };
|
||||
const auto mappedRect = QRectF{ mapToWallpaper(rect.topLeft()), mapToWallpaper(rect.size()) };
|
||||
if (!Utils::isValidGeometry(mappedRect)) {
|
||||
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();
|
||||
}
|
||||
|
||||
MicaMaterial::MicaMaterial(QObject *parent)
|
||||
: QObject(parent), d_ptr(new MicaMaterialPrivate(this))
|
||||
{
|
||||
|
@ -900,10 +1008,10 @@ void MicaMaterial::setFallbackEnabled(const bool value)
|
|||
Q_EMIT fallbackEnabledChanged();
|
||||
}
|
||||
|
||||
void MicaMaterial::paint(QPainter *painter, const QSize &size, const QPoint &pos, const bool active)
|
||||
void MicaMaterial::paint(QPainter *painter, const QRect &rect, const bool active)
|
||||
{
|
||||
Q_D(MicaMaterial);
|
||||
d->paint(painter, size, pos, active);
|
||||
d->paint(painter, rect, active);
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -530,7 +530,7 @@ qreal Utils::getRelativeScaleFactor(const quint32 oldDpi, const quint32 newDpi)
|
|||
return qreal(newDpr / oldDpr);
|
||||
}
|
||||
|
||||
QSize Utils::rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint32 newDpi)
|
||||
QSizeF Utils::rescaleSize(const QSizeF &oldSize, const quint32 oldDpi, const quint32 newDpi)
|
||||
{
|
||||
if (oldSize.isEmpty()) {
|
||||
return {};
|
||||
|
@ -545,14 +545,23 @@ QSize Utils::rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint
|
|||
if (qFuzzyCompare(scaleFactor, qreal(1))) {
|
||||
return oldSize;
|
||||
}
|
||||
const QSizeF newSize = QSizeF(oldSize) * scaleFactor;
|
||||
return newSize.toSize(); // The numbers will be rounded to the nearest integer.
|
||||
return QSizeF(oldSize * scaleFactor);
|
||||
}
|
||||
|
||||
QSize Utils::rescaleSize(const QSize &oldSize, const quint32 oldDpi, const quint32 newDpi)
|
||||
{
|
||||
return rescaleSize(QSizeF(oldSize), oldDpi, newDpi).toSize();
|
||||
}
|
||||
|
||||
bool Utils::isValidGeometry(const QRectF &rect)
|
||||
{
|
||||
// The position of the rectangle is not relevant.
|
||||
return ((rect.right() > rect.left()) && (rect.bottom() > rect.top()));
|
||||
}
|
||||
|
||||
bool Utils::isValidGeometry(const QRect &rect)
|
||||
{
|
||||
// The position of the rectangle is not relevant.
|
||||
return ((rect.right() > rect.left()) && (rect.bottom() > rect.top()));
|
||||
return isValidGeometry(QRectF(rect));
|
||||
}
|
||||
|
||||
quint32 Utils::defaultScreenDpi()
|
||||
|
|
|
@ -89,7 +89,7 @@ void QuickImageItemPrivate::paint(QPainter *painter) const
|
|||
if (!painter) {
|
||||
return;
|
||||
}
|
||||
if (!m_source.isValid()) {
|
||||
if (!m_source.isValid() || m_source.isNull()) {
|
||||
return;
|
||||
}
|
||||
painter->save();
|
||||
|
@ -126,7 +126,8 @@ QVariant QuickImageItemPrivate::source() const
|
|||
void QuickImageItemPrivate::setSource(const QVariant &value)
|
||||
{
|
||||
Q_ASSERT(value.isValid());
|
||||
if (!value.isValid()) {
|
||||
Q_ASSERT(!value.isNull());
|
||||
if (!value.isValid() || value.isNull()) {
|
||||
return;
|
||||
}
|
||||
if (m_source == value) {
|
||||
|
@ -196,7 +197,9 @@ void QuickImageItemPrivate::fromPixmap(const QPixmap &value, QPainter *painter)
|
|||
if (value.isNull() || !painter) {
|
||||
return;
|
||||
}
|
||||
painter->drawPixmap(paintArea(), value);
|
||||
const QRectF paintRect = paintArea();
|
||||
const QSize paintSize = paintRect.size().toSize();
|
||||
painter->drawPixmap(paintRect.topLeft(), (value.size() == paintSize ? value : value.scaled(paintSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)));
|
||||
}
|
||||
|
||||
void QuickImageItemPrivate::fromIcon(const QIcon &value, QPainter *painter) const
|
||||
|
@ -206,18 +209,18 @@ void QuickImageItemPrivate::fromIcon(const QIcon &value, QPainter *painter) cons
|
|||
if (value.isNull() || !painter) {
|
||||
return;
|
||||
}
|
||||
value.paint(painter, paintArea());
|
||||
fromPixmap(value.pixmap(paintArea().size().toSize()), painter);
|
||||
}
|
||||
|
||||
QRect QuickImageItemPrivate::paintArea() const
|
||||
QRectF QuickImageItemPrivate::paintArea() const
|
||||
{
|
||||
Q_Q(const QuickImageItem);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
const QSize size = q->size().toSize();
|
||||
const QSizeF size = q->size();
|
||||
#else
|
||||
const QSize size = {int(std::round(q->width())), int(std::round(q->height()))};
|
||||
const QSizeF size = {q->width(), q->height()};
|
||||
#endif
|
||||
return {QPoint(0, 0), size};
|
||||
return {QPointF(0, 0), size};
|
||||
}
|
||||
|
||||
QuickImageItem::QuickImageItem(QQuickItem *parent)
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
#include <FramelessHelper/Core/framelessmanager.h>
|
||||
#include <FramelessHelper/Core/private/micamaterial_p.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qpainter.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtQuick/qquickwindow.h>
|
||||
#include <QtQuick/qsgsimpletexturenode.h>
|
||||
#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||
|
@ -74,10 +72,12 @@ private:
|
|||
void initialize();
|
||||
|
||||
private:
|
||||
QSGTexture *m_texture = nullptr;
|
||||
QPointer<QuickMicaMaterial> m_item = nullptr;
|
||||
QSGSimpleTextureNode *m_node = nullptr;
|
||||
QPixmap m_pixmapCache = {};
|
||||
std::unique_ptr<QSGTexture> m_texture = nullptr;
|
||||
QPointer<MicaMaterial> m_mica{ nullptr };
|
||||
QPointer<MicaMaterialPrivate> m_micaPriv{ nullptr };
|
||||
QPointer<QQuickWindow> m_window{ nullptr };
|
||||
};
|
||||
|
||||
WallpaperImageNode::WallpaperImageNode(QuickMicaMaterial *item)
|
||||
|
@ -90,12 +90,18 @@ WallpaperImageNode::WallpaperImageNode(QuickMicaMaterial *item)
|
|||
initialize();
|
||||
}
|
||||
|
||||
WallpaperImageNode::~WallpaperImageNode() = default;
|
||||
WallpaperImageNode::~WallpaperImageNode()
|
||||
{
|
||||
QuickMicaMaterialPrivate::get(m_item)->removeNode(this);
|
||||
}
|
||||
|
||||
void WallpaperImageNode::initialize()
|
||||
{
|
||||
QQuickWindow * const window = m_item->window();
|
||||
m_window = m_item->window();
|
||||
m_mica = QuickMicaMaterialPrivate::get(m_item)->m_micaMaterial;
|
||||
m_micaPriv = MicaMaterialPrivate::get(m_mica);
|
||||
|
||||
// QtQuick's render engine will free it when appropriate.
|
||||
m_node = new QSGSimpleTextureNode;
|
||||
m_node->setFiltering(QSGTexture::Linear);
|
||||
|
||||
|
@ -104,7 +110,7 @@ void WallpaperImageNode::initialize()
|
|||
|
||||
appendChildNode(m_node);
|
||||
|
||||
connect(window, &QQuickWindow::beforeRendering, this,
|
||||
connect(m_window, &QQuickWindow::beforeRendering, this,
|
||||
&WallpaperImageNode::maybeUpdateWallpaperImageClipRect, Qt::DirectConnection);
|
||||
|
||||
QuickMicaMaterialPrivate::get(m_item)->appendNode(this);
|
||||
|
@ -112,24 +118,18 @@ void WallpaperImageNode::initialize()
|
|||
|
||||
void WallpaperImageNode::maybeGenerateWallpaperImageCache(const bool force)
|
||||
{
|
||||
if (!m_pixmapCache.isNull() && !force) {
|
||||
if (m_texture && !force) {
|
||||
return;
|
||||
}
|
||||
const QSize desktopSize = QGuiApplication::primaryScreen()->virtualSize();
|
||||
static constexpr const QPoint originPoint = {0, 0};
|
||||
m_pixmapCache = QPixmap(desktopSize);
|
||||
m_pixmapCache.fill(kDefaultTransparentColor);
|
||||
QPainter painter(&m_pixmapCache);
|
||||
MicaMaterial * const mica = QuickMicaMaterialPrivate::get(m_item)->m_micaMaterial;
|
||||
Q_ASSERT(mica);
|
||||
static constexpr const auto originPoint = QPoint{ 0, 0 };
|
||||
const QSize imageSize = MicaMaterialPrivate::wallpaperSize();
|
||||
auto pixmap = QPixmap(imageSize);
|
||||
pixmap.fill(kDefaultTransparentColor);
|
||||
QPainter painter(&pixmap);
|
||||
// We need the real wallpaper image here, so always use "active" state.
|
||||
mica->paint(&painter, desktopSize, originPoint, true);
|
||||
if (m_texture) {
|
||||
delete m_texture;
|
||||
m_texture = nullptr;
|
||||
}
|
||||
m_texture = m_item->window()->createTextureFromImage(m_pixmapCache.toImage());
|
||||
m_node->setTexture(m_texture);
|
||||
m_mica->paint(&painter, QRect{ originPoint, imageSize }, true);
|
||||
m_texture.reset(m_window->createTextureFromImage(pixmap.toImage()));
|
||||
m_node->setTexture(m_texture.get());
|
||||
}
|
||||
|
||||
void WallpaperImageNode::maybeUpdateWallpaperImageClipRect()
|
||||
|
@ -140,7 +140,8 @@ void WallpaperImageNode::maybeUpdateWallpaperImageClipRect()
|
|||
const QSizeF itemSize = {m_item->width(), m_item->height()};
|
||||
#endif
|
||||
m_node->setRect(QRectF(QPointF(0.0, 0.0), itemSize));
|
||||
m_node->setSourceRect(QRectF(m_item->mapToGlobal(QPointF(0.0, 0.0)), itemSize));
|
||||
const auto rect = QRectF(m_item->mapToGlobal(QPointF(0.0, 0.0)), itemSize);
|
||||
m_node->setSourceRect(m_micaPriv->mapToWallpaper(rect.toRect()));
|
||||
}
|
||||
|
||||
QuickMicaMaterialPrivate::QuickMicaMaterialPrivate(QuickMicaMaterial *q) : QObject(q)
|
||||
|
@ -265,6 +266,18 @@ void QuickMicaMaterialPrivate::appendNode(WallpaperImageNode *node)
|
|||
m_nodes.append(node);
|
||||
}
|
||||
|
||||
void QuickMicaMaterialPrivate::removeNode(WallpaperImageNode *node)
|
||||
{
|
||||
Q_ASSERT(node);
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (!m_nodes.contains(node)) {
|
||||
return;
|
||||
}
|
||||
m_nodes.removeAll(node);
|
||||
}
|
||||
|
||||
void QuickMicaMaterialPrivate::updateFallbackColor()
|
||||
{
|
||||
#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||
|
|
|
@ -187,8 +187,8 @@ void WidgetsSharedHelper::repaintMica()
|
|||
return;
|
||||
}
|
||||
QPainter painter(m_targetWidget);
|
||||
m_micaMaterial->paint(&painter, m_targetWidget->size(),
|
||||
m_targetWidget->mapToGlobal(QPoint(0, 0)), m_targetWidget->isActiveWindow());
|
||||
const QRect rect = { m_targetWidget->mapToGlobal(QPoint(0, 0)), m_targetWidget->size() };
|
||||
m_micaMaterial->paint(&painter, rect, m_targetWidget->isActiveWindow());
|
||||
}
|
||||
|
||||
void WidgetsSharedHelper::repaintBorder()
|
||||
|
|
Loading…
Reference in New Issue