MauiKit Controls

linux/blurhelper/windowblur.cpp
1/*
2 * Copyright (C) 2021 CutefishOS Team.
3 *
4 * Author: cutefish <cutefishos@foxmail.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "windowblur.h"
21
22#include <QApplication>
23#include <QPainterPath>
24#include <QScreen>
25
26#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
27#include <QX11Info>
28#endif
29
30#include <xcb/xcb.h>
31#include <xcb/shape.h>
32#include <xcb/xcb_icccm.h>
33#include <KWindowSystem>
34#include <KWindowEffects>
35#include "style.h"
36
37WindowBlur::WindowBlur(QObject *parent) noexcept
38: QObject(parent)
39, m_view(nullptr)
40, m_enabled(false)
41, m_windowRadius(0.0)
42{
43}
44
45WindowBlur::~WindowBlur()
46{
47}
48
49void WindowBlur::classBegin()
50{
51}
52
53void WindowBlur::componentComplete()
54{
55 Style::instance()->setTranslucencyAvailable(m_enabled);
56 updateBlur();
57}
58
59void WindowBlur::setView(QWindow *view)
60{
61 if (view != m_view) {
62 m_view = view;
63 updateBlur();
64 Q_EMIT viewChanged();
65
66 connect(m_view, &QWindow::visibleChanged, this, &WindowBlur::onViewVisibleChanged);
67 }
68}
69
70QWindow* WindowBlur::view() const
71{
72 return m_view;
73}
74
75void WindowBlur::setGeometry(const QRect &rect)
76{
77 if (rect != m_rect) {
78 m_rect = rect;
79
80
81 updateBlur();
82
83 Q_EMIT geometryChanged();
84 }
85}
86
87QRect WindowBlur::geometry() const
88{
89 return m_rect;
90}
91
92void WindowBlur::setEnabled(bool enabled)
93{
94 if (enabled != m_enabled) {
95 m_enabled = enabled;
96 updateBlur();
97 Q_EMIT enabledChanged();
98 }
99}
100
101bool WindowBlur::enabled() const
102{
103 return m_enabled;
104}
105
106void WindowBlur::setWindowRadius(qreal radius)
107{
108 if (radius != m_windowRadius) {
109 m_windowRadius = radius;
110
111 updateBlur();
112
113 Q_EMIT windowRadiusChanged();
114 }
115}
116
117qreal WindowBlur::windowRadius() const
118{
119 return m_windowRadius;
120}
121
122void WindowBlur::onViewVisibleChanged(bool visible)
123{
124 if (visible)
125 updateBlur();
126}
127
128void WindowBlur::updateBlur()
129{
130 if (!m_view)
131 return;
132
134 {
135 qDebug() << "SETTING BLURRED WINDOW BG WAYLAND KDE;" << m_enabled << m_view;
136 KWindowEffects::enableBlurBehind(m_view, m_enabled, m_rect);
138 return;
139 }
140
141#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
142 xcb_connection_t *c = QX11Info::connection();
143 if (!c)
144 return;
145
146 const QByteArray effectName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION");
147 xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c, false, effectName.length(), effectName.constData());
148 QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> atom(xcb_intern_atom_reply(c, atomCookie, nullptr));
149 if (!atom)
150 return;
151
152 if (m_enabled) {
153 qreal devicePixelRatio = m_view->screen()->devicePixelRatio();
155 path.addRoundedRect(QRect(QPoint(0, 0), m_view->size() * devicePixelRatio),
156 m_windowRadius * devicePixelRatio,
157 m_windowRadius * devicePixelRatio);
159 foreach (const QPolygonF &polygon, path.toFillPolygons()) {
160 QRegion region = polygon.toPolygon();
161 for (auto i = region.begin(); i != region.end(); ++i) {
162 data << i->x() << i->y() << i->width() << i->height();
163 }
164 }
165
166 xcb_change_property(c, XCB_PROP_MODE_REPLACE, m_view->winId(), atom->atom, XCB_ATOM_CARDINAL,
167 32, data.size(), data.constData());
168
169 } else {
170 xcb_delete_property(c, m_view->winId(), atom->atom);
171 }
172#endif
173}
static bool isPlatformWayland()
QString path(const QString &relativePath)
void enableBlurBehind(QWindow *window, bool enable=true, const QRegion &region=QRegion())
void enableBackgroundContrast(QWindow *window, bool enable=true, qreal contrast=1, qreal intensity=1, qreal saturation=1, const QRegion &region=QRegion())
const char * constData() const const
qsizetype length() const const
const_pointer constData() const const
qsizetype size() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QPolygon toPolygon() const const
const_iterator begin() const const
const_iterator end() const const
QScreen * screen() const const
virtual QSize size() const const override
void visibleChanged(bool arg)
WId winId() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.