[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.
wilder-5.14
Martin Gräßlin 10 years ago
parent 1dbaf2b8c5
commit c6bb9347f0
  1. 1
      krunner/CMakeLists.txt
  2. 59
      krunner/view.cpp
  3. 10
      krunner/view.h

@ -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}")

@ -42,13 +42,21 @@
#include <KPackage/Package>
#include <KPackage/PackageLoader>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h>
#include <KWayland/Client/plasmashell.h>
#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<QQuickItem *>(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<QPlatformSurfaceEvent*>(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<QMoveEvent *>(event);
m_plasmaShellSurface->setPosition(me->pos());
}
return retval;
}

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

Loading…
Cancel
Save