Commit 0f5c7ede authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇

[Desktop Sessions KCM] Add Restart to BIOS/UEFI checkbox

This sets a logind flag that tells the system to boot into the BIOS/UEFI setup screen on next boot.
It can be quite a challenge to enter the setup screen on boot these days as with quick boot and what not
the timeframe for the keypress is often quite narrow.

Differential Revision: https://phabricator.kde.org/D19560
parent 737b114c
......@@ -3,6 +3,7 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kcmsmserver\")
set(kcm_smserver_PART_SRCS kcmsmserver.cpp smserverconfigimpl.cpp )
qt5_add_dbus_interface(kcm_smserver_PART_SRCS org.freedesktop.login1.Manager.xml login1_manager)
ki18n_wrap_ui(kcm_smserver_PART_SRCS smserverconfigdlg.ui )
......
......@@ -19,11 +19,15 @@
* along with this program; if not, write to the Free Software
*/
#include <QAction>
#include <QDBusConnection>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QCheckBox>
#include <QFileInfo>
//Added by qt3to4:
#include <QVBoxLayout>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <ksharedconfig.h>
......@@ -42,10 +46,18 @@
#include <KPluginLoader>
#include <KLocalizedString>
#include "kworkspace.h"
#include "login1_manager.h"
K_PLUGIN_FACTORY(SMSFactory, registerPlugin<SMServerConfig>();)
SMServerConfig::SMServerConfig(QWidget *parent, const QVariantList &args)
: KCModule(parent, args)
, m_login1Manager(new OrgFreedesktopLogin1ManagerInterface(QStringLiteral("org.freedesktop.login1"),
QStringLiteral("/org/freedesktop/login1"),
QDBusConnection::systemBus(),
this))
{
setQuickHelp( i18n("<h1>Session Manager</h1>"
" You can configure the session manager here."
......@@ -59,9 +71,85 @@ SMServerConfig::SMServerConfig(QWidget *parent, const QVariantList &args)
dialog = new SMServerConfigImpl(this);
connect(dialog, SIGNAL(changed()), SLOT(changed()));
initFirmwareSetup();
checkFirmwareSetupRequested();
topLayout->addWidget(dialog);
}
void SMServerConfig::initFirmwareSetup()
{
m_rebootNowAction = new QAction(QIcon::fromTheme(QStringLiteral("system-reboot")), i18n("Restart Now"));
connect(m_rebootNowAction, &QAction::triggered, this, [] {
KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmNo, KWorkSpace::ShutdownTypeReboot);
});
connect(dialog->firmwareSetupCheck, &QCheckBox::clicked, this, [this](bool enable) {
dialog->firmwareSetupMessageWidget->removeAction(m_rebootNowAction);
dialog->firmwareSetupMessageWidget->animatedHide();
QDBusMessage message = QDBusMessage::createMethodCall(m_login1Manager->service(),
m_login1Manager->path(),
m_login1Manager->interface(),
QStringLiteral("SetRebootToFirmwareSetup"));
message.setArguments({enable});
// This cannot be set through a generated DBus interface, so we have to create the message ourself.
message.setInteractiveAuthorizationAllowed(true);
QDBusPendingReply<void> call = m_login1Manager->connection().asyncCall(message);
QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(call, this);
connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this, enable](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<void> reply = *watcher;
watcher->deleteLater();
checkFirmwareSetupRequested();
KMessageWidget *message = dialog->firmwareSetupMessageWidget;
if (reply.isError()) {
// User likely canceled the PolKit prompt, don't show an error in this case
if (reply.error().type() != QDBusError::AccessDenied) {
message->setMessageType(KMessageWidget::Error);
message->setText(i18n("Failed to request restart to firmware setup: %1", reply.error().message()));
message->animatedShow();
}
return;
}
if (!enable) {
return;
}
message->setMessageType(KMessageWidget::Information);
if (m_isUefi) {
message->setText(i18n("Next time the computer is restarted, it will enter the UEFI setup screen."));
} else {
message->setText(i18n("Next time the computer is restarted, it will enter the firmware setup screen."));
}
message->addAction(m_rebootNowAction);
message->animatedShow();
});
});
const QString canFirmareSetup = m_login1Manager->CanRebootToFirmwareSetup().value();
if (canFirmareSetup == QLatin1String("yes") || canFirmareSetup == QLatin1String("challenge")) {
// now check whether we're UEFI to provide a more descriptive button label
if (QFileInfo(QStringLiteral("/sys/firmware/efi")).isDir()) {
m_isUefi = true;
dialog->firmwareSetupBox->setTitle(i18n("UEFI Setup"));
dialog->firmwareSetupCheck->setText(i18n("Enter UEFI setup on next restart"));
}
dialog->firmwareSetupBox->setVisible(true);
}
}
void SMServerConfig::checkFirmwareSetupRequested()
{
dialog->firmwareSetupCheck->setChecked(m_login1Manager->property("RebootToFirmwareSetup").toBool());
}
void SMServerConfig::load()
{
KConfigGroup c(KSharedConfig::openConfig(QStringLiteral("ksmserverrc"), KConfig::NoGlobals),
......
......@@ -102,7 +102,7 @@ Comment[x-test]=xxDesktop Session Login and Logoutxx
Comment[zh_CN]=桌面会话登录和注销
Comment[zh_TW]=桌面作業階段登入與登出
X-KDE-Keywords=ksmserver,session,logout,confirmation,save,restore
X-KDE-Keywords=ksmserver,session,logout,confirmation,save,restore,efi,uefi,bios
X-KDE-Keywords[bs]=ksmserver,sesija,odjava,potvrda,snimanje,vrati
X-KDE-Keywords[ca]=ksmserver,sessió,sortida,confirmació,desa,restaura
X-KDE-Keywords[ca@valencia]=ksmserver,sessió,eixida,confirmació,guarda,restaura
......
......@@ -23,8 +23,11 @@
#include <kcmodule.h>
class QAction;
class SMServerConfigImpl;
class OrgFreedesktopLogin1ManagerInterface;
class SMServerConfig : public KCModule
{
......@@ -38,7 +41,13 @@ public:
void defaults() override;
private:
void initFirmwareSetup();
void checkFirmwareSetupRequested();
SMServerConfigImpl* dialog;
OrgFreedesktopLogin1ManagerInterface *m_login1Manager = nullptr;
QAction *m_rebootNowAction = nullptr;
bool m_isUefi = false;
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Manager">
<property name="RebootToFirmwareSetup" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<method name="SetRebootToFirmwareSetup">
<arg type="b" direction="in"/>
</method>
<method name="CanRebootToFirmwareSetup">
<arg type="s" direction="out" />
</method>
</interface>
</node>
......@@ -127,6 +127,32 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="firmwareSetupBox">
<property name="title">
<string>Firmware Setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="KMessageWidget" name="firmwareSetupMessageWidget">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="firmwareSetupCheck">
<property name="toolTip">
<string>When the computer is restarted the next time, enter firmware setup screen (e.g. UEFI or BIOS setup)</string>
</property>
<property name="text">
<string>Enter firmware setup on next restart</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
......@@ -144,8 +170,10 @@
</widget>
<customwidgets>
<customwidget>
<class>QLineEdit</class>
<header>qlineedit.h</header>
<class>KMessageWidget</class>
<extends>QFrame</extends>
<header>kmessagewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
......
......@@ -27,6 +27,10 @@ SMServerConfigImpl::SMServerConfigImpl(QWidget *parent ) : SMServerConfigDlg(par
connect(rebootRadio,&QAbstractButton::toggled, this, &SMServerConfigImpl::configChanged);
connect(excludeLineedit,&QLineEdit::textChanged,this, &SMServerConfigImpl::configChanged);
connect(offerShutdownCheck,&QAbstractButton::toggled,this, &SMServerConfigImpl::configChanged);
firmwareSetupBox->hide();
firmwareSetupMessageWidget->hide();
}
SMServerConfigImpl::~SMServerConfigImpl(){
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment