Skip to content

Commit

Permalink
[Desktop Sessions KCM] Add Restart to BIOS/UEFI checkbox
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kbroulik committed Mar 13, 2019
1 parent 737b114 commit 0f5c7ed
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 4 deletions.
1 change: 1 addition & 0 deletions kcms/ksmserver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 )

Expand Down
90 changes: 89 additions & 1 deletion kcms/ksmserver/kcmsmserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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."
Expand All @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion kcms/ksmserver/kcmsmserver.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions kcms/ksmserver/kcmsmserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@

#include <kcmodule.h>

class QAction;

class SMServerConfigImpl;

class OrgFreedesktopLogin1ManagerInterface;

class SMServerConfig : public KCModule
{
Expand All @@ -38,7 +41,13 @@ class SMServerConfig : public KCModule
void defaults() override;

private:
void initFirmwareSetup();
void checkFirmwareSetupRequested();
SMServerConfigImpl* dialog;

OrgFreedesktopLogin1ManagerInterface *m_login1Manager = nullptr;
QAction *m_rebootNowAction = nullptr;
bool m_isUefi = false;
};

#endif
15 changes: 15 additions & 0 deletions kcms/ksmserver/org.freedesktop.login1.Manager.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?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>
32 changes: 30 additions & 2 deletions kcms/ksmserver/smserverconfigdlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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/>
Expand Down
4 changes: 4 additions & 0 deletions kcms/ksmserver/smserverconfigimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
}
Expand Down

0 comments on commit 0f5c7ed

Please sign in to comment.