File indexing completed on 2024-05-12 17:00:18
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> 0004 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "waylandintegration.h" 0010 #include "logging.h" 0011 0012 #include <KWayland/Client/blur.h> 0013 #include <KWayland/Client/compositor.h> 0014 #include <KWayland/Client/connection_thread.h> 0015 #include <KWayland/Client/contrast.h> 0016 #include <KWayland/Client/plasmashell.h> 0017 #include <KWayland/Client/plasmawindowmanagement.h> 0018 #include <KWayland/Client/region.h> 0019 #include <KWayland/Client/registry.h> 0020 #include <KWayland/Client/shadow.h> 0021 #include <KWayland/Client/shm_pool.h> 0022 #include <KWayland/Client/slide.h> 0023 #include <KWayland/Client/surface.h> 0024 0025 #include <KWindowSystem> 0026 0027 #include "waylandxdgactivationv1_p.h" 0028 #include <QGuiApplication> 0029 0030 class WaylandIntegrationSingleton 0031 { 0032 public: 0033 WaylandIntegration self; 0034 }; 0035 0036 Q_GLOBAL_STATIC(WaylandIntegrationSingleton, privateWaylandIntegrationSelf) 0037 0038 WaylandIntegration::WaylandIntegration() 0039 : QObject() 0040 { 0041 setupKWaylandIntegration(); 0042 } 0043 0044 WaylandIntegration::~WaylandIntegration() 0045 { 0046 } 0047 0048 void WaylandIntegration::setupKWaylandIntegration() 0049 { 0050 using namespace KWayland::Client; 0051 m_waylandConnection = ConnectionThread::fromApplication(this); 0052 if (!m_waylandConnection) { 0053 qCWarning(KWAYLAND_KWS) << "Failed getting Wayland connection from QPA"; 0054 return; 0055 } 0056 m_registry = new Registry(qApp); 0057 connect(m_registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this](const QByteArray &interfaceName, quint32 name, quint32 version) { 0058 if (interfaceName != xdg_activation_v1_interface.name) 0059 return; 0060 0061 m_activationInterface = {name, version}; 0062 }); 0063 m_registry->create(m_waylandConnection); 0064 m_waylandCompositor = Compositor::fromApplication(this); 0065 0066 m_registry->setup(); 0067 m_waylandConnection->roundtrip(); 0068 } 0069 0070 WaylandIntegration *WaylandIntegration::self() 0071 { 0072 return &privateWaylandIntegrationSelf()->self; 0073 } 0074 0075 KWayland::Client::Registry *WaylandIntegration::registry() const 0076 { 0077 return m_registry; 0078 } 0079 0080 KWayland::Client::ConnectionThread *WaylandIntegration::waylandConnection() const 0081 { 0082 return m_waylandConnection; 0083 } 0084 0085 KWayland::Client::BlurManager *WaylandIntegration::waylandBlurManager() 0086 { 0087 if (!m_waylandBlurManager && m_registry) { 0088 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Blur); 0089 0090 if (wmInterface.name == 0) { 0091 return nullptr; 0092 } 0093 0094 m_waylandBlurManager = m_registry->createBlurManager(wmInterface.name, wmInterface.version, qApp); 0095 0096 connect(m_waylandBlurManager, &KWayland::Client::BlurManager::removed, this, [this]() { 0097 m_waylandBlurManager->deleteLater(); 0098 }); 0099 } 0100 0101 return m_waylandBlurManager; 0102 } 0103 0104 KWayland::Client::ContrastManager *WaylandIntegration::waylandContrastManager() 0105 { 0106 if (!m_waylandContrastManager && m_registry) { 0107 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Contrast); 0108 0109 if (wmInterface.name == 0) { 0110 return nullptr; 0111 } 0112 0113 m_waylandContrastManager = m_registry->createContrastManager(wmInterface.name, wmInterface.version, qApp); 0114 0115 connect(m_waylandContrastManager, &KWayland::Client::ContrastManager::removed, this, [this]() { 0116 m_waylandContrastManager->deleteLater(); 0117 }); 0118 } 0119 return m_waylandContrastManager; 0120 } 0121 0122 KWayland::Client::SlideManager *WaylandIntegration::waylandSlideManager() 0123 { 0124 if (!m_waylandSlideManager && m_registry) { 0125 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Slide); 0126 0127 if (wmInterface.name == 0) { 0128 return nullptr; 0129 } 0130 0131 m_waylandSlideManager = m_registry->createSlideManager(wmInterface.name, wmInterface.version, qApp); 0132 0133 connect(m_waylandSlideManager, &KWayland::Client::SlideManager::removed, this, [this]() { 0134 m_waylandSlideManager->deleteLater(); 0135 }); 0136 } 0137 0138 return m_waylandSlideManager; 0139 } 0140 0141 KWayland::Client::ShadowManager *WaylandIntegration::waylandShadowManager() 0142 { 0143 if (!m_waylandShadowManager && m_registry) { 0144 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Shadow); 0145 0146 if (wmInterface.name == 0) { 0147 qCWarning(KWAYLAND_KWS) << "This compositor does not support the Shadow interface"; 0148 return nullptr; 0149 } 0150 0151 m_waylandShadowManager = m_registry->createShadowManager(wmInterface.name, wmInterface.version, qApp); 0152 0153 connect(m_waylandShadowManager, &KWayland::Client::ShadowManager::removed, this, [this]() { 0154 m_waylandShadowManager->deleteLater(); 0155 }); 0156 } 0157 0158 return m_waylandShadowManager; 0159 } 0160 0161 KWayland::Client::Compositor *WaylandIntegration::waylandCompositor() const 0162 { 0163 return m_waylandCompositor; 0164 } 0165 0166 KWayland::Client::PlasmaWindowManagement *WaylandIntegration::plasmaWindowManagement() 0167 { 0168 using namespace KWayland::Client; 0169 0170 if (!m_wm && m_registry) { 0171 const Registry::AnnouncedInterface wmInterface = m_registry->interface(Registry::Interface::PlasmaWindowManagement); 0172 0173 if (wmInterface.name == 0) { 0174 qCWarning(KWAYLAND_KWS) << "This compositor does not support the Plasma Window Management interface"; 0175 return nullptr; 0176 } 0177 0178 m_wm = m_registry->createPlasmaWindowManagement(wmInterface.name, wmInterface.version, qApp); 0179 connect(m_wm, &PlasmaWindowManagement::showingDesktopChanged, KWindowSystem::self(), &KWindowSystem::showingDesktopChanged); 0180 qCDebug(KWAYLAND_KWS) << "Plasma Window Management interface bound"; 0181 0182 connect(m_wm, &KWayland::Client::PlasmaWindowManagement::removed, this, [this]() { 0183 m_wm->deleteLater(); 0184 }); 0185 } 0186 0187 return m_wm; 0188 } 0189 0190 KWayland::Client::PlasmaShell *WaylandIntegration::waylandPlasmaShell() 0191 { 0192 if (!m_waylandPlasmaShell && m_registry) { 0193 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); 0194 0195 if (wmInterface.name == 0) { 0196 return nullptr; 0197 } 0198 0199 m_waylandPlasmaShell = m_registry->createPlasmaShell(wmInterface.name, wmInterface.version, qApp); 0200 } 0201 return m_waylandPlasmaShell; 0202 } 0203 0204 KWayland::Client::ShmPool *WaylandIntegration::createShmPool() 0205 { 0206 if (m_registry) { 0207 const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Shm); 0208 0209 if (wmInterface.name == 0) { 0210 return nullptr; 0211 } 0212 0213 return m_registry->createShmPool(wmInterface.name, wmInterface.version); 0214 } 0215 0216 return nullptr; 0217 } 0218 0219 WaylandXdgActivationV1 *WaylandIntegration::activation() 0220 { 0221 if (!m_activation && m_registry && m_activationInterface.name) { 0222 m_activation = new WaylandXdgActivationV1(*m_registry, m_activationInterface.name, m_activationInterface.version); 0223 } 0224 return m_activation; 0225 }