diff --git a/src/windowsystem/CMakeLists.txt b/src/windowsystem/CMakeLists.txt --- a/src/windowsystem/CMakeLists.txt +++ b/src/windowsystem/CMakeLists.txt @@ -3,8 +3,9 @@ plugin.cpp waylandintegration.cpp windoweffects.cpp - windowsystem.cpp windowinfo.cpp + windowshadow.cpp + windowsystem.cpp ) ecm_qt_declare_logging_category(wayland_plugin_SRCS HEADER logging.h IDENTIFIER KWAYLAND_KWS CATEGORY_NAME org.kde.kf5.kwindowsystem.kwayland DEFAULT_SEVERITY Warning) diff --git a/src/windowsystem/plugin.h b/src/windowsystem/plugin.h --- a/src/windowsystem/plugin.h +++ b/src/windowsystem/plugin.h @@ -35,6 +35,8 @@ KWindowEffectsPrivate *createEffects() override; KWindowSystemPrivate *createWindowSystem() override; KWindowInfoPrivate *createWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2) override; + KWindowShadowTilePrivate *createWindowShadowTile() override; + KWindowShadowPrivate *createWindowShadow() override; }; #endif diff --git a/src/windowsystem/plugin.cpp b/src/windowsystem/plugin.cpp --- a/src/windowsystem/plugin.cpp +++ b/src/windowsystem/plugin.cpp @@ -18,6 +18,7 @@ * License along with this library. If not, see . */ #include "plugin.h" +#include "windowshadow.h" #include "windowsystem.h" #include "windoweffects.h" #include "windowinfo.h" @@ -45,3 +46,13 @@ { return new WindowInfo(window, properties, properties2); } + +KWindowShadowTilePrivate *KWaylandPlugin::createWindowShadowTile() +{ + return new WindowShadowTile(); +} + +KWindowShadowPrivate *KWaylandPlugin::createWindowShadow() +{ + return new WindowShadow(); +} diff --git a/src/windowsystem/waylandintegration.h b/src/windowsystem/waylandintegration.h --- a/src/windowsystem/waylandintegration.h +++ b/src/windowsystem/waylandintegration.h @@ -1,6 +1,7 @@ /* * Copyright 2014 Martin Gräßlin * Copyright 2015 Marco Martin + * Copyright 2020 Vlad Zahorodnii * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +36,8 @@ class PlasmaWindowManagement; class PlasmaShell; class Registry; + class ShadowManager; + class ShmPool; class SlideManager; } } @@ -52,19 +55,23 @@ KWayland::Client::BlurManager *waylandBlurManager(); KWayland::Client::ContrastManager *waylandContrastManager(); KWayland::Client::SlideManager *waylandSlideManager(); + KWayland::Client::ShadowManager *waylandShadowManager(); KWayland::Client::Compositor *waylandCompositor() const; KWayland::Client::PlasmaWindowManagement *plasmaWindowManagement(); KWayland::Client::PlasmaShell *waylandPlasmaShell(); + KWayland::Client::ShmPool *waylandShmPool(); private: QPointer m_waylandConnection; QPointer m_waylandCompositor; QPointer m_registry; QPointer m_waylandBlurManager; QPointer m_waylandContrastManager; QPointer m_waylandSlideManager; + QPointer m_waylandShadowManager; QPointer m_wm; QPointer m_waylandPlasmaShell; + QPointer m_waylandShmPool; }; #endif diff --git a/src/windowsystem/waylandintegration.cpp b/src/windowsystem/waylandintegration.cpp --- a/src/windowsystem/waylandintegration.cpp +++ b/src/windowsystem/waylandintegration.cpp @@ -1,6 +1,7 @@ /* * Copyright 2014 Martin Gräßlin * Copyright 2015 Marco Martin + * Copyright 2020 Vlad Zahorodnii * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,6 +33,8 @@ #include #include #include +#include +#include #include @@ -143,6 +146,28 @@ return m_waylandSlideManager; } +KWayland::Client::ShadowManager *WaylandIntegration::waylandShadowManager() +{ + if (!m_waylandShadowManager && m_registry) { + const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Shadow); + + if (wmInterface.name == 0) { + qCWarning(KWAYLAND_KWS) << "This compositor does not support the Shadow interface"; + return nullptr; + } + + m_waylandShadowManager = m_registry->createShadowManager(wmInterface.name, wmInterface.version, qApp); + + connect(m_waylandShadowManager, &KWayland::Client::ShadowManager::removed, this, + [this] () { + m_waylandShadowManager->deleteLater(); + } + ); + } + + return m_waylandShadowManager; +} + KWayland::Client::Compositor *WaylandIntegration::waylandCompositor() const { return m_waylandCompositor; @@ -208,3 +233,24 @@ } return m_waylandPlasmaShell; } + +KWayland::Client::ShmPool *WaylandIntegration::waylandShmPool() +{ + if (!m_waylandShmPool && m_registry) { + const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Shm); + + if (wmInterface.name == 0) { + return nullptr; + } + + m_waylandShmPool = m_registry->createShmPool(wmInterface.name, wmInterface.version, qApp); + + connect(m_waylandShmPool, &KWayland::Client::ShmPool::removed, this, + [this] () { + m_waylandShmPool->deleteLater(); + } + ); + } + + return m_waylandShmPool; +} diff --git a/src/windowsystem/plugin.cpp b/src/windowsystem/windowshadow.h copy from src/windowsystem/plugin.cpp copy to src/windowsystem/windowshadow.h --- a/src/windowsystem/plugin.cpp +++ b/src/windowsystem/windowshadow.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Martin Gräßlin + * Copyright 2020 Vlad Zahorodnii * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,31 +17,32 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ -#include "plugin.h" -#include "windowsystem.h" -#include "windoweffects.h" -#include "windowinfo.h" -KWaylandPlugin::KWaylandPlugin(QObject *parent) - : KWindowSystemPluginInterface(parent) -{ -} +#ifndef WINDOWSHADOW_H +#define WINDOWSHADOW_H -KWaylandPlugin::~KWaylandPlugin() -{ -} +#include +#include +#include -KWindowEffectsPrivate *KWaylandPlugin::createEffects() +class WindowShadowTile final : public KWindowShadowTilePrivate { - return new WindowEffects(); -} +public: + bool create() noexcept override; + void destroy() noexcept override; -KWindowSystemPrivate *KWaylandPlugin::createWindowSystem() -{ - return new WindowSystem(); -} + static WindowShadowTile *get(const KWindowShadowTile *tile) noexcept; -KWindowInfoPrivate *KWaylandPlugin::createWindowInfo(WId window, NET::Properties properties, NET::Properties2 properties2) + KWayland::Client::Buffer::Ptr buffer; +}; + +class WindowShadow final : public KWindowShadowPrivate { - return new WindowInfo(window, properties, properties2); -} +public: + bool create() noexcept override; + void destroy() noexcept override; + + QPointer shadow; +}; + +#endif // WINDOWSHADOW_H diff --git a/src/windowsystem/windowshadow.cpp b/src/windowsystem/windowshadow.cpp new file mode 100644 --- /dev/null +++ b/src/windowsystem/windowshadow.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2020 Vlad Zahorodnii + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "windowshadow.h" +#include "waylandintegration.h" + +#include +#include + +bool WindowShadowTile::create() +{ + KWayland::Client::ShmPool *shmPool = WaylandIntegration::self()->waylandShmPool(); + if (!shmPool) { + return false; + } + buffer = shmPool->createBuffer(image); + return true; +} + +void WindowShadowTile::destroy() +{ + buffer = nullptr; +} + +WindowShadowTile *WindowShadowTile::get(const KWindowShadowTile *tile) +{ + KWindowShadowTilePrivate *d = KWindowShadowTilePrivate::get(tile); + return static_cast(d); +} + +static KWayland::Client::Buffer::Ptr bufferForTile(const KWindowShadowTile::Ptr &tile) +{ + if (!tile) { + return KWayland::Client::Buffer::Ptr(); + } + WindowShadowTile *d = WindowShadowTile::get(tile.data()); + return d->buffer; +} + +bool WindowShadow::create() +{ + KWayland::Client::ShadowManager *shadowManager = WaylandIntegration::self()->waylandShadowManager(); + if (!shadowManager) { + return false; + } + KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(window); + if (!surface) { + return false; + } + + shadow = shadowManager->createShadow(surface, surface); + shadow->attachLeft(bufferForTile(leftTile)); + shadow->attachTopLeft(bufferForTile(topLeftTile)); + shadow->attachTop(bufferForTile(topTile)); + shadow->attachTopRight(bufferForTile(topRightTile)); + shadow->attachRight(bufferForTile(rightTile)); + shadow->attachBottomRight(bufferForTile(bottomRightTile)); + shadow->attachBottom(bufferForTile(bottomTile)); + shadow->attachBottomLeft(bufferForTile(bottomLeftTile)); + shadow->setOffsets(padding); + shadow->commit(); + + surface->commit(KWayland::Client::Surface::CommitFlag::None); + + return true; +} + +void WindowShadow::destroy() +{ + if (!shadow) { + return; + } + KWayland::Client::ShadowManager *shadowManager = WaylandIntegration::self()->waylandShadowManager(); + if (!shadowManager) { + return; + } + KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(window); + if (!surface) { + return; + } + shadowManager->removeShadow(surface); + surface->commit(KWayland::Client::Surface::CommitFlag::None); + shadow = nullptr; +}