File indexing completed on 2024-05-05 05:38:40
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 <KWindowSystem> 0021 #include <LayerShellQt/Shell> 0022 0023 Greeter::Greeter(const KPackage::Package &package) 0024 : QObject() 0025 , m_package(package) 0026 { 0027 new LogoutPromptAdaptor(this); 0028 QDBusConnection::sessionBus().registerObject(QStringLiteral("/LogoutPrompt"), this); 0029 QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.LogoutPrompt")); 0030 } 0031 0032 Greeter::~Greeter() 0033 { 0034 qDeleteAll(m_dialogs); 0035 } 0036 0037 void Greeter::setupWaylandIntegration() 0038 { 0039 if (!KWindowSystem::isPlatformWayland() || m_windowed) { 0040 return; 0041 } 0042 LayerShellQt::Shell::useLayerShell(); 0043 } 0044 0045 void Greeter::init() 0046 { 0047 // If we're already shutting down we don't need another prompt, 0048 // just reply to the dbus message and exit 0049 if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Shutdown")) { 0050 QApplication::quit(); 0051 return; 0052 } 0053 0054 setupWaylandIntegration(); 0055 const auto screens = qApp->screens(); 0056 for (QScreen *screen : screens) { 0057 adoptScreen(screen); 0058 } 0059 connect(qApp, &QGuiApplication::screenAdded, this, &Greeter::adoptScreen); 0060 m_running = true; 0061 } 0062 0063 void Greeter::enableWindowed() 0064 { 0065 m_windowed = true; 0066 promptAll(); 0067 } 0068 0069 void Greeter::adoptScreen(QScreen *screen) 0070 { 0071 if (screen->geometry().isNull()) { 0072 return; 0073 } 0074 // TODO: last argument is the theme, maybe add command line option for it? 0075 KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownType, screen); 0076 w->setWindowed(m_windowed); 0077 w->installEventFilter(this); 0078 m_dialogs << w; 0079 0080 QObject::connect(screen, &QObject::destroyed, w, [w, this] { 0081 m_dialogs.removeOne(w); 0082 w->deleteLater(); 0083 }); 0084 connect(w, &KSMShutdownDlg::rejected, this, &Greeter::rejected); 0085 0086 connect(w, &KSMShutdownDlg::accepted, this, []() { 0087 QApplication::exit(1); 0088 }); 0089 0090 w->setGeometry(screen->geometry()); 0091 w->init(m_package); 0092 } 0093 0094 void Greeter::rejected() 0095 { 0096 QApplication::exit(1); 0097 } 0098 0099 bool Greeter::eventFilter(QObject *watched, QEvent *event) 0100 { 0101 if (qobject_cast<KSMShutdownDlg *>(watched)) { 0102 if (event->type() == QEvent::MouseButtonPress) { 0103 // check that the position is on no window 0104 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0105 if (std::any_of(m_dialogs.cbegin(), m_dialogs.cend(), [me](KSMShutdownDlg *dialog) { 0106 return dialog->geometry().contains(me->globalPosition().toPoint()); 0107 })) { 0108 return false; 0109 } 0110 // click outside, close 0111 rejected(); 0112 } 0113 } 0114 return false; 0115 } 0116 0117 void Greeter::promptLogout() 0118 { 0119 if (m_running) { 0120 return; 0121 } 0122 m_shutdownType = KWorkSpace::ShutdownTypeNone; 0123 init(); 0124 } 0125 0126 void Greeter::promptShutDown() 0127 { 0128 if (m_running) { 0129 return; 0130 } 0131 m_shutdownType = KWorkSpace::ShutdownTypeHalt; 0132 init(); 0133 } 0134 0135 void Greeter::promptReboot() 0136 { 0137 if (m_running) { 0138 return; 0139 } 0140 m_shutdownType = KWorkSpace::ShutdownTypeReboot; 0141 init(); 0142 } 0143 0144 void Greeter::promptAll() 0145 { 0146 if (m_running) { 0147 return; 0148 } 0149 m_shutdownType = KWorkSpace::ShutdownTypeDefault; 0150 init(); 0151 }