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; };