diff --git a/ksmserver/CMakeLists.txt b/ksmserver/CMakeLists.txt
--- a/ksmserver/CMakeLists.txt
+++ b/ksmserver/CMakeLists.txt
@@ -44,7 +44,7 @@
qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${klauncher_xml} klauncher_interface )
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_adaptor( ksmserver_KDEINIT_SRCS org.kde.KSMServerInterface.xml server.h KSMServer )
diff --git a/ksmserver/org.kde.LogoutPrompt.xml b/ksmserver/org.kde.LogoutPrompt.xml
new file mode 100644
--- /dev/null
+++ b/ksmserver/org.kde.LogoutPrompt.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/ksmserver/server.h b/ksmserver/server.h
--- a/ksmserver/server.h
+++ b/ksmserver/server.h
@@ -239,7 +239,6 @@
ClosingSubSession, KillingSubSession, RestoringSubSession
};
State state;
- bool dialogActive;
bool saveSession;
int wmPhase1WaitingCount;
int saveType;
@@ -289,7 +288,6 @@
QList clientsToSave;
int sockets[2];
- friend bool readFromPipe(int pipe);
};
#endif
diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp
--- a/ksmserver/server.cpp
+++ b/ksmserver/server.cpp
@@ -624,7 +624,6 @@
shutdownType = KWorkSpace::ShutdownTypeNone;
state = Idle;
- dialogActive = false;
saveSession = false;
wmPhase1WaitingCount = 0;
KConfigGroup config(KSharedConfig::openConfig(), "General");
diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp
--- a/ksmserver/shutdown.cpp
+++ b/ksmserver/shutdown.cpp
@@ -77,6 +77,7 @@
#include "client.h"
#include
+#include "logoutprompt_interface.h"
#include
#include
@@ -108,34 +109,12 @@
return state >= Shutdown;
}
-bool readFromPipe(int pipe)
-{
- QFile readPipe;
- if (!readPipe.open(pipe, QIODevice::ReadOnly)) {
- return false;
- }
- QByteArray result = readPipe.readLine();
- if (result.isEmpty()) {
- return false;
- }
- bool ok = false;
- const int number = result.toInt(&ok);
- if (!ok) {
- return false;
- }
- KSMServer::self()->shutdownType = KWorkSpace::ShutdownType(number);
-
- return true;
-}
-
void KSMServer::shutdown( KWorkSpace::ShutdownConfirm confirm,
KWorkSpace::ShutdownType sdtype, KWorkSpace::ShutdownMode sdmode )
{
qCDebug(KSMSERVER) << "Shutdown called with confirm " << confirm
<< " type " << sdtype << " and mode " << sdmode;
pendingShutdown.stop();
- if( dialogActive )
- return;
if( state >= Shutdown ) // already performing shutdown
return;
if( state != Idle ) // performing startup
@@ -160,129 +139,27 @@
(confirm == KWorkSpace::ShutdownConfirmYes) ? false :
(confirm == KWorkSpace::ShutdownConfirmNo) ? true :
!cg.readEntry( "confirmLogout", true );
- bool choose = false;
- bool maysd = false;
- if (cg.readEntry( "offerShutdown", true ) && KDisplayManager().canShutdown())
- maysd = true;
- if (!maysd) {
- if (sdtype != KWorkSpace::ShutdownTypeNone &&
- sdtype != KWorkSpace::ShutdownTypeDefault &&
- logoutConfirmed)
- return; /* unsupported fast shutdown */
- sdtype = KWorkSpace::ShutdownTypeNone;
- } else if (sdtype == KWorkSpace::ShutdownTypeDefault) {
- sdtype = (KWorkSpace::ShutdownType)
- cg.readEntry( "shutdownType", (int)KWorkSpace::ShutdownTypeNone );
- choose = true;
- }
- if (sdmode == KWorkSpace::ShutdownModeDefault)
- sdmode = KWorkSpace::ShutdownModeInteractive;
-
- qCDebug(KSMSERVER) << "After modifications confirm is " << confirm
- << " type is " << sdtype << " and mode " << sdmode;
- QString bopt;
- if ( !logoutConfirmed ) {
- int pipeFds[2];
- if (pipe(pipeFds) != 0) {
- return;
- }
- QProcess *p = new QProcess(this);
- p->setProgram(QStringLiteral(LOGOUT_GREETER_BIN));
- QStringList arguments;
- if (maysd) {
- arguments << QStringLiteral("--shutdown-allowed");
- }
- if (choose) {
- arguments << QStringLiteral("--choose");
- }
- if (sdtype != KWorkSpace::ShutdownTypeDefault) {
- arguments << QStringLiteral("--mode");
- switch (sdtype) {
- case KWorkSpace::ShutdownTypeHalt:
- arguments << QStringLiteral("shutdown");
- break;
- case KWorkSpace::ShutdownTypeReboot:
- arguments << QStringLiteral("reboot");
- break;
- case KWorkSpace::ShutdownTypeNone:
- default:
- // logout
- arguments << QStringLiteral("logout");
- break;
- }
- }
- arguments << QStringLiteral("--mode-fd");
- arguments << QString::number(pipeFds[1]);
- p->setArguments(arguments);
-
- const int resultPipe = pipeFds[0];
- connect(p, static_cast(&QProcess::error), this,
- [this, resultPipe, sdmode, sdtype] {
- close(resultPipe);
- dialogActive = false;
- auto fallbackPrompt = new QMessageBox;
- fallbackPrompt->setAttribute(Qt::WA_DeleteOnClose, true);
- fallbackPrompt->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- switch (sdtype) {
- case KWorkSpace::ShutdownTypeHalt:
- //i18nd is used as this patch was backported to an LTS with stable translations
- fallbackPrompt->setText(i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Shut Down"));
- break;
- case KWorkSpace::ShutdownTypeReboot:
- fallbackPrompt->setText(i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Reboot"));
- break;
- case KWorkSpace::ShutdownTypeNone:
- Q_FALLTHROUGH();
- default:
- fallbackPrompt->setText(i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Logout"));
- break;
- }
- connect(fallbackPrompt, &QMessageBox::buttonClicked, this, [=](QAbstractButton *button) {
- if (button != fallbackPrompt->button(QMessageBox::Ok)) {
- return;
- }
- shutdownType = sdtype;
- shutdownMode = sdmode;
- bootOption = QString();
- performLogout();
- });
- fallbackPrompt->show();
- }
- );
-
- connect(p, static_cast(&QProcess::finished), this,
- [this, resultPipe, sdmode, p] (int exitCode) {
- p->deleteLater();
- dialogActive = false;
- if (exitCode != 0) {
- close(resultPipe);
- return;
- }
- QFutureWatcher *watcher = new QFutureWatcher();
- QObject::connect(watcher, &QFutureWatcher::finished, this,
- [this, sdmode, watcher] {
- const bool result = watcher->result();
- if (!result) {
- // it failed to read, don't logout
- return;
- }
- shutdownMode = sdmode;
- bootOption = QString();
- performLogout();
- }, Qt::QueuedConnection);
- QObject::connect(watcher, &QFutureWatcher::finished, watcher, &QFutureWatcher::deleteLater, Qt::QueuedConnection);
- watcher->setFuture(QtConcurrent::run(readFromPipe, resultPipe));
- }
- );
- dialogActive = true;
- p->start();
- close(pipeFds[1]);
+ if (!logoutConfirmed) {
+ OrgKdeLogoutPromptInterface logoutPrompt(QStringLiteral("org.kde.LogoutPrompt"),
+ QStringLiteral("/LogoutPrompt"),
+ QDBusConnection::sessionBus());
+ switch (sdtype) {
+ case KWorkSpace::ShutdownTypeHalt:
+ logoutPrompt.promptShutDown();
+ break;
+ case KWorkSpace::ShutdownTypeReboot:
+ logoutPrompt.promptReboot();
+ break;
+ case KWorkSpace::ShutdownTypeNone:
+ Q_FALLTHROUGH();
+ default:
+ logoutPrompt.promptLogout();
+ break;
+ }
} else {
shutdownType = sdtype;
shutdownMode = sdmode;
- bootOption = bopt;
-
performLogout();
}
}
@@ -349,7 +226,6 @@
qCDebug(KSMSERVER) << "clients should be empty, " << clients.isEmpty();
if ( clients.isEmpty() )
completeShutdownOrCheckpoint();
- dialogActive = false;
}
void KSMServer::pendingShutdownTimeout()
@@ -359,7 +235,7 @@
void KSMServer::saveCurrentSession()
{
- if ( state != Idle || dialogActive )
+ if ( state != Idle )
return;
if ( currentSession().isEmpty() || currentSession() == QString::fromLocal8Bit( SESSION_PREVIOUS_LOGOUT ) )
@@ -392,7 +268,7 @@
void KSMServer::saveCurrentSessionAs( const QString &session )
{
- if ( state != Idle || dialogActive )
+ if ( state != Idle )
return;
sessionGroup = QStringLiteral( "Session: " ) + session;
saveCurrentSession();
diff --git a/logout-greeter/CMakeLists.txt b/logout-greeter/CMakeLists.txt
--- a/logout-greeter/CMakeLists.txt
+++ b/logout-greeter/CMakeLists.txt
@@ -4,6 +4,10 @@
CATEGORY_NAME kde.logout_greeter
DEFAULT_SEVERITY Info)
+
+qt5_add_dbus_adaptor( LOGOUT_GREETER_SRCS ../ksmserver/org.kde.LogoutPrompt.xml greeter.h Greeter)
+qt5_add_dbus_interface( LOGOUT_GREETER_SRCS ../ksmserver/org.kde.KSMServerInterface.xml ksmserveriface)
+
add_executable(ksmserver-logout-greeter ${LOGOUT_GREETER_SRCS})
target_link_libraries(ksmserver-logout-greeter
PW::KWorkspace
@@ -20,6 +24,7 @@
${X11_LIBRARIES}
)
install(TARGETS ksmserver-logout-greeter DESTINATION ${KDE_INSTALL_LIBEXECDIR})
+kdbusaddons_generate_dbus_service_file(ksmserver-logout-greeter org.kde.LogoutPrompt ${KDE_INSTALL_FULL_LIBEXECDIR})
if(BUILD_TESTING)
add_subdirectory(tests)
diff --git a/logout-greeter/greeter.h b/logout-greeter/greeter.h
--- a/logout-greeter/greeter.h
+++ b/logout-greeter/greeter.h
@@ -43,22 +43,27 @@
{
Q_OBJECT
public:
- Greeter(int fd, bool shutdownAllowed, bool choose, KWorkSpace::ShutdownType type);
+ Greeter(bool shutdownAllowed);
~Greeter() override;
void init();
bool eventFilter(QObject *watched, QEvent *event) override;
+public Q_SLOTS:
+ void promptLogout();
+ void promptShutDown();
+ void promptReboot();
+
private:
void adoptScreen(QScreen *screen);
void rejected();
void setupWaylandIntegration();
- int m_fd;
bool m_shutdownAllowed;
- bool m_choose;
- KWorkSpace::ShutdownType m_shutdownType;
+ bool m_running = false;
+
+ KWorkSpace::ShutdownType m_shutdownType = KWorkSpace::ShutdownTypeHalt;
QVector m_dialogs;
KWayland::Client::PlasmaShell *m_waylandPlasmaShell;
};
diff --git a/logout-greeter/greeter.cpp b/logout-greeter/greeter.cpp
--- a/logout-greeter/greeter.cpp
+++ b/logout-greeter/greeter.cpp
@@ -31,23 +31,24 @@
#include "shutdowndlg.h"
+#include "logoutpromptadaptor.h"
+#include "ksmserveriface.h"
+
#include
#include
#include
#include
#include
-#include
-
-Greeter::Greeter(int fd, bool shutdownAllowed, bool choose, KWorkSpace::ShutdownType type)
+Greeter::Greeter(bool shutdownAllowed)
: QObject()
- , m_fd(fd)
, m_shutdownAllowed(shutdownAllowed)
- , m_choose(choose)
- , m_shutdownType(type)
, m_waylandPlasmaShell(nullptr)
{
+ new LogoutPromptAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(QStringLiteral("/LogoutPrompt"), this);
+ QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.LogoutPrompt"));
}
Greeter::~Greeter()
@@ -83,42 +84,33 @@
adoptScreen(screen);
}
connect(qApp, &QGuiApplication::screenAdded, this, &Greeter::adoptScreen);
+ m_running = true;
}
void Greeter::adoptScreen(QScreen* screen)
{
// TODO: last argument is the theme, maybe add command line option for it?
- KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownAllowed, m_choose, m_shutdownType, m_waylandPlasmaShell);
+ KSMShutdownDlg *w = new KSMShutdownDlg(nullptr, m_shutdownAllowed, m_shutdownType, m_waylandPlasmaShell);
w->installEventFilter(this);
m_dialogs << w;
QObject::connect(screen, &QObject::destroyed, w, [w, this] {
m_dialogs.removeOne(w);
w->deleteLater();
});
connect(w, &KSMShutdownDlg::rejected, this, &Greeter::rejected);
- connect(w, &KSMShutdownDlg::accepted, this,
- [w, this] {
- if (m_fd != -1) {
- QFile f;
- if (f.open(m_fd, QFile::WriteOnly, QFile::AutoCloseHandle)) {
- f.write(QByteArray::number(int(w->shutdownType())));
- f.close();
- }
- }
- QApplication::quit();
- }
- );
+ connect(w, &KSMShutdownDlg::accepted, this, [w]() {
+ OrgKdeKSMServerInterfaceInterface ksmserver(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QDBusConnection::sessionBus());
+ ksmserver.logout(KWorkSpace::ShutdownConfirmNo, w->shutdownType(), KWorkSpace::ShutdownModeDefault);
+ QApplication::exit(1);
+ });
w->setScreen(screen);
w->setGeometry(screen->geometry());
w->init();
}
void Greeter::rejected()
{
- if (m_fd != -1) {
- close(m_fd);
- }
QApplication::exit(1);
}
@@ -139,3 +131,32 @@
}
return false;
}
+
+void Greeter::promptLogout()
+{
+ if (m_running) {
+ return;
+ }
+ m_shutdownType = KWorkSpace::ShutdownTypeLogout;
+ init();
+}
+
+void Greeter::promptShutDown()
+{
+ if (m_running) {
+ return;
+ }
+ m_shutdownType = KWorkSpace::ShutdownTypeHalt;
+ init();
+}
+
+void Greeter::promptReboot()
+{
+ if (m_running) {
+ return;
+ }
+ m_shutdownType = KWorkSpace::ShutdownTypeReboot;
+ init();
+}
+
+
diff --git a/logout-greeter/main.cpp b/logout-greeter/main.cpp
--- a/logout-greeter/main.cpp
+++ b/logout-greeter/main.cpp
@@ -28,7 +28,7 @@
#include
-#include
+#include "ksmserveriface.h"
#include "greeter.h"
@@ -38,64 +38,35 @@
// Before Qt 5.12, the xdg-shell v6 integration does not support fullscreen.
qputenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell");
}
+ qunsetenv("SESSION_MANAGER");
KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QApplication app(argc, argv);
KQuickAddons::QtQuickSettings::init();
- QCommandLineParser parser;
- parser.addHelpOption();
-
- // TODO: should these things be translated? It's internal after all...
- QCommandLineOption shutdownAllowedOption(QStringLiteral("shutdown-allowed"),
- QStringLiteral("Whether the user is allowed to shut down the system."));
- parser.addOption(shutdownAllowedOption);
-
- QCommandLineOption chooseOption(QStringLiteral("choose"),
- QStringLiteral("Whether the user is offered the choices between logout, shutdown, etc."));
- parser.addOption(chooseOption);
-
- QCommandLineOption modeOption(QStringLiteral("mode"),
- QStringLiteral("The initial exit mode to offer to the user."),
- QStringLiteral("logout|shutdown|reboot"),
- QStringLiteral("logout"));
- parser.addOption(modeOption);
-
- QCommandLineOption fdOption(QStringLiteral("mode-fd"),
- QStringLiteral("An optional file descriptor the selected mode is written to on accepted"),
- QStringLiteral("fd"), QString::number(-1));
- parser.addOption(fdOption);
-
- parser.process(app);
-
- KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeDefault;
- if (parser.isSet(modeOption)) {
- const QString modeValue = parser.value(modeOption);
- if (QString::compare(QLatin1String("logout"), modeValue, Qt::CaseInsensitive) == 0) {
- type = KWorkSpace::ShutdownTypeNone;
- } else if (QString::compare(QLatin1String("shutdown"), modeValue, Qt::CaseInsensitive) == 0) {
- type = KWorkSpace::ShutdownTypeHalt;
- } else if (QString::compare(QLatin1String("reboot"), modeValue, Qt::CaseInsensitive) == 0) {
- type = KWorkSpace::ShutdownTypeReboot;
- } else {
- return 1;
- }
+ OrgKdeKSMServerInterfaceInterface ksmserver(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QDBusConnection::sessionBus());
+ QDBusPendingReply isShuttingDownPending = ksmserver.isShuttingDown();
+ QDBusPendingReply canShutdownPending = ksmserver.canShutdown();
+
+ isShuttingDownPending.waitForFinished();
+ canShutdownPending.waitForFinished();
+
+ //if ksmserver is shutting us down already, we don't want another prompt
+ if (isShuttingDownPending.value()) {
+ return 0;
}
- int fd = -1;
- if (parser.isSet(fdOption)) {
- bool ok = false;
- const int passedFd = parser.value(fdOption).toInt(&ok);
- if (ok) {
- fd = dup(passedFd);
- }
+ bool shutdownAllowed = canShutdownPending.value();
+
+ Greeter greeter(shutdownAllowed);
+
+ if (argc > 1) {
+ //special case, invoked from ksmserver from a former release which had a tonne of args
+ //shouldn't happen often
+ greeter.promptLogout();
}
- Greeter greeter(fd, parser.isSet(shutdownAllowedOption), parser.isSet(chooseOption), type);
- greeter.init();
return app.exec();
}
-
-#include "main.moc"
diff --git a/logout-greeter/shutdowndlg.h b/logout-greeter/shutdowndlg.h
--- a/logout-greeter/shutdowndlg.h
+++ b/logout-greeter/shutdowndlg.h
@@ -43,7 +43,7 @@
Q_OBJECT
public:
- KSMShutdownDlg( QWindow* parent, bool maysd, bool choose, KWorkSpace::ShutdownType sdtype, KWayland::Client::PlasmaShell *plasmaShell = nullptr );
+ KSMShutdownDlg( QWindow* parent, bool maysd, KWorkSpace::ShutdownType sdtype, KWayland::Client::PlasmaShell *plasmaShell = nullptr );
void init();
bool result() const;
diff --git a/logout-greeter/shutdowndlg.cpp b/logout-greeter/shutdowndlg.cpp
--- a/logout-greeter/shutdowndlg.cpp
+++ b/logout-greeter/shutdowndlg.cpp
@@ -68,8 +68,8 @@
Q_DECLARE_METATYPE(Solid::PowerManagement::SleepState)
-KSMShutdownDlg::KSMShutdownDlg( QWindow* parent,
- bool maysd, bool choose, KWorkSpace::ShutdownType sdtype,
+KSMShutdownDlg::KSMShutdownDlg(QWindow* parent,
+ bool maysd, KWorkSpace::ShutdownType sdtype,
KWayland::Client::PlasmaShell *plasmaShell)
: QuickViewSharedEngine(parent),
m_result(false),
@@ -100,7 +100,6 @@
//windowContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QQmlContext *context = rootContext();
context->setContextProperty(QStringLiteral("maysd"), maysd);
- context->setContextProperty(QStringLiteral("choose"), choose);
context->setContextProperty(QStringLiteral("sdtype"), sdtype);
QQmlPropertyMap *mapShutdownType = new QQmlPropertyMap(this);
@@ -122,6 +121,10 @@
// TODO KF6 remove, used to read "BootManager" from kdmrc
context->setContextProperty(QStringLiteral("bootManager"), QStringLiteral("None"));
+ //TODO KF6 remove. Unused
+ context->setContextProperty(QStringLiteral("choose"), false);
+
+
// TODO KF6 remove, used to call KDisplayManager::bootOptions
QStringList rebootOptions;
int def = 0;