diff --git a/ksmserver/CMakeLists.txt b/ksmserver/CMakeLists.txt --- a/ksmserver/CMakeLists.txt +++ b/ksmserver/CMakeLists.txt @@ -23,6 +23,8 @@ qt5_add_dbus_adaptor( ksmserver_KDEINIT_SRCS org.kde.KSMServerInterface.xml server.h KSMServer ) qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/org.kde.screensaver.xml kscreenlocker_interface ) qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS org.kde.LogoutPrompt.xml logoutprompt_interface) +qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS org.kde.KWin.Session.xml kwinsession_interface) + set(klauncher_xml ${KINIT_DBUS_INTERFACES_DIR}/kf5_org.kde.KLauncher.xml) qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${klauncher_xml} klauncher_interface ) diff --git a/ksmserver/logout.cpp b/ksmserver/logout.cpp --- a/ksmserver/logout.cpp +++ b/ksmserver/logout.cpp @@ -77,6 +77,13 @@ #include "logoutprompt_interface.h" #include "shutdown_interface.h" +#include "kwinsession_interface.h" + +enum KWinSessionState { + Normal = 0, + Saving = 1, + Quitting = 2 +}; void KSMServer::logout( int confirm, int sdtype, int sdmode ) { @@ -183,6 +190,11 @@ if (state != Idle) { QTimer::singleShot(1000, this, &KSMServer::performLogout); } + + auto reply = m_kwinInterface->setState(KWinSessionState::Saving); + // we don't need to block as we wait for kwin to handle it's session 1 + // before messaging the clients + state = Shutdown; // shall we save the session on logout? @@ -251,6 +263,7 @@ sessionGroup = QLatin1String("Session: ") + QString::fromLocal8Bit( SESSION_BY_USER ); state = Checkpoint; + wmPhase1WaitingCount = 0; saveType = SmSaveLocal; saveSession = true; @@ -405,6 +418,9 @@ } } state = Idle; + + m_kwinInterface->setState(KWinSessionState::Normal); + if (m_performLogoutCall.type() == QDBusMessage::MethodCallMessage) { auto reply = m_performLogoutCall.createReply(false); QDBusConnection::sessionBus().send(reply); @@ -519,6 +535,9 @@ } // kill all clients state = Killing; + + m_kwinInterface->setState(KWinSessionState::Quitting); + foreach( KSMClient* c, clients ) { if( isWM( c )) // kill the WM as the last one in order to reduce flicker continue; diff --git a/ksmserver/org.kde.KWin.Session.xml b/ksmserver/org.kde.KWin.Session.xml new file mode 100644 --- /dev/null +++ b/ksmserver/org.kde.KWin.Session.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/ksmserver/server.h b/ksmserver/server.h --- a/ksmserver/server.h +++ b/ksmserver/server.h @@ -62,6 +62,7 @@ class KSMConnection; class KSMClient; +class OrgKdeKWinSessionInterface; enum SMType { SM_ERROR, SM_WMCOMMAND, SM_WMSAVEYOURSELF }; struct SMData @@ -83,6 +84,7 @@ ImmediateLockScreen = 1 << 1, NoLockScreen = 1 << 2 }; + Q_DECLARE_FLAGS(InitFlags, InitFlag) KSMServer( const QString& windowManager, InitFlags flags ); ~KSMServer() override; @@ -255,6 +257,8 @@ QList clientsToKill; QList clientsToSave; + OrgKdeKWinSessionInterface *m_kwinInterface; + int sockets[2]; friend bool readFromPipe(int pipe); }; diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp --- a/ksmserver/server.cpp +++ b/ksmserver/server.cpp @@ -93,6 +93,7 @@ #include #include "kscreenlocker_interface.h" +#include "kwinsession_interface.h" KSMServer* the_server = nullptr; @@ -599,6 +600,7 @@ KSMServer::KSMServer( const QString& windowManager, InitFlags flags ) : wmProcess( nullptr ) , sessionGroup( QStringLiteral( "" ) ) + , m_kwinInterface(new OrgKdeKWinSessionInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Session"), QDBusConnection::sessionBus(), this)) , sockets{ -1, -1 } { if (!flags.testFlag(InitFlag::NoLockScreen)) {