File indexing completed on 2024-05-19 16:33:10
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "../src/client/compositor.h" 0007 #include "../src/client/connection_thread.h" 0008 #include "../src/client/datadevice.h" 0009 #include "../src/client/datadevicemanager.h" 0010 #include "../src/client/dataoffer.h" 0011 #include "../src/client/event_queue.h" 0012 #include "../src/client/keyboard.h" 0013 #include "../src/client/plasmashell.h" 0014 #include "../src/client/plasmawindowmanagement.h" 0015 #include "../src/client/pointer.h" 0016 #include "../src/client/registry.h" 0017 #include "../src/client/seat.h" 0018 #include "../src/client/shell.h" 0019 #include "../src/client/shm_pool.h" 0020 #include "../src/client/surface.h" 0021 // Qt 0022 #include <QDebug> 0023 #include <QFile> 0024 #include <QGuiApplication> 0025 #include <QImage> 0026 #include <QMimeType> 0027 #include <QThread> 0028 // system 0029 #include <unistd.h> 0030 0031 #include <linux/input.h> 0032 0033 using namespace KWayland::Client; 0034 0035 class PanelTest : public QObject 0036 { 0037 Q_OBJECT 0038 public: 0039 explicit PanelTest(QObject *parent = nullptr); 0040 ~PanelTest() override; 0041 0042 void init(); 0043 0044 private: 0045 void setupRegistry(Registry *registry); 0046 void render(); 0047 void showTooltip(const QPointF &pos); 0048 void hideTooltip(); 0049 void moveTooltip(const QPointF &pos); 0050 QThread *m_connectionThread; 0051 ConnectionThread *m_connectionThreadObject; 0052 EventQueue *m_eventQueue = nullptr; 0053 Compositor *m_compositor = nullptr; 0054 Seat *m_seat = nullptr; 0055 Shell *m_shell = nullptr; 0056 ShellSurface *m_shellSurface = nullptr; 0057 ShmPool *m_shm = nullptr; 0058 Surface *m_surface = nullptr; 0059 PlasmaShell *m_plasmaShell = nullptr; 0060 PlasmaShellSurface *m_plasmaShellSurface = nullptr; 0061 PlasmaWindowManagement *m_windowManagement = nullptr; 0062 struct { 0063 Surface *surface = nullptr; 0064 ShellSurface *shellSurface = nullptr; 0065 PlasmaShellSurface *plasmaSurface = nullptr; 0066 bool visible = false; 0067 } m_tooltip; 0068 }; 0069 0070 PanelTest::PanelTest(QObject *parent) 0071 : QObject(parent) 0072 , m_connectionThread(new QThread(this)) 0073 , m_connectionThreadObject(new ConnectionThread()) 0074 { 0075 } 0076 0077 PanelTest::~PanelTest() 0078 { 0079 m_connectionThread->quit(); 0080 m_connectionThread->wait(); 0081 m_connectionThreadObject->deleteLater(); 0082 } 0083 0084 void PanelTest::init() 0085 { 0086 connect( 0087 m_connectionThreadObject, 0088 &ConnectionThread::connected, 0089 this, 0090 [this] { 0091 m_eventQueue = new EventQueue(this); 0092 m_eventQueue->setup(m_connectionThreadObject); 0093 0094 Registry *registry = new Registry(this); 0095 setupRegistry(registry); 0096 }, 0097 Qt::QueuedConnection); 0098 m_connectionThreadObject->moveToThread(m_connectionThread); 0099 m_connectionThread->start(); 0100 0101 m_connectionThreadObject->initConnection(); 0102 } 0103 0104 void PanelTest::showTooltip(const QPointF &pos) 0105 { 0106 if (!m_tooltip.surface) { 0107 m_tooltip.surface = m_compositor->createSurface(this); 0108 m_tooltip.shellSurface = m_shell->createSurface(m_tooltip.surface, this); 0109 if (m_plasmaShell) { 0110 m_tooltip.plasmaSurface = m_plasmaShell->createSurface(m_tooltip.surface, this); 0111 } 0112 } 0113 m_tooltip.shellSurface->setTransient(m_surface, pos.toPoint()); 0114 0115 if (!m_tooltip.visible) { 0116 const QSize size(100, 50); 0117 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0118 buffer->setUsed(true); 0119 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0120 image.fill(Qt::red); 0121 0122 m_tooltip.surface->attachBuffer(*buffer); 0123 m_tooltip.surface->damage(QRect(QPoint(0, 0), size)); 0124 m_tooltip.surface->commit(Surface::CommitFlag::None); 0125 m_tooltip.visible = true; 0126 } 0127 } 0128 0129 void PanelTest::hideTooltip() 0130 { 0131 if (!m_tooltip.visible) { 0132 return; 0133 } 0134 m_tooltip.surface->attachBuffer(Buffer::Ptr()); 0135 m_tooltip.surface->commit(Surface::CommitFlag::None); 0136 m_tooltip.visible = false; 0137 } 0138 0139 void PanelTest::moveTooltip(const QPointF &pos) 0140 { 0141 if (m_tooltip.plasmaSurface) { 0142 m_tooltip.plasmaSurface->setPosition(QPoint(10, 0) + pos.toPoint()); 0143 } 0144 } 0145 0146 void PanelTest::setupRegistry(Registry *registry) 0147 { 0148 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) { 0149 m_compositor = registry->createCompositor(name, version, this); 0150 }); 0151 connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) { 0152 m_shell = registry->createShell(name, version, this); 0153 }); 0154 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) { 0155 m_shm = registry->createShmPool(name, version, this); 0156 }); 0157 connect(registry, &Registry::seatAnnounced, this, [this, registry](quint32 name, quint32 version) { 0158 m_seat = registry->createSeat(name, version, this); 0159 connect(m_seat, &Seat::hasPointerChanged, this, [this](bool has) { 0160 if (!has) { 0161 return; 0162 } 0163 auto p = m_seat->createPointer(this); 0164 connect(p, &Pointer::buttonStateChanged, this, [this](quint32 serial, quint32 time, quint32 button, KWayland::Client::Pointer::ButtonState state) { 0165 Q_UNUSED(time) 0166 Q_UNUSED(serial) 0167 if (!m_windowManagement) { 0168 return; 0169 } 0170 if (state == Pointer::ButtonState::Released) { 0171 return; 0172 } 0173 if (button == BTN_LEFT) { 0174 m_windowManagement->showDesktop(); 0175 } else if (button == BTN_RIGHT) { 0176 m_windowManagement->hideDesktop(); 0177 } 0178 }); 0179 connect(p, &Pointer::entered, this, [this, p](quint32 serial, const QPointF &relativeToSurface) { 0180 Q_UNUSED(serial) 0181 if (p->enteredSurface() == m_surface) { 0182 showTooltip(relativeToSurface); 0183 } 0184 }); 0185 connect(p, &Pointer::motion, this, [this, p](const QPointF &relativeToSurface) { 0186 if (p->enteredSurface() == m_surface) { 0187 moveTooltip(relativeToSurface); 0188 } 0189 }); 0190 connect(p, &Pointer::left, this, [this] { 0191 hideTooltip(); 0192 }); 0193 }); 0194 }); 0195 connect(registry, &Registry::plasmaShellAnnounced, this, [this, registry](quint32 name, quint32 version) { 0196 m_plasmaShell = registry->createPlasmaShell(name, version, this); 0197 }); 0198 connect(registry, &Registry::plasmaWindowManagementAnnounced, this, [this, registry](quint32 name, quint32 version) { 0199 m_windowManagement = registry->createPlasmaWindowManagement(name, version, this); 0200 connect(m_windowManagement, &PlasmaWindowManagement::showingDesktopChanged, this, [](bool set) { 0201 qDebug() << "Showing desktop changed, new state: " << set; 0202 }); 0203 connect(m_windowManagement, &PlasmaWindowManagement::windowCreated, this, [this](PlasmaWindow *w) { 0204 connect(w, &PlasmaWindow::titleChanged, this, [w] { 0205 qDebug() << "Window title changed to: " << w->title(); 0206 }); 0207 connect(w, &PlasmaWindow::activeChanged, this, [w] { 0208 qDebug() << "Window active changed: " << w->isActive(); 0209 }); 0210 connect(w, &PlasmaWindow::maximizedChanged, this, [w] { 0211 qDebug() << "Window maximized changed: " << w->isMaximized(); 0212 }); 0213 connect(w, &PlasmaWindow::maximizedChanged, this, [w] { 0214 qDebug() << "Window minimized changed: " << w->isMinimized(); 0215 }); 0216 connect(w, &PlasmaWindow::keepAboveChanged, this, [w] { 0217 qDebug() << "Window keep above changed: " << w->isKeepAbove(); 0218 }); 0219 connect(w, &PlasmaWindow::keepBelowChanged, this, [w] { 0220 qDebug() << "Window keep below changed: " << w->isKeepBelow(); 0221 }); 0222 connect(w, &PlasmaWindow::onAllDesktopsChanged, this, [w] { 0223 qDebug() << "Window on all desktops changed: " << w->isOnAllDesktops(); 0224 }); 0225 connect(w, &PlasmaWindow::fullscreenChanged, this, [w] { 0226 qDebug() << "Window full screen changed: " << w->isFullscreen(); 0227 }); 0228 connect(w, &PlasmaWindow::demandsAttentionChanged, this, [w] { 0229 qDebug() << "Window demands attention changed: " << w->isDemandingAttention(); 0230 }); 0231 connect(w, &PlasmaWindow::closeableChanged, this, [w] { 0232 qDebug() << "Window is closeable changed: " << w->isCloseable(); 0233 }); 0234 connect(w, &PlasmaWindow::minimizeableChanged, this, [w] { 0235 qDebug() << "Window is minimizeable changed: " << w->isMinimizeable(); 0236 }); 0237 connect(w, &PlasmaWindow::maximizeableChanged, this, [w] { 0238 qDebug() << "Window is maximizeable changed: " << w->isMaximizeable(); 0239 }); 0240 connect(w, &PlasmaWindow::fullscreenableChanged, this, [w] { 0241 qDebug() << "Window is fullscreenable changed: " << w->isFullscreenable(); 0242 }); 0243 connect(w, &PlasmaWindow::iconChanged, this, [w] { 0244 qDebug() << "Window icon changed: " << w->icon().name(); 0245 }); 0246 }); 0247 }); 0248 connect(registry, &Registry::interfacesAnnounced, this, [this] { 0249 Q_ASSERT(m_compositor); 0250 Q_ASSERT(m_seat); 0251 Q_ASSERT(m_shell); 0252 Q_ASSERT(m_shm); 0253 m_surface = m_compositor->createSurface(this); 0254 Q_ASSERT(m_surface); 0255 m_shellSurface = m_shell->createSurface(m_surface, this); 0256 Q_ASSERT(m_shellSurface); 0257 m_shellSurface->setToplevel(); 0258 connect(m_shellSurface, &ShellSurface::sizeChanged, this, &PanelTest::render); 0259 if (m_plasmaShell) { 0260 m_plasmaShellSurface = m_plasmaShell->createSurface(m_surface, this); 0261 m_plasmaShellSurface->setPosition(QPoint(10, 0)); 0262 m_plasmaShellSurface->setRole(PlasmaShellSurface::Role::Panel); 0263 } 0264 render(); 0265 }); 0266 registry->setEventQueue(m_eventQueue); 0267 registry->create(m_connectionThreadObject); 0268 registry->setup(); 0269 } 0270 0271 void PanelTest::render() 0272 { 0273 const QSize &size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(300, 20); 0274 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0275 buffer->setUsed(true); 0276 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0277 image.fill(Qt::blue); 0278 0279 m_surface->attachBuffer(*buffer); 0280 m_surface->damage(QRect(QPoint(0, 0), size)); 0281 m_surface->commit(Surface::CommitFlag::None); 0282 buffer->setUsed(false); 0283 } 0284 0285 int main(int argc, char **argv) 0286 { 0287 QGuiApplication app(argc, argv); 0288 PanelTest client; 0289 client.init(); 0290 0291 return app.exec(); 0292 } 0293 0294 #include "paneltest.moc"