|
|
|
|
@ -36,6 +36,8 @@
|
|
|
|
|
|
|
|
|
|
// Qt
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
#include <QScreen>
|
|
|
|
|
#include <QRect>
|
|
|
|
|
#include <QVariant>
|
|
|
|
|
#include <QEvent>
|
|
|
|
|
#include <QPainterPath>
|
|
|
|
|
@ -110,3 +112,41 @@ void BlurHelper::update(QWidget *widget) const
|
|
|
|
|
widget->update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BlurHelper::enableBlurBehind(QWidget *widget, bool enable, qreal windowRadius)
|
|
|
|
|
{
|
|
|
|
|
if (!widget)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
xcb_connection_t *c = QX11Info::connection();
|
|
|
|
|
if (!c)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const QByteArray effectName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION");
|
|
|
|
|
xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c, false, effectName.length(), effectName.constData());
|
|
|
|
|
QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> atom(xcb_intern_atom_reply(c, atomCookie, nullptr));
|
|
|
|
|
if (!atom)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (enable) {
|
|
|
|
|
qreal devicePixelRatio = widget->screen()->devicePixelRatio();
|
|
|
|
|
QPainterPath path;
|
|
|
|
|
path.addRoundedRect(QRectF(QPoint(0, 0), widget->size() * devicePixelRatio),
|
|
|
|
|
windowRadius * devicePixelRatio,
|
|
|
|
|
windowRadius * devicePixelRatio);
|
|
|
|
|
QVector<uint32_t> data;
|
|
|
|
|
for (const QPolygonF &polygon : path.toFillPolygons()) {
|
|
|
|
|
QRegion region = polygon.toPolygon();
|
|
|
|
|
for (auto i = region.begin(); i != region.end(); ++i) {
|
|
|
|
|
data << i->x() << i->y() << i->width() << i->height();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xcb_change_property(c, XCB_PROP_MODE_REPLACE, widget->winId(),
|
|
|
|
|
atom->atom, XCB_ATOM_CARDINAL,
|
|
|
|
|
32, data.size(), data.constData());
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
xcb_delete_property(c, widget->winId(), atom->atom);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|