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 }