Use blur instead of Acrylic on Win10.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-10-17 20:14:22 +08:00
parent 226bc52ece
commit d3f58ae98f
3 changed files with 54 additions and 6 deletions

View File

@ -25,12 +25,15 @@
#include "widget.h"
#include "../../winnativeeventfilter.h"
#include "ui_widget.h"
#include <QColorDialog>
#include <QOperatingSystemVersion>
#include <QStyleOption>
namespace {
const char useNativeTitleBar[] = "WNEF_USE_NATIVE_TITLE_BAR";
const char preserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
const char forceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10";
void *getRawHandle(QWidget *widget)
{
@ -48,12 +51,20 @@ void updateWindow(QWidget *widget)
}
}
bool isGreaterThanWin10_1803()
{
return QOperatingSystemVersion::current()
>= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 17134);
}
} // namespace
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
ui->forceAcrylicCB->setEnabled(isGreaterThanWin10_1803());
connect(ui->minimizeButton, &QPushButton::clicked, this, &Widget::showMinimized);
connect(ui->maximizeButton, &QPushButton::clicked, this, [this]() {
if (isMaximized()) {
@ -96,9 +107,30 @@ Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
updateWindow(this);
});
connect(ui->blurEffectCB, &QCheckBox::stateChanged, this, [this](int state) {
WinNativeEventFilter::setBlurEffectEnabled(getRawHandle(this), state == Qt::Checked);
const bool enable = state == Qt::Checked;
QColor color = QColor(255, 255, 255, 0);
if (isGreaterThanWin10_1803() && ui->forceAcrylicCB->isChecked()) {
if (enable) {
color = QColorDialog::getColor(color,
this,
tr("Please select a gradient color"),
QColorDialog::ShowAlphaChannel);
}
}
WinNativeEventFilter::setBlurEffectEnabled(getRawHandle(this), enable, color);
updateWindow(this);
});
connect(ui->forceAcrylicCB, &QCheckBox::stateChanged, this, [this](int state) {
if (state == Qt::Checked) {
qputenv(forceUseAcrylicEffect, "1");
} else {
qunsetenv(forceUseAcrylicEffect);
}
if (ui->blurEffectCB->isChecked()) {
ui->blurEffectCB->click();
ui->blurEffectCB->click();
}
});
connect(ui->resizableCB, &QCheckBox::stateChanged, this, [this](int state) {
const bool enable = state == Qt::Checked;
ui->maximizeButton->setEnabled(enable);

View File

@ -313,6 +313,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="forceAcrylicCB">
<property name="text">
<string>Force enabling Acrylic effect</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="resizableCB">
<property name="text">

View File

@ -2378,7 +2378,6 @@ bool WinNativeEventFilter::setBlurEffectEnabled(void *handle,
if (isWin8OrGreater() && coreData()->m_lpSetWindowCompositionAttribute) {
ACCENT_POLICY accentPolicy;
SecureZeroMemory(&accentPolicy, sizeof(accentPolicy));
accentPolicy.GradientColor = gradientColor.rgba();
WINDOWCOMPOSITIONATTRIBDATA wcaData;
SecureZeroMemory(&wcaData, sizeof(wcaData));
wcaData.Attrib = WCA_ACCENT_POLICY;
@ -2386,10 +2385,20 @@ bool WinNativeEventFilter::setBlurEffectEnabled(void *handle,
wcaData.cbData = sizeof(accentPolicy);
if (enabled) {
if (isWin10OrGreater(17134)) {
// Windows 10, version 1803 (10.0.17134)
// It's not allowed to enable the Acrylic effect for Win32
// applications until Win10 1803.
accentPolicy.AccentState = ACCENT_ENABLE_ACRYLICBLURBEHIND;
// Enabling the Acrylic effect for Win32 windows is
// very buggy and it's a bug of Windows 10 itself so
// it's not fixable from my side.
if (qEnvironmentVariableIsSet("WNEF_FORCE_ACRYLIC_ON_WIN10")) {
// Windows 10, version 1803 (10.0.17134)
// It's not allowed to enable the Acrylic effect for Win32
// applications until Win10 1803.
accentPolicy.AccentState = ACCENT_ENABLE_ACRYLICBLURBEHIND;
const QColor color = gradientColor.isValid() ? gradientColor
: QColor(255, 255, 255, 0);
accentPolicy.GradientColor = color.rgba();
} else {
accentPolicy.AccentState = ACCENT_ENABLE_BLURBEHIND;
}
} else if (isWin10OrGreater(10240)) {
// Windows 10, version 1507 (10.0.10240)
// The initial version of Win10.