Skip to content

Commit

Permalink
support windows backdrop effect
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardLuo0 committed Feb 12, 2024
1 parent 465a052 commit f3cc30e
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 245 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
build-*
*.pro.user
*.bat
deploy-*
2 changes: 1 addition & 1 deletion Kvantum/kvantummanager/kvantummanager.pro
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ unix|win32 {
}

#VARIABLES
BINDIR = $$PREFIX/bin
BINDIR = $$PREFIX
DATADIR =$$PREFIX/share

DEFINES += DATADIR="qgetenv(\\\"KVANTUM_DATA\\\")"
Expand Down
2 changes: 1 addition & 1 deletion Kvantum/kvantumpreview/kvantumpreview.pro
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ unix|win32 {
}

#VARIABLES
BINDIR = $$PREFIX/bin
BINDIR = $$PREFIX
DATADIR =$$PREFIX/share

DEFINES += DATADIR="qgetenv(\\\"KVANTUM_DATA\\\")"
Expand Down
31 changes: 0 additions & 31 deletions Kvantum/style-hack/KvantumPlugin.cpp

This file was deleted.

18 changes: 11 additions & 7 deletions Kvantum/style-hack/KvantumPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@

#include <QStylePlugin>

#include "Kvantum.h"

namespace Kvantum {
class KvantumPlugin : public QStylePlugin
{
class KvantumPlugin : public QStylePlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "kvantum.json")
public:
QStyle *create(const QString &key);
QStringList keys() const;
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE
"kvantum.json")
public:
QStyle *create(const QString &key) override {
Q_UNUSED(key);
return new Style(false);
};
};
} // namespace Kvantum
} // namespace Kvantum

#endif
1 change: 0 additions & 1 deletion Kvantum/style-hack/style-hack.pro
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ greaterThan(QT_MAJOR_VERSION, 4) {
$$STYLE/rendering.cpp \
$$STYLE/standardIcons.cpp \
$$STYLE/viewItems.cpp \
KvantumPlugin.cpp \
$$STYLE/shortcuthandler.cpp \
$$STYLE/drag/windowmanager.cpp \
$$STYLE/blur/blurhelper.cpp \
Expand Down
4 changes: 3 additions & 1 deletion Kvantum/style/Kvantum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ static inline QString getName(const QColor &col)

Style::Style(bool useDark) : QCommonStyle()
{
isDark = useDark;

opacityTimer_ = opacityTimerOut_ = nullptr;
animationOpacity_ = animationOpacityOut_ = 100;
animationStartState_ = animationStartStateOut_ = "normal";
Expand Down Expand Up @@ -373,7 +375,7 @@ Style::Style(bool useDark) : QCommonStyle()
blurHelper_ = new BlurHelper(this, menuShadow_, tooltipShadow_,
tspec_.menu_blur_radius, tspec_.tooltip_blur_radius,
tspec_.contrast, tspec_.intensity, tspec_.saturation,
hspec_.blur_only_active_window);
hspec_.blur_only_active_window, isDark);
}

cachedOption_ = nullptr;
Expand Down
2 changes: 2 additions & 0 deletions Kvantum/style/Kvantum.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,8 @@ class Style : public QCommonStyle {
// For item views:
mutable QStyleOptionViewItem *cachedOption_;
mutable QRect decorationRect_, displayRect_, checkRect_;

bool isDark = false;
};
}

Expand Down
198 changes: 71 additions & 127 deletions Kvantum/style/blur/blurhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,158 +16,102 @@
*/

#include "blurhelper.h"
#undef DATADIR
#include <Windows.h>
#include <dwmapi.h>
#pragma comment(lib, "Dwmapi.lib")

#include <QDebug>
#include <QEvent>
#include <QMenu>
#include <QFrame>
#include <QMenu>
#include <QWindow>
#include <QtMath>

#ifdef NO_KF
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <QVector>
#endif
#include <QApplication>
#else
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <KWindowEffects>
#endif
#endif

