diff --git a/ksmserver/logout-greeter/CMakeLists.txt b/ksmserver/logout-greeter/CMakeLists.txt --- a/ksmserver/logout-greeter/CMakeLists.txt +++ b/ksmserver/logout-greeter/CMakeLists.txt @@ -10,6 +10,7 @@ KF5::I18n KF5::Package KF5::KDELibs4Support # Solid/PowerManagement + KF5::WaylandClient ${X11_LIBRARIES} ) install(TARGETS ksmserver-logout-greeter DESTINATION ${KDE_INSTALL_LIBEXECDIR}) diff --git a/ksmserver/logout-greeter/main.cpp b/ksmserver/logout-greeter/main.cpp --- a/ksmserver/logout-greeter/main.cpp +++ b/ksmserver/logout-greeter/main.cpp @@ -27,6 +27,12 @@ #include #include "../shutdowndlg.h" +#include + +#include +#include +#include + #include class Greeter : public QObject @@ -43,30 +49,55 @@ private: void adoptScreen(QScreen *screen); void rejected(); + void setupWaylandIntegration(); int m_fd; bool m_shutdownAllowed; bool m_choose; KWorkSpace::ShutdownType m_shutdownType; QVector m_dialogs; + KWayland::Client::PlasmaShell *m_waylandPlasmaShell; }; Greeter::Greeter(int fd, bool shutdownAllowed, bool choose, KWorkSpace::ShutdownType type) : QObject() , m_fd(fd) , m_shutdownAllowed(shutdownAllowed) , m_choose(choose) , m_shutdownType(type) + , m_waylandPlasmaShell(nullptr) { } Greeter::~Greeter() { qDeleteAll(m_dialogs); } +void Greeter::setupWaylandIntegration() +{ + if (!KWindowSystem::isPlatformWayland()) { + return; + } + using namespace KWayland::Client; + ConnectionThread *connection = ConnectionThread::fromApplication(this); + if (!connection) { + return; + } + Registry *registry = new Registry(this); + registry->create(connection); + connect(registry, &Registry::plasmaShellAnnounced, this, + [this, registry] (quint32 name, quint32 version) { + m_waylandPlasmaShell = registry->createPlasmaShell(name, version, this); + } + ); + registry->setup(); + connection->roundtrip(); +} + void Greeter::init() { + setupWaylandIntegration(); foreach (QScreen *screen, qApp->screens()) { adoptScreen(screen); } @@ -76,7 +107,7 @@ void Greeter::adoptScreen(QScreen* screen) { // TODO: last argument is the theme, maybe add command line option for it? - KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownAllowed, m_choose, m_shutdownType, QString()); + KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownAllowed, m_choose, m_shutdownType, QString(), m_waylandPlasmaShell); w->installEventFilter(this); m_dialogs << w; diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h --- a/ksmserver/shutdowndlg.h +++ b/ksmserver/shutdowndlg.h @@ -41,15 +41,24 @@ class FrameSvg; } +namespace KWayland +{ +namespace Client +{ +class PlasmaShell; +class PlasmaShellSurface; +} +} + class QQuickView; // The confirmation dialog class KSMShutdownDlg : public QQuickView { Q_OBJECT public: - KSMShutdownDlg( QWindow* parent, bool maysd, bool choose, KWorkSpace::ShutdownType sdtype, const QString& theme ); + KSMShutdownDlg( QWindow* parent, bool maysd, bool choose, KWorkSpace::ShutdownType sdtype, const QString& theme, KWayland::Client::PlasmaShell *plasmaShell = nullptr ); void init(); bool result() const; @@ -74,14 +83,18 @@ protected: void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; + bool event(QEvent *e) override; private: void rePosition(); + void setupWaylandIntegration(); KWorkSpace::ShutdownType m_shutdownType; QString m_bootOption; QStringList rebootOptions; bool m_result : 1; QString m_theme; + KWayland::Client::PlasmaShell *m_waylandPlasmaShell; + KWayland::Client::PlasmaShellSurface *m_shellSurface = nullptr; }; #endif diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp --- a/ksmserver/shutdowndlg.cpp +++ b/ksmserver/shutdowndlg.cpp @@ -62,19 +62,24 @@ #include #include +#include #include #include +#include +#include + Q_DECLARE_METATYPE(Solid::PowerManagement::SleepState) KSMShutdownDlg::KSMShutdownDlg( QWindow* parent, bool maysd, bool choose, KWorkSpace::ShutdownType sdtype, - const QString& theme) + const QString& theme, KWayland::Client::PlasmaShell *plasmaShell) : QQuickView(parent), m_result(false), - m_theme(theme) + m_theme(theme), + m_waylandPlasmaShell(plasmaShell) // this is a WType_Popup on purpose. Do not change that! Not // having a popup here has severe side effects. { @@ -210,10 +215,51 @@ rePosition(); } +bool KSMShutdownDlg::event(QEvent *e) +{ + if (e->type() == QEvent::PlatformSurface) { + if (auto pe = dynamic_cast(e)) { + switch (pe->surfaceEventType()) { + case QPlatformSurfaceEvent::SurfaceCreated: + setupWaylandIntegration(); + break; + case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: + delete m_shellSurface; + m_shellSurface = nullptr; + break; + } + } + } + return QQuickView::event(e); +} + +void KSMShutdownDlg::setupWaylandIntegration() +{ + if (m_shellSurface) { + // already setup + return; + } + using namespace KWayland::Client; + if (!m_waylandPlasmaShell) { + return; + } + Surface *s = Surface::fromWindow(this); + if (!s) { + return; + } + m_shellSurface = m_waylandPlasmaShell->createSurface(s, this); + // TODO: set a proper window type to indicate to KWin that this is the logout dialog + // maybe we need a dedicated type for it? + m_shellSurface->setPosition(geometry().topLeft()); +} + void KSMShutdownDlg::rePosition() { setPosition(screen()->geometry().center().x() - width() / 2, screen()->geometry().center().y() - height() / 2); + if (m_shellSurface) { + m_shellSurface->setPosition(geometry().topLeft()); + } } void KSMShutdownDlg::slotLogout()