From c6bb9347f0090066e5fa37fdbb6a2594408c3ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 8 Mar 2016 18:30:18 +0100 Subject: [PATCH] [krunner] Make it work on Wayland Checks whether a PlasmaShell interface is available, if so it listens on PlatformSurface events to create/destroy a PlasmaShellSurface and on move events the position is updated on the PlasmaShellSurface. --- krunner/CMakeLists.txt | 1 + krunner/view.cpp | 59 +++++++++++++++++++++++++++++++++++++++++- krunner/view.h | 10 +++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/krunner/CMakeLists.txt b/krunner/CMakeLists.txt index 4c0431c34..3b0c46af8 100644 --- a/krunner/CMakeLists.txt +++ b/krunner/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(krunner KF5::WindowSystem KF5::ConfigWidgets KF5::Crash + KF5::WaylandClient ) target_compile_definitions(krunner PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") diff --git a/krunner/view.cpp b/krunner/view.cpp index 84567cc37..99da6f804 100644 --- a/krunner/view.cpp +++ b/krunner/view.cpp @@ -42,13 +42,21 @@ #include #include +#include +#include +#include +#include + #include "appadaptor.h" View::View(QWindow *) : PlasmaQuick::Dialog(), m_offset(.5), - m_floating(false) + m_floating(false), + m_plasmaShell(nullptr), + m_plasmaShellSurface(nullptr) { + initWayland(); setClearBeforeRendering(true); setColor(QColor(Qt::transparent)); setFlags(Qt::FramelessWindowHint); @@ -138,6 +146,31 @@ View::~View() { } +void View::initWayland() +{ + if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) { + return; + } + using namespace KWayland::Client; + auto connection = ConnectionThread::fromApplication(this); + if (!connection) { + return; + } + Registry *registry = new Registry(this); + registry->create(connection); + QObject::connect(registry, &Registry::interfacesAnnounced, this, + [registry, this] { + const auto interface = registry->interface(Registry::Interface::PlasmaShell); + if (interface.name != 0) { + m_plasmaShell = registry->createPlasmaShell(interface.name, interface.version, this); + } + } + ); + + registry->setup(); + connection->roundtrip(); +} + void View::objectIncubated() { setMainItem(qobject_cast(m_qmlObj->rootObject())); @@ -198,6 +231,30 @@ bool View::event(QEvent *event) if (setState) { KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::KeepAbove | NET::StaysOnTop); } + + if (m_plasmaShell && event->type() == QEvent::PlatformSurface) { + if (auto e = dynamic_cast(event)) { + using namespace KWayland::Client; + switch (e->surfaceEventType()) { + case QPlatformSurfaceEvent::SurfaceCreated: { + Surface *s = Surface::fromWindow(this); + if (!s) { + return false; + } + m_plasmaShellSurface = m_plasmaShell->createSurface(s, this); + break; + } + case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: + delete m_plasmaShellSurface; + m_plasmaShellSurface = nullptr; + break; + } + } + } else if (m_plasmaShellSurface && event->type() == QEvent::Move) { + QMoveEvent *me = static_cast(event); + m_plasmaShellSurface->setPosition(me->pos()); + } + return retval; } diff --git a/krunner/view.h b/krunner/view.h index e73a4197a..e9d2e4a73 100644 --- a/krunner/view.h +++ b/krunner/view.h @@ -27,6 +27,13 @@ namespace KDeclarative { class QmlObject; } +namespace KWayland { + namespace Client { + class PlasmaShell; + class PlasmaShellSurface; + } +} + class ViewPrivate; class View : public PlasmaQuick::Dialog @@ -73,12 +80,15 @@ protected Q_SLOTS: void slotFocusWindowChanged(); private: + void initWayland(); QPoint m_customPos; KDeclarative::QmlObject *m_qmlObj; KConfigGroup m_config; qreal m_offset; bool m_floating : 1; QStringList m_history; + KWayland::Client::PlasmaShell *m_plasmaShell; + KWayland::Client::PlasmaShellSurface *m_plasmaShellSurface; };