File indexing completed on 2024-04-28 05:35:31
0001 /* 0002 ksmserver - the KDE session management server 0003 0004 SPDX-FileCopyrightText: 2000 Matthias Ettrich <ettrich@kde.org> 0005 0006 SPDX-License-Identifier: MIT 0007 */ 0008 0009 #pragma once 0010 0011 #define INT32 QINT32 0012 #include <X11/ICE/ICElib.h> 0013 #include <X11/Xlib.h> 0014 #include <X11/Xmd.h> 0015 extern "C" { 0016 #include <X11/SM/SM.h> 0017 #include <X11/SM/SMlib.h> 0018 } 0019 0020 #include <fixx11h.h> 0021 0022 #include <QDBusContext> 0023 #include <QDBusMessage> 0024 #include <QMap> 0025 #include <QObject> 0026 #include <QStringList> 0027 #include <QTime> 0028 #include <QTimer> 0029 #include <QWindow> 0030 0031 #include <KConfigGroup> 0032 #include <kworkspace.h> 0033 0034 class KProcess; 0035 0036 class KSMListener; 0037 class KSMConnection; 0038 class KSMClient; 0039 0040 class OrgKdeKWinSessionInterface; 0041 0042 enum SMType { 0043 SM_ERROR, 0044 SM_WMCOMMAND, 0045 SM_WMSAVEYOURSELF, 0046 }; 0047 struct SMData { 0048 SMType type; 0049 QStringList wmCommand; 0050 QString wmClientMachine; 0051 QString wmclass1, wmclass2; 0052 }; 0053 using WindowMap = QMap<WId, SMData>; 0054 0055 constexpr QLatin1String SESSION_PREFIX("Session: "); 0056 constexpr QLatin1String SUBSESSION_PREFIX("SubSession: "); 0057 constexpr QLatin1String SESSION_PREVIOUS_LOGOUT("saved at previous logout"); 0058 constexpr QLatin1String SESSION_BY_USER("saved by user"); 0059 0060 class KSMServer : public QObject, protected QDBusContext 0061 { 0062 Q_OBJECT 0063 public: 0064 enum class InitFlag { 0065 None = 0, 0066 OnlyLocal = 1 << 0, 0067 ImmediateLockScreen = 1 << 1, 0068 NoLockScreen = 1 << 2, 0069 }; 0070 0071 Q_DECLARE_FLAGS(InitFlags, InitFlag) 0072 explicit KSMServer(InitFlags flags); 0073 ~KSMServer() override; 0074 Q_DISABLE_COPY_MOVE(KSMServer); 0075 0076 static KSMServer *self(); 0077 0078 void *watchConnection(IceConn iceConn); 0079 void removeConnection(KSMConnection *conn); 0080 0081 KSMClient *newClient(SmsConn); 0082 void deleteClient(KSMClient *client); 0083 0084 // callbacks 0085 void saveYourselfDone(KSMClient *client, bool success); 0086 void interactRequest(KSMClient *client, int dialogType); 0087 void interactDone(KSMClient *client, bool cancelShutdown); 0088 void phase2Request(KSMClient *client); 0089 0090 // error handling 0091 void ioError(IceConn iceConn); 0092 0093 // notification 0094 void clientRegistered(const char *previousId); 0095 0096 // public API 0097 void performLogout(); 0098 void restoreSession(); 0099 void setRestoreSession(const QString &sessionName); 0100 void startDefaultSession(); 0101 void resetLogout(); 0102 0103 Q_SIGNALS: 0104 void logoutFinished(bool sessionClosed); 0105 0106 public Q_SLOTS: 0107 0108 void cleanUp(); 0109 0110 private Q_SLOTS: 0111 void newConnection(int socket); 0112 void processData(int socket); 0113 0114 void protectionTimeout(); 0115 void timeoutQuit(); 0116 0117 private: 0118 void handlePendingInteractions(); 0119 void completeShutdownOrCheckpoint(); 0120 void startKilling(); 0121 void startKillingSubSession(); 0122 void performStandardKilling(); 0123 void completeKilling(); 0124 void completeKillingSubSession(); 0125 void signalSubSessionClosed(); 0126 void cancelShutdown(KSMClient *c); 0127 void killingCompleted(); 0128 0129 void discardSession(); 0130 void storeSession(); 0131 0132 void startProtection(); 0133 void endProtection(); 0134 0135 void startApplication(const QStringList &command, const QString &clientMachine = QString(), const QString &userId = QString()); 0136 void executeCommand(const QStringList &command); 0137 0138 bool defaultSession() const; // empty session 0139 void setupXIOErrorHandler(); 0140 0141 void performLegacySessionSave(); 0142 void storeLegacySession(KConfig *config); 0143 void restoreLegacySession(KConfig *config); 0144 void restoreLegacySessionInternal(KConfigGroup *config, char sep = ','); 0145 QStringList windowWmCommand(WId w); 0146 QString windowWmClientMachine(WId w); 0147 WId windowWmClientLeader(WId w); 0148 QByteArray windowSessionId(WId w, WId leader); 0149 0150 void tryRestore(); 0151 void startupDone(); 0152 0153 void runShutdownScripts(); 0154 0155 public Q_SLOTS: // public dbus interface 0156 bool isShuttingDown() const; 0157 QString currentSession(); 0158 void saveCurrentSession(); 0159 void saveCurrentSessionAs(const QString &); 0160 QStringList sessionList(); 0161 void saveSubSession(const QString &name, QStringList saveAndClose, QStringList saveOnly = QStringList()); 0162 void restoreSubSession(const QString &name); 0163 0164 void openSwitchUserDialog(); 0165 bool closeSession(); 0166 0167 Q_SIGNALS: 0168 void subSessionClosed(); 0169 void subSessionCloseCanceled(); 0170 void subSessionOpened(); 0171 void sessionRestored(); 0172 0173 private: 0174 QList<KSMListener *> listener; 0175 QList<KSMClient *> clients; 0176 0177 enum State { 0178 Idle, 0179 Restoring, 0180 Shutdown, 0181 Checkpoint, 0182 Killing, 0183 WaitingForKNotify, // shutdown 0184 ClosingSubSession, 0185 KillingSubSession, 0186 RestoringSubSession, 0187 }; 0188 State state; 0189 bool saveSession; 0190 int saveType; 0191 0192 bool clean; 0193 KSMClient *clientInteracting; 0194 QString sessionGroup; 0195 QTimer protectionTimer; 0196 QString xonCommand; 0197 // sequential startup 0198 int appsToStart; 0199 0200 QStringList excludeApps; 0201 0202 WindowMap legacyWindows; 0203 0204 QDBusMessage m_restoreSessionCall; 0205 0206 // subSession stuff 0207 QList<KSMClient *> clientsToKill; 0208 QList<KSMClient *> clientsToSave; 0209 0210 OrgKdeKWinSessionInterface *m_kwinInterface; 0211 0212 int sockets[2]; 0213 friend bool readFromPipe(int pipe); 0214 };