File indexing completed on 2024-05-12 17:07:19
0001 /* 0002 kcmsmserver.cpp 0003 SPDX-FileCopyrightText: 2000, 2002 Oswald Buddenhagen <ossi@kde.org> 0004 0005 based on kcmtaskbar.cpp 0006 SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org> 0007 0008 SPDX-FileCopyrightText: 2019 Kevin Ottens <kevin.ottens@enioka.com> 0009 SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0010 0011 SPDX-License-Identifier: GPL-2.0-or-later 0012 */ 0013 0014 #include <QAction> 0015 #include <QDBusConnection> 0016 #include <QDBusPendingCallWatcher> 0017 #include <QDBusPendingReply> 0018 #include <QFileInfo> 0019 0020 #include <KDesktopFile> 0021 #include <KPluginFactory> 0022 #include <KProcess> 0023 #include <QDBusInterface> 0024 #include <kworkspace.h> 0025 0026 #include "kcmsmserver.h" 0027 #include "smserverdata.h" 0028 #include "smserversettings.h" 0029 0030 #include <KLocalizedString> 0031 0032 #include <sessionmanagement.h> 0033 0034 #include "login1_manager.h" 0035 0036 K_PLUGIN_FACTORY_WITH_JSON(SMServerConfigFactory, "kcm_smserver.json", registerPlugin<SMServerConfig>(); registerPlugin<SMServerData>();) 0037 0038 SMServerConfig::SMServerConfig(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args) 0039 : KQuickAddons::ManagedConfigModule(parent, metaData, args) 0040 , m_login1Manager(new OrgFreedesktopLogin1ManagerInterface(QStringLiteral("org.freedesktop.login1"), 0041 QStringLiteral("/org/freedesktop/login1"), 0042 QDBusConnection::systemBus(), 0043 this)) 0044 { 0045 auto settings = new SMServerSettings(this); 0046 qmlRegisterSingletonInstance("org.kde.desktopsession.private", 1, 0, "Settings", settings); 0047 0048 setQuickHelp( 0049 i18n("<h1>Session Manager</h1>" 0050 " You can configure the session manager here." 0051 " This includes options such as whether or not the session exit (logout)" 0052 " should be confirmed, whether the session should be restored again when logging in" 0053 " and whether the computer should be automatically shut down after session" 0054 " exit by default.")); 0055 0056 checkFirmwareSetupRequested(); 0057 m_restartInSetupScreenInitial = m_restartInSetupScreen; 0058 0059 setButtons(Help | Apply | Default); 0060 0061 const QString canFirmwareSetup = m_login1Manager->CanRebootToFirmwareSetup().value(); 0062 if (canFirmwareSetup == QLatin1String("yes") || canFirmwareSetup == QLatin1String("challenge")) { 0063 m_canFirmwareSetup = true; 0064 // now check whether we're UEFI to provide a more descriptive button label 0065 if (QFileInfo(QStringLiteral("/sys/firmware/efi")).isDir()) { 0066 m_isUefi = true; 0067 } 0068 } 0069 } 0070 0071 SMServerConfig::~SMServerConfig() = default; 0072 0073 bool SMServerConfig::isUefi() const 0074 { 0075 return m_isUefi; 0076 } 0077 0078 bool SMServerConfig::restartInSetupScreen() const 0079 { 0080 return m_restartInSetupScreen; 0081 } 0082 0083 void SMServerConfig::setRestartInSetupScreen(bool restartInSetupScreen) 0084 { 0085 if (m_restartInSetupScreen == restartInSetupScreen) { 0086 return; 0087 } 0088 0089 QDBusMessage message = QDBusMessage::createMethodCall(m_login1Manager->service(), 0090 m_login1Manager->path(), 0091 m_login1Manager->interface(), 0092 QStringLiteral("SetRebootToFirmwareSetup")); 0093 0094 message.setArguments({restartInSetupScreen}); 0095 // This cannot be set through a generated DBus interface, so we have to create the message ourself. 0096 message.setInteractiveAuthorizationAllowed(true); 0097 0098 QDBusPendingReply<void> call = m_login1Manager->connection().asyncCall(message); 0099 QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(call, this); 0100 connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this, restartInSetupScreen](QDBusPendingCallWatcher *watcher) { 0101 QDBusPendingReply<void> reply = *watcher; 0102 watcher->deleteLater(); 0103 0104 checkFirmwareSetupRequested(); 0105 0106 settingsChanged(); 0107 0108 if (reply.isError()) { 0109 // User likely canceled the PolKit prompt, don't show an error in this case 0110 if (reply.error().type() != QDBusError::AccessDenied) { 0111 m_error = reply.error().message(); 0112 Q_EMIT errorChanged(); 0113 } 0114 return; 0115 } else if (m_error.length() > 0) { 0116 m_error = QString(); 0117 Q_EMIT errorChanged(); 0118 } 0119 m_restartInSetupScreen = restartInSetupScreen; 0120 Q_EMIT restartInSetupScreenChanged(); 0121 0122 if (!restartInSetupScreen) { 0123 return; 0124 } 0125 }); 0126 } 0127 0128 QString SMServerConfig::error() const 0129 { 0130 return m_error; 0131 } 0132 0133 void SMServerConfig::reboot() 0134 { 0135 auto sm = new SessionManagement(this); 0136 auto doShutdown = [sm]() { 0137 sm->requestReboot(); 0138 delete sm; 0139 }; 0140 if (sm->state() == SessionManagement::State::Loading) { 0141 connect(sm, &SessionManagement::stateChanged, this, doShutdown); 0142 } else { 0143 doShutdown(); 0144 } 0145 } 0146 0147 void SMServerConfig::checkFirmwareSetupRequested() 0148 { 0149 m_restartInSetupScreen = m_login1Manager->property("RebootToFirmwareSetup").toBool(); 0150 Q_EMIT restartInSetupScreenChanged(); 0151 } 0152 0153 bool SMServerConfig::canFirmwareSetup() const 0154 { 0155 return m_canFirmwareSetup; 0156 } 0157 0158 bool SMServerConfig::isSaveNeeded() const 0159 { 0160 return m_restartInSetupScreen != m_restartInSetupScreenInitial; 0161 } 0162 0163 bool SMServerConfig::isDefaults() const 0164 { 0165 return !m_restartInSetupScreen; 0166 } 0167 0168 void SMServerConfig::defaults() 0169 { 0170 ManagedConfigModule::defaults(); 0171 setRestartInSetupScreen(false); 0172 } 0173 0174 void SMServerConfig::save() 0175 { 0176 ManagedConfigModule::save(); 0177 Q_EMIT ksmserverSettingsChanged(); 0178 } 0179 0180 #include "kcmsmserver.moc"