namespace Kvantum {
BlurHelper::BlurHelper (QObject* parent, QList<qreal> menuS, QList<qreal> tooltipS,
int menuBlurRadius, int toolTipBlurRadius,
qreal contrast, qreal intensity, qreal saturation,
bool onlyActiveWindow) : QObject (parent)
{
}
/*************************/
void BlurHelper::registerWidget (QWidget* widget)
{
}
/*************************/
void BlurHelper::unregisterWidget (QWidget* widget)
{
}
/*************************/
bool BlurHelper::isWidgetActive (const QWidget *widget) const
{
return (widget->window()->windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus)
|| widget->window()->windowFlags().testFlag(Qt::X11BypassWindowManagerHint)
|| widget->isActiveWindow()
// make exception for tooltips
|| widget->inherits("QTipLabel")
|| ((widget->windowFlags() & Qt::WindowType_Mask) == Qt::ToolTip
&& !qobject_cast<const QFrame*>(widget)));
}
/*************************/
bool BlurHelper::eventFilter (QObject* object, QEvent* event)
{
// never eat events
return false;
DWM_WINDOW_CORNER_PREFERENCE getWindowsCorner(int radius) {
switch (radius) {
case 0:
return DWMWCP_DEFAULT;
case 1:
return DWMWCP_ROUNDSMALL;
default:
return DWMWCP_ROUND;
}
}
/*************************/
static inline int ceilingInt(const qreal r)
{
int res = qRound(r);
if (r - static_cast<qreal>(res) > static_cast<qreal>(0.1))
res += 1;
return res;

namespace Kvantum {
BlurHelper::BlurHelper(QObject *parent, QList<qreal> menuS,
QList<qreal> tooltipS, int menuBlurRadius,
int toolTipBlurRadius, qreal contrast, qreal intensity,
qreal saturation, bool onlyActiveWindow, bool darkMode)
: QObject(parent), darkMode(darkMode) {
menuCorner = getWindowsCorner(menuBlurRadius);
tooltipsCorner = getWindowsCorner(toolTipBlurRadius);
}

QRegion BlurHelper::blurRegion (QWidget* widget) const
{
if (!widget->isVisible())
return QRegion();
MARGINS margins = {-1};
auto mica = DWM_SYSTEMBACKDROP_TYPE::DWMSBT_TRANSIENTWINDOW;

if (onlyActiveWindow_ && !isWidgetActive(widget))
return QRegion();
int defaultDarkMode = 0;
auto defaultBackdropType = DWM_SYSTEMBACKDROP_TYPE::DWMSBT_AUTO;
auto defaultWindowCorner = DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DEFAULT;

QRect rect = widget->rect();
QRegion wMask = widget->mask();
void BlurHelper::registerWidget(QWidget *widget) {
widget->installEventFilter(this);
}

qreal dpr = 1;
#ifdef NO_KF
if (isX11_) {
QWindow* win = widget->window()->windowHandle();
dpr = win ? win->devicePixelRatio() : qApp->devicePixelRatio();
}
#endif
void BlurHelper::unregisterWidget(QWidget *widget) {
widget->removeEventFilter(this);

/* blurring may not be suitable when the available
painting area is restricted by a widget mask */
if (!wMask.isEmpty()) {
if (wMask != QRegion(rect))
return QRegion();
#ifdef NO_KF
QRect mr = wMask.boundingRect();
if (dpr > static_cast<qreal>(1))
mr.setSize(QSizeF(mr.size() * dpr).toSize());
return mr;
#else
return wMask;
#endif
}
HWND hwnd = (HWND)widget->winId();

QList<qreal> r;
int radius = 0;
if ((qobject_cast<QMenu*>(widget)
&& !widget->testAttribute(Qt::WA_X11NetWmWindowTypeMenu)) // not a detached menu
|| widget->inherits("QComboBoxPrivateContainer")) {
if (!widget->testAttribute(Qt::WA_StyleSheetTarget))
r = menuShadow_;
radius = menuBlurRadius_;
} else if (widget->inherits("QTipLabel")
/* unusual tooltips (like in KDE system settings) */
|| ((widget->windowFlags() & Qt::WindowType_Mask) == Qt::ToolTip
&& !qobject_cast<QFrame*>(widget))) {
if (!widget->testAttribute(Qt::WA_StyleSheetTarget))
r = tooltipShadow_;
radius = toolTipBlurRadius_;
}
DwmSetWindowAttribute(hwnd, DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE,
&defaultDarkMode, sizeof(defaultDarkMode));
DwmSetWindowAttribute(hwnd, DWMWINDOWATTRIBUTE::DWMWA_SYSTEMBACKDROP_TYPE,
&defaultBackdropType, sizeof(defaultBackdropType));
DwmSetWindowAttribute(hwnd,
DWMWINDOWATTRIBUTE::DWMWA_WINDOW_CORNER_PREFERENCE,
&defaultWindowCorner, sizeof(defaultWindowCorner));
}

#ifdef NO_KF
if (dpr > static_cast<qreal>(1)) {
rect.setSize(QSizeF(rect.size() * dpr).toSize());
radius *= qRound(dpr * 2);
bool BlurHelper::eventFilter(QObject *watched, QEvent *event) {
if (watched->isWidgetType() && (event->type() == QEvent::Show ||
event->type() == QEvent::WindowActivate)) {
QWidget *widget = qobject_cast<QWidget *>(watched);
applyBackdrop(widget);
}
#endif
return false;
}

if (!r.isEmpty()) {
rect.adjust(ceilingInt(dpr * r.at(0)),
ceilingInt(dpr * r.at(1)),
-ceilingInt(dpr * r.at(2)),
-ceilingInt(dpr * r.at(3)));
}
void BlurHelper::applyBackdrop(QWidget *widget) {
HWND hwnd = (HWND)widget->winId();

if (radius > 0) {
radius = qMin(radius, qMin(rect.width(), rect.height()) / 2);
QSize rSize(radius, radius);
QRegion topLeft(QRect(rect.topLeft(), 2 * rSize), QRegion::Ellipse);
QRegion topRight(QRect(rect.topLeft() + QPoint(rect.width() - 2 * radius, 0), 2 * rSize),
QRegion::Ellipse);
QRegion bottomLeft(QRect(rect.topLeft() + QPoint(0, rect.height() - 2 * radius), 2 * rSize),
QRegion::Ellipse);
QRegion bottomRight(QRect(rect.topLeft()
+ QPoint(rect.width() - 2 * radius, rect.height() - 2 * radius),
2 * rSize),
QRegion::Ellipse);
return topLeft.united(topRight)
.united(bottomLeft)
.united(bottomRight)
.united(QRect(rect.topLeft() + QPoint(radius, 0),
QSize(rect.width() - 2 * radius, rect.height())))
.united(QRect(rect.topLeft() + QPoint(0, radius),
QSize(rect.width(), rect.height() - 2 * radius)));
} else
return rect;
}
/*************************/
void BlurHelper::update (QWidget* widget) const
{
}
/*************************/
void BlurHelper::clear (QWidget* widget) const
{
}
DwmExtendFrameIntoClientArea(hwnd, &margins);
DwmSetWindowAttribute(hwnd, DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE,
&darkMode, sizeof(darkMode));
DwmSetWindowAttribute(hwnd, DWMWINDOWATTRIBUTE::DWMWA_SYSTEMBACKDROP_TYPE,
&mica, sizeof(mica));

DWM_WINDOW_CORNER_PREFERENCE corner =
DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_DEFAULT;
if (qobject_cast<QMenu *>(widget))
corner = (DWM_WINDOW_CORNER_PREFERENCE)menuCorner;
else if (widget->inherits("QTipLabel")) {
corner = (DWM_WINDOW_CORNER_PREFERENCE)tooltipsCorner;
}
DwmSetWindowAttribute(hwnd,
DWMWINDOWATTRIBUTE::DWMWA_WINDOW_CORNER_PREFERENCE,
&corner, sizeof(corner));
}
} // namespace Kvantum
Loading

0 comments on commit f3cc30e

Please sign in to comment.