Skip to content

Commit f2f4676

Browse files
authored
Add reboot option when downloads complete
This commit implements a new "Reboot System" option that allows users to automatically reboot the computer when all downloads are complete, similar to the existing shutdown, suspend, and hibernate options. Closes #10774. PR #23525.
1 parent 8b9064a commit f2f4676

File tree

9 files changed

+90
-16
lines changed

9 files changed

+90
-16
lines changed

src/app/application.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,8 +776,9 @@ void Application::allTorrentsFinished()
776776
bool isShutdown = pref->shutdownWhenDownloadsComplete();
777777
bool isSuspend = pref->suspendWhenDownloadsComplete();
778778
bool isHibernate = pref->hibernateWhenDownloadsComplete();
779+
bool isReboot = pref->rebootWhenDownloadsComplete();
779780

780-
bool haveAction = isExit || isShutdown || isSuspend || isHibernate;
781+
const bool haveAction = isExit || isShutdown || isSuspend || isHibernate || isReboot;
781782
if (!haveAction) return;
782783

783784
ShutdownDialogAction action = ShutdownDialogAction::Exit;
@@ -787,6 +788,8 @@ void Application::allTorrentsFinished()
787788
action = ShutdownDialogAction::Hibernate;
788789
else if (isShutdown)
789790
action = ShutdownDialogAction::Shutdown;
791+
else if (isReboot)
792+
action = ShutdownDialogAction::Reboot;
790793

791794
#ifndef DISABLE_GUI
792795
// ask confirm
@@ -808,6 +811,7 @@ void Application::allTorrentsFinished()
808811
pref->setShutdownWhenDownloadsComplete(false);
809812
pref->setSuspendWhenDownloadsComplete(false);
810813
pref->setHibernateWhenDownloadsComplete(false);
814+
pref->setRebootWhenDownloadsComplete(false);
811815
// Make sure preferences are synced before exiting
812816
m_shutdownAct = action;
813817
}

src/base/preferences.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,19 @@ void Preferences::setShutdownWhenDownloadsComplete(const bool shutdown)
12971297
setValue(u"Preferences/Downloads/AutoShutDownOnCompletion"_s, shutdown);
12981298
}
12991299

1300+
bool Preferences::rebootWhenDownloadsComplete() const
1301+
{
1302+
return value(u"Preferences/Downloads/AutoRebootOnCompletion"_s, false);
1303+
}
1304+
1305+
void Preferences::setRebootWhenDownloadsComplete(const bool reboot)
1306+
{
1307+
if (reboot == rebootWhenDownloadsComplete())
1308+
return;
1309+
1310+
setValue(u"Preferences/Downloads/AutoRebootOnCompletion"_s, reboot);
1311+
}
1312+
13001313
bool Preferences::suspendWhenDownloadsComplete() const
13011314
{
13021315
return value(u"Preferences/Downloads/AutoSuspendOnCompletion"_s, false);

src/base/preferences.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ class Preferences final : public QObject
287287

288288
bool shutdownWhenDownloadsComplete() const;
289289
void setShutdownWhenDownloadsComplete(bool shutdown);
290+
bool rebootWhenDownloadsComplete() const;
291+
void setRebootWhenDownloadsComplete(bool reboot);
290292
bool suspendWhenDownloadsComplete() const;
291293
void setSuspendWhenDownloadsComplete(bool suspend);
292294
bool hibernateWhenDownloadsComplete() const;

src/base/types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ enum class ShutdownDialogAction
3737
Exit,
3838
Shutdown,
3939
Suspend,
40-
Hibernate
40+
Hibernate,
41+
Reboot
4142
};
4243

4344
using QStringMap = QMap<QString, QString>;

