8#include "windowshadow.h"
11#include "surfacehelper.h"
13#include <qwayland-shadow.h>
16#include <QExposeEvent>
17#include <QWaylandClientExtension>
19#include <qpa/qplatformwindow_p.h>
21class ShadowManager :
public QWaylandClientExtensionTemplate<ShadowManager>,
public QtWayland::org_kde_kwin_shadow_manager
24 static constexpr int version = 2;
25 explicit ShadowManager(
QObject *parent =
nullptr)
26 : QWaylandClientExtensionTemplate(
version)
31 connect(
this, &QWaylandClientExtension::activeChanged,
this, [
this] {
45 static ShadowManager *instance()
47 static ShadowManager *instance =
new ShadowManager(qGuiApp);
52class Shadow :
public QtWayland::org_kde_kwin_shadow
55 using QtWayland::org_kde_kwin_shadow::org_kde_kwin_shadow;
62WindowShadowTile::WindowShadowTile()
64 connect(Shm::instance(), &Shm::activeChanged,
this, [
this] {
65 if (Shm::instance()->isActive()) {
70WindowShadowTile::~WindowShadowTile()
74bool WindowShadowTile::create()
76 if (!Shm::instance()->isActive()) {
80 buffer = Shm::instance()->createBuffer(image);
84void WindowShadowTile::destroy()
91 KWindowShadowTilePrivate *d = KWindowShadowTilePrivate::get(tile);
92 return static_cast<WindowShadowTile *
>(d);
100 WindowShadowTile *d = WindowShadowTile::get(tile.
data());
102 if (!d->buffer && d->isCreated) {
103 d->buffer = Shm::instance()->createBuffer(d->image);
105 return d->buffer ? d->buffer.get()->object() :
nullptr;
108WindowShadow::WindowShadow()
111WindowShadow::~WindowShadow()
115bool WindowShadow::eventFilter(
QObject *watched,
QEvent *event)
120 if (!internalCreate()) {
121 qCWarning(KWAYLAND_KWS) <<
"Failed to recreate shadow for" <<
window;
128bool WindowShadow::internalCreate()
133 if (!ShadowManager::instance()->isActive()) {
136 auto surface = surfaceForWindow(window);
141 shadow = std::make_unique<Shadow>(ShadowManager::instance()->create(surface));
142 auto waylandWindow =
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>();
144 connect(waylandWindow, &QNativeInterface::Private::QWaylandWindow::surfaceDestroyed,
this, &WindowShadow::internalDestroy,
Qt::UniqueConnection);
147 auto attach = [](
const std::unique_ptr<Shadow> &shadow,
auto attach_func,
const KWindowShadowTile::Ptr &tile) {
148 if (
auto buffer = bufferForTile(tile)) {
149 (*shadow.*attach_func)(buffer);
152 attach(shadow, &Shadow::attach_left, leftTile);
153 attach(shadow, &Shadow::attach_top_left, topLeftTile);
154 attach(shadow, &Shadow::attach_top, topTile);
155 attach(shadow, &Shadow::attach_top_right, topRightTile);
156 attach(shadow, &Shadow::attach_right, rightTile);
157 attach(shadow, &Shadow::attach_bottom_right, bottomRightTile);
158 attach(shadow, &Shadow::attach_bottom, bottomTile);
159 attach(shadow, &Shadow::attach_bottom_left, bottomLeftTile);
161 shadow->set_left_offset(wl_fixed_from_double(padding.left()));
162 shadow->set_top_offset(wl_fixed_from_double(padding.top()));
163 shadow->set_right_offset(wl_fixed_from_double(padding.right()));
164 shadow->set_bottom_offset(wl_fixed_from_double(padding.bottom()));
174bool WindowShadow::create()
176 if (!ShadowManager::instance()->isActive()) {
185void WindowShadow::internalDestroy()
193 if (window &&
window->nativeInterface<QNativeInterface::Private::QWaylandWindow>() && ShadowManager::instance()->isActive()) {
194 if (
auto surface = surfaceForWindow(window)) {
195 ShadowManager::instance()->unset(surface);
206void WindowShadow::destroy()
214#include "windowshadow.moc"
The KWindowShadowTile class provides a platform-indendent shadow tile representation.
KCRASH_EXPORT void initialize()
KDB_EXPORT KDbVersionInfo version()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
void installEventFilter(QObject *filterObj)
T qobject_cast(QObject *object)
void removeEventFilter(QObject *obj)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)