File indexing completed on 2024-04-28 16:54:46

0001 /*
0002     ksmserver - the KDE session management server
0003 
0004     SPDX-FileCopyrightText: 2016 Martin Graesslin <mgraesslin@kde.org>
0005     SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org>
0006 
0007     SPDX-License-Identifier: MIT
0008 */
0009 
0010 #include "greeter.h"
0011 
0012 #include <QApplication>
0013 #include <QDebug>
0014 #include <QScreen>
0015 
0016 #include "shutdowndlg.h"
0017 
0018 #include "logoutpromptadaptor.h"
0019 
0020 #include <KQuickAddons/QtQuickSettings>
0021 #include <KWindowSystem>
0022 #include <LayerShellQt/Shell>
0023 
0024 Greeter::Greeter(const KPackage::Package &package)
0025     : QObject()
0026     , m_package(package)
0027 {
0028     new LogoutPromptAdaptor(this);
0029     QDBusConnection::sessionBus().registerObject(QStringLiteral("/LogoutPrompt"), this);
0030     QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.LogoutPrompt"));
0031 }
0032 
0033 Greeter::~Greeter()
0034 {
0035     qDeleteAll(m_dialogs);
0036 }
0037 
0038 void Greeter::setupWaylandIntegration()
0039 {
0040     if (!KWindowSystem::isPlatformWayland() || m_windowed) {
0041         return;
0042     }
0043     LayerShellQt::Shell::useLayerShell();
0044 }
0045 
0046 void Greeter::init()
0047 {
0048     setupWaylandIntegration();
0049     const auto screens = qApp->screens();
0050     for (QScreen *screen : screens) {
0051         adoptScreen(screen);
0052     }
0053     connect(qApp, &QGuiApplication::screenAdded, this, &Greeter::adoptScreen);
0054     m_running = true;
0055 }
0056 
0057 void Greeter::enableWindowed()
0058 {
0059     m_windowed = true;
0060     promptLogout();
0061 }
0062 
0063 void Greeter::adoptScreen(QScreen *screen)
0064 {
0065     if (screen->geometry().isNull()) {
0066         return;
0067     }
0068     // TODO: last argument is the theme, maybe add command line option for it?
0069     KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownType, screen);
0070     w->setWindowed(m_windowed);
0071     w->installEventFilter(this);
0072     m_dialogs << w;
0073 
0074     QObject::connect(screen, &QObject::destroyed, w, [w, this] {
0075         m_dialogs.removeOne(w);
0076         w->deleteLater();
0077     });
0078     connect(w, &KSMShutdownDlg::rejected, this, &Greeter::rejected);
0079 
0080     connect(w, &KSMShutdownDlg::accepted, this, []() {
0081         QApplication::exit(1);
0082     });
0083 
0084     w->setGeometry(screen->geometry());
0085     w->init(m_package);
0086 }
0087 
0088 void Greeter::rejected()
0089 {
0090     QApplication::exit(1);
0091 }
0092 
0093 bool Greeter::eventFilter(QObject *watched, QEvent *event)
0094 {
0095     if (qobject_cast<KSMShutdownDlg *>(watched)) {
0096         if (event->type() == QEvent::MouseButtonPress) {
0097             // check that the position is on no window
0098             QMouseEvent *me = static_cast<QMouseEvent *>(event);
0099             for (auto it = m_dialogs.constBegin(); it != m_dialogs.constEnd(); ++it) {
0100                 if ((*it)->geometry().contains(me->globalPos())) {
0101                     return false;
0102                 }
0103             }
0104             // click outside, close
0105             rejected();
0106         }
0107     }
0108     return false;
0109 }
0110 
0111 void Greeter::promptLogout()
0112 {
0113     if (m_running) {
0114         return;
0115     }
0116     m_shutdownType = KWorkSpace::ShutdownTypeNone;
0117     init();
0118 }
0119 
0120 void Greeter::promptShutDown()
0121 {
0122     if (m_running) {
0123         return;
0124     }
0125     m_shutdownType = KWorkSpace::ShutdownTypeHalt;
0126     init();
0127 }
0128 
0129 void Greeter::promptReboot()
0130 {
0131     if (m_running) {
0132         return;
0133     }
0134     m_shutdownType = KWorkSpace::ShutdownTypeReboot;
0135     init();
0136 }