src/base/utils/os.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,30 @@ void Utils::OS::shutdownComputer([[maybe_unused]] const ShutdownDialogAction &ac
8787
{
8888
::SetSuspendState(TRUE, FALSE, FALSE);
8989
}
90-
else
90+
else if (action == ShutdownDialogAction::Shutdown)
9191
{
9292
std::wstring msg = QCoreApplication::translate("misc"
9393
, "qBittorrent will shutdown the computer now because all downloads are complete.").toStdWString();
9494
::InitiateSystemShutdownW(nullptr, msg.data(), 10, TRUE, FALSE);
9595
}
96+
else if (action == ShutdownDialogAction::Reboot)
97+
{
98+
std::wstring msg = QCoreApplication::translate("misc"
99+
, "qBittorrent will reboot the computer now because all downloads are complete.").toStdWString();
100+
::InitiateSystemShutdownW(nullptr, msg.data(), 10, TRUE, TRUE);
101+
}
96102

97103
// Disable shutdown privilege.
98104
tkp.Privileges[0].Attributes = 0;
99105
::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
100106

101107
#elif defined(Q_OS_MACOS)
102-
AEEventID EventToSend;
103-
if (action != ShutdownDialogAction::Shutdown)
108+
AEEventID EventToSend {};
109+
if (action == ShutdownDialogAction::Suspend)
104110
EventToSend = kAESleep;
105-
else
111+
else if (action == ShutdownDialogAction::Reboot)
112+
EventToSend = kAERestart;
113+
else if (action == ShutdownDialogAction::Shutdown)
106114
EventToSend = kAEShutDown;
107115
AEAddressDesc targetDesc;
108116
const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess};
@@ -133,7 +141,7 @@ void Utils::OS::shutdownComputer([[maybe_unused]] const ShutdownDialogAction &ac
133141

134142
#elif defined(QBT_USES_DBUS)
135143
// Use dbus to power off / suspend the system
136-
if (action != ShutdownDialogAction::Shutdown)
144+
if ((action == ShutdownDialogAction::Suspend) || (action == ShutdownDialogAction::Hibernate))
137145
{
138146
// Some recent systems use systemd's logind
139147
QDBusInterface login1Iface(u"org.freedesktop.login1"_s, u"/org/freedesktop/login1"_s,
@@ -166,7 +174,7 @@ void Utils::OS::shutdownComputer([[maybe_unused]] const ShutdownDialogAction &ac
166174
else
167175
halIface.call(u"Hibernate"_s);
168176
}
169-
else
177+
else if (action == ShutdownDialogAction::Shutdown)
170178
{
171179
// Some recent systems use systemd's logind
172180
QDBusInterface login1Iface(u"org.freedesktop.login1"_s, u"/org/freedesktop/login1"_s,
@@ -190,6 +198,30 @@ void Utils::OS::shutdownComputer([[maybe_unused]] const ShutdownDialogAction &ac
190198
QDBusConnection::systemBus());
191199
halIface.call(u"Shutdown"_s);
192200
}
201+
else if (action == ShutdownDialogAction::Reboot)
202+
{
203+
// Some recent systems use systemd's logind
204+
QDBusInterface login1Iface(u"org.freedesktop.login1"_s, u"/org/freedesktop/login1"_s,
205+
u"org.freedesktop.login1.Manager"_s, QDBusConnection::systemBus());
206+
if (login1Iface.isValid())
207+
{
208+
login1Iface.call(u"Reboot"_s, false);
209+
return;
210+
}
211+
// Else, other recent systems use ConsoleKit
212+
QDBusInterface consolekitIface(u"org.freedesktop.ConsoleKit"_s, u"/org/freedesktop/ConsoleKit/Manager"_s,
213+
u"org.freedesktop.ConsoleKit.Manager"_s, QDBusConnection::systemBus());
214+
if (consolekitIface.isValid())
215+
{
216+
consolekitIface.call(u"Restart"_s);
217+
return;
218+
}
219+
// HAL (older systems)
220+
QDBusInterface halIface(u"org.freedesktop.Hal"_s, u"/org/freedesktop/Hal/devices/computer"_s,
221+
u"org.freedesktop.Hal.Device.SystemPowerManagement"_s,
222+
QDBusConnection::systemBus());
223+
halIface.call(u"Reboot"_s);
224+
}
193225
#endif
194226
}
195227

src/gui/mainwindow.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,16 @@ MainWindow::MainWindow(IGUIApplication *app, const WindowState initialState, con
388388
autoShutdownGroup->addAction(m_ui->actionAutoShutdown);
389389
autoShutdownGroup->addAction(m_ui->actionAutoSuspend);
390390
autoShutdownGroup->addAction(m_ui->actionAutoHibernate);
391+
autoShutdownGroup->addAction(m_ui->actionAutoReboot);
391392
#if (!defined(Q_OS_UNIX) || defined(Q_OS_MACOS)) || defined(QBT_USES_DBUS)
392393
m_ui->actionAutoShutdown->setChecked(pref->shutdownWhenDownloadsComplete());
394+
m_ui->actionAutoReboot->setChecked(pref->rebootWhenDownloadsComplete());
393395
m_ui->actionAutoSuspend->setChecked(pref->suspendWhenDownloadsComplete());
394396
m_ui->actionAutoHibernate->setChecked(pref->hibernateWhenDownloadsComplete());
397+
#ifdef Q_OS_MACOS
398+
// macOS doesn't support Hibernate via Apple Events API
399+
m_ui->actionAutoHibernate->setDisabled(true);
400+
#endif
395401
#else
396402
m_ui->actionAutoShutdown->setDisabled(true);
397403
m_ui->actionAutoSuspend->setDisabled(true);
@@ -1790,30 +1796,31 @@ void MainWindow::on_actionCriticalMessages_triggered(const bool checked)
17901796
setExecutionLogMsgTypes(flags);
17911797
}
17921798

1793-
void MainWindow::on_actionAutoExit_toggled(bool enabled)
1799+
void MainWindow::on_actionAutoExit_toggled(const bool enabled)
17941800
{
1795-
qDebug() << Q_FUNC_INFO << enabled;
17961801
Preferences::instance()->setShutdownqBTWhenDownloadsComplete(enabled);
17971802
}
17981803

1799-
void MainWindow::on_actionAutoSuspend_toggled(bool enabled)
1804+
void MainWindow::on_actionAutoSuspend_toggled(const bool enabled)
18001805
{
1801-
qDebug() << Q_FUNC_INFO << enabled;
18021806
Preferences::instance()->setSuspendWhenDownloadsComplete(enabled);
18031807
}
18041808

1805-
void MainWindow::on_actionAutoHibernate_toggled(bool enabled)
1809+
void MainWindow::on_actionAutoHibernate_toggled(const bool enabled)
18061810
{
1807-
qDebug() << Q_FUNC_INFO << enabled;
18081811
Preferences::instance()->setHibernateWhenDownloadsComplete(enabled);
18091812
}
18101813

1811-
void MainWindow::on_actionAutoShutdown_toggled(bool enabled)
1814+
void MainWindow::on_actionAutoShutdown_toggled(const bool enabled)
18121815
{
1813-
qDebug() << Q_FUNC_INFO << enabled;
18141816
Preferences::instance()->setShutdownWhenDownloadsComplete(enabled);
18151817
}
18161818

1819+
void MainWindow::on_actionAutoReboot_toggled(const bool enabled)
1820+
{
1821+
Preferences::instance()->setRebootWhenDownloadsComplete(enabled);
1822+
}
1823+
18171824
void MainWindow::updatePowerManagementState() const
18181825
{
18191826
const auto *pref = Preferences::instance();

src/gui/mainwindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ private slots:
158158
void on_actionAutoSuspend_toggled(bool);
159159
void on_actionAutoHibernate_toggled(bool);
160160
void on_actionAutoShutdown_toggled(bool);
161+
void on_actionAutoReboot_toggled(bool);
161162
void on_actionAbout_triggered();
162163
void on_actionStatistics_triggered();
163164
void on_actionCreateTorrent_triggered();

src/gui/mainwindow.ui

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<addaction name="actionAutoExit"/>
7777
<addaction name="actionAutoSuspend"/>
7878
<addaction name="actionAutoHibernate"/>
79+
<addaction name="actionAutoReboot"/>
7980
<addaction name="actionAutoShutdown"/>
8081
</widget>
8182
<addaction name="actionCreateTorrent"/>
@@ -397,6 +398,14 @@
397398
<string>Sh&amp;utdown System</string>
398399
</property>
399400
</action>
401+
<action name="actionAutoReboot">
402+
<property name="checkable">
403+
<bool>true</bool>
404+
</property>
405+
<property name="text">
406+
<string>&amp;Reboot System</string>
407+
</property>
408+
</action>
400409
<action name="actionAutoShutdownDisabled">
401410
<property name="checkable">
402411
<bool>true</bool>

src/gui/shutdownconfirmdialog.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ void ShutdownConfirmDialog::initText()
134134
okButton->setText(tr("&Hibernate Now"));
135135
setWindowTitle(tr("Hibernate confirmation"));
136136
break;
137+
case ShutdownDialogAction::Reboot:
138+
m_msg = tr("The computer is going to reboot.");
139+
okButton->setText(tr("&Reboot Now"));
140+
setWindowTitle(tr("Reboot confirmation"));
141+
break;
137142
}
138143

139144
m_msg += u'\n';

0 commit comments

Comments
 (0)