Make the wallpaper blur dynamic update

The window background will update dynamically once
it's being moved.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2021-03-10 14:18:08 +08:00
parent 0931b73671
commit a183a6d4a1
9 changed files with 56 additions and 44 deletions

View File

@ -120,8 +120,4 @@ Window {
framelessHelper.removeWindowFrame()
framelessHelper.setBlurEffectEnabled(true)
}
// Re-draw the window frame.
onActiveChanged: acrylicItem.update()
onVisibilityChanged: acrylicItem.update()
}

View File

@ -60,13 +60,15 @@
namespace _flh_global {
[[maybe_unused]] const char _flh_framelessMode_flag[] = "_FRAMELESSHELPER_FRAMELESS_MODE_ENABLED";
[[maybe_unused]] const char _flh_framelessEnabled_flag[] = "_FRAMELESSHELPER_FRAMELESS_MODE_ENABLED";
[[maybe_unused]] const char _flh_borderWidth_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_WIDTH";
[[maybe_unused]] const char _flh_borderHeight_flag[] = "_FRAMELESSHELPER_WINDOW_BORDER_HEIGHT";
[[maybe_unused]] const char _flh_titleBarHeight_flag[] = "_FRAMELESSHELPER_WINDOW_TITLE_BAR_HEIGHT";
[[maybe_unused]] const char _flh_ignoredObjects_flag[] = "_FRAMELESSHELPER_WINDOW_TITLE_BAR_IGNORED_OBJECTS";
[[maybe_unused]] const char _flh_acrylic_forceOfficialMSWin10Blur_flag[] = "_FRAMELESSHELPER_FORCE_MSWIN10_OFFICIAL_ACRYLIC";
[[maybe_unused]] const char _flh_acrylic_forceDWMBlur_flag[] = "_FRAMELESSHELPER_FORCE_DWM_BLUR";
[[maybe_unused]] const char _flh_acrylic_blurEnabled_flag[] = "_FRAMELESSHELPER_BLUR_ENABLED";
[[maybe_unused]] const char _flh_acrylic_blurMode_flag[] = "_FRAMELESSHELPER_BLUR_MODE";
[[maybe_unused]] const char _flh_acrylic_forceEnableOfficialMSWin10AcrylicBlur_flag[] = "_FRAMELESSHELPER_FORCE_ENABLE_MSWIN10_OFFICIAL_ACRYLIC_BLUR";
[[maybe_unused]] const char _flh_acrylic_forceEnableTraditionalBlur_flag[] = "_FRAMELESSHELPER_FORCE_ENABLE_TRADITIONAL_BLUR";
[[maybe_unused]] const char _flh_acrylic_forceDisableWallpaperBlur_flag[] = "_FRAMELESSHELPER_FORCE_DISABLE_WALLPAPER_BLUR";
[[maybe_unused]] const char _flh_useNativeTitleBar_flag[] = "_FRAMELESSHELPER_USE_NATIVE_TITLE_BAR";
[[maybe_unused]] const char _flh_preserveNativeFrame_flag[] = "_FRAMELESSHELPER_PRESERVE_NATIVE_WINDOW_FRAME";

View File

@ -121,7 +121,7 @@ static inline void installHelper(QWindow *window, const bool enable)
if (!window) {
return;
}
window->setProperty(_flh_global::_flh_framelessMode_flag, enable);
window->setProperty(_flh_global::_flh_framelessEnabled_flag, enable);
Utilities::updateQtFrameMargins(window, enable);
Utilities::updateFrameMargins(window, !enable);
Utilities::triggerFrameChange(window);
@ -149,7 +149,7 @@ bool FramelessHelperWin::isWindowFrameless(const QWindow *window)
if (!window) {
return false;
}
return window->property(_flh_global::_flh_framelessMode_flag).toBool();
return window->property(_flh_global::_flh_framelessEnabled_flag).toBool();
}
void FramelessHelperWin::removeFramelessWindow(QWindow *window)
@ -211,7 +211,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
return false;
}
const QWindow *window = Utilities::findWindow(reinterpret_cast<WId>(msg->hwnd));
if (!window || (window && !window->property(_flh_global::_flh_framelessMode_flag).toBool())) {
if (!window || (window && !window->property(_flh_global::_flh_framelessEnabled_flag).toBool())) {
return false;
}
switch (msg->message) {

View File

@ -53,12 +53,28 @@ void QtAcrylicEffectHelper::install(const QWindow *window)
}
if (m_window != window) {
m_window = const_cast<QWindow *>(window);
connect(m_window, &QWindow::xChanged, this, &QtAcrylicEffectHelper::needsRepaint);
connect(m_window, &QWindow::yChanged, this, &QtAcrylicEffectHelper::needsRepaint);
connect(m_window, &QWindow::activeChanged, this, &QtAcrylicEffectHelper::needsRepaint);
//connect(m_window, &QWindow::visibilityChanged, this, &QtAcrylicEffectHelper::needsRepaint);
connect(m_window, &QWindow::windowStateChanged, this, &QtAcrylicEffectHelper::needsRepaint);
#ifdef Q_OS_WINDOWS
//QtAcrylicWinEventFilter::setup();
#endif
}
}
void QtAcrylicEffectHelper::uninstall()
{
if (m_window) {
#ifdef Q_OS_WINDOWS
//QtAcrylicWinEventFilter::unsetup();
#endif
disconnect(m_window, &QWindow::xChanged, this, &QtAcrylicEffectHelper::needsRepaint);
disconnect(m_window, &QWindow::yChanged, this, &QtAcrylicEffectHelper::needsRepaint);
disconnect(m_window, &QWindow::activeChanged, this, &QtAcrylicEffectHelper::needsRepaint);
//disconnect(m_window, &QWindow::visibilityChanged, this, &QtAcrylicEffectHelper::needsRepaint);
disconnect(m_window, &QWindow::windowStateChanged, this, &QtAcrylicEffectHelper::needsRepaint);
m_window = nullptr;
}
}
@ -157,8 +173,7 @@ void QtAcrylicEffectHelper::paintWindowBackground(QPainter *painter, const QRegi
if (!painter || clip.isEmpty()) {
return;
}
if (!m_window) {
qWarning() << "m_window is null, forgot to call \"QtAcrylicEffectHelper::install()\"?";
if (!checkWindow()) {
return;
}
painter->save();
@ -173,8 +188,7 @@ void QtAcrylicEffectHelper::paintWindowBackground(QPainter *painter, const QRect
if (!painter || !rect.isValid()) {
return;
}
if (!m_window) {
qWarning() << "m_window is null, forgot to call \"QtAcrylicEffectHelper::install()\"?";
if (!checkWindow()) {
return;
}
painter->save();
@ -189,8 +203,7 @@ void QtAcrylicEffectHelper::paintBackground(QPainter *painter, const QRect &rect
if (!painter || !rect.isValid()) {
return;
}
if (!m_window) {
qWarning() << "m_window is null, forgot to call \"QtAcrylicEffectHelper::install()\"?";
if (!checkWindow()) {
return;
}
if (Utilities::shouldUseTraditionalBlur()) {
@ -201,7 +214,7 @@ void QtAcrylicEffectHelper::paintBackground(QPainter *painter, const QRect &rect
} else {
// Emulate blur behind window by blurring the desktop wallpaper.
updateBehindWindowBackground();
painter->drawPixmap(QPoint{0, 0}, m_bluredWallpaper, rect);
painter->drawPixmap(QPoint{0, 0}, m_bluredWallpaper, QRect{m_window->mapToGlobal(QPoint{0, 0}), rect.size()});
}
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->setOpacity(1);
@ -215,8 +228,7 @@ void QtAcrylicEffectHelper::paintWindowFrame(QPainter *painter, const QRect &rec
if (!painter) {
return;
}
if (!m_window) {
qWarning() << "m_window is null, forgot to call \"QtAcrylicEffectHelper::install()\"?";
if (!checkWindow()) {
return;
}
if (m_window->windowState() != Qt::WindowNoState) {
@ -321,3 +333,12 @@ void QtAcrylicEffectHelper::updateBehindWindowBackground()
painter.drawImage(QPoint{0, 0}, buffer);
#endif
}
bool QtAcrylicEffectHelper::checkWindow() const
{
if (m_window) {
return true;
}
qWarning() << "m_window is null, forgot to call \"QtAcrylicEffectHelper::install()\"?";
return false;
}

View File

@ -27,19 +27,15 @@
#include "framelesshelper_global.h"
#include <QtGui/qbrush.h>
class FRAMELESSHELPER_EXPORT QtAcrylicEffectHelper
class FRAMELESSHELPER_EXPORT QtAcrylicEffectHelper : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QtAcrylicEffectHelper)
public:
explicit QtAcrylicEffectHelper();
~QtAcrylicEffectHelper();
void install(const QWindow *window);
void uninstall();
void clearWallpaper();
QBrush getAcrylicBrush() const;
QColor getTintColor() const;
qreal getTintOpacity() const;
@ -48,6 +44,12 @@ public:
QColor getFrameColor() const;
qreal getFrameThickness() const;
public Q_SLOTS:
void install(const QWindow *window);
void uninstall();
void clearWallpaper();
void setTintColor(const QColor &value);
void setTintOpacity(const qreal value);
void setNoiseOpacity(const qreal value);
@ -62,6 +64,10 @@ public:
private:
void paintBackground(QPainter *painter, const QRect &rect);
void updateBehindWindowBackground();
bool checkWindow() const;
Q_SIGNALS:
void needsRepaint();
private:
QWindow *m_window = nullptr;

View File

@ -35,6 +35,9 @@ QtAcrylicItem::QtAcrylicItem(QQuickItem *parent) : QQuickPaintedItem(parent)
if (win) {
m_acrylicHelper.install(win);
m_acrylicHelper.updateAcrylicBrush();
connect(&m_acrylicHelper, &QtAcrylicEffectHelper::needsRepaint, this, [this](){
update();
});
}
});
}

View File

@ -148,6 +148,7 @@ void QtAcrylicWidget::showEvent(QShowEvent *event)
Utilities::setBlurEffectEnabled(win, true);
m_acrylicHelper.install(win);
m_acrylicHelper.updateAcrylicBrush(tintColor());
connect(&m_acrylicHelper, &QtAcrylicEffectHelper::needsRepaint, this, qOverload<>(&QtAcrylicWidget::update));
update();
inited = true;
}
@ -162,19 +163,3 @@ void QtAcrylicWidget::paintEvent(QPaintEvent *event)
}
QWidget::paintEvent(event);
}
void QtAcrylicWidget::changeEvent(QEvent *event)
{
QWidget::changeEvent(event);
switch (event->type()) {
case QEvent::PaletteChange:
m_acrylicHelper.updateAcrylicBrush(tintColor());
break;
case QEvent::ActivationChange:
case QEvent::WindowStateChange:
update();
break;
default:
break;
}
}

View File

@ -72,7 +72,6 @@ Q_SIGNALS:
protected:
void showEvent(QShowEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void changeEvent(QEvent *event) override;
private:
QtAcrylicEffectHelper m_acrylicHelper;

View File

@ -628,7 +628,7 @@ bool Utilities::isWin10OrGreater(const int subVer)
static inline bool forceEnableDwmBlur()
{
return qEnvironmentVariableIsSet(_flh_global::_flh_acrylic_forceDWMBlur_flag);
return qEnvironmentVariableIsSet(_flh_global::_flh_acrylic_forceEnableTraditionalBlur_flag);
}
static inline bool forceDisableWallpaperBlur()
@ -638,7 +638,7 @@ static inline bool forceDisableWallpaperBlur()
static inline bool forceEnableOfficialMSWin10AcrylicBlur()
{
return qEnvironmentVariableIsSet(_flh_global::_flh_acrylic_forceOfficialMSWin10Blur_flag);
return qEnvironmentVariableIsSet(_flh_global::_flh_acrylic_forceEnableOfficialMSWin10AcrylicBlur_flag);
}
static inline bool shouldUseOfficialMSWin10AcrylicBlur()