Skip to content

Commit

Permalink
Update 1.7.0:
Browse files Browse the repository at this point in the history
* Added command line option to allow self restarting if Bluetooth device
  becomes unavailable.

  Older versions had to end program execution because when a Bluetooth
  device becomes unavailable, it won't be available for the program even
  when that Bluetooth device becomes available again.

  For more information, read:
  https://doc.qt.io/qt-6/qbluetoothlocaldevice.html#isValid
  • Loading branch information
brookiestein committed Jul 29, 2024
1 parent 519330f commit 5cbb24b
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.28)

project(BtScreenLocker
VERSION 1.6.5
VERSION 1.7.0
LANGUAGES CXX
DESCRIPTION "Daemon to lock your screen if trusted Bluetooth devices go away."
)
Expand Down
66 changes: 56 additions & 10 deletions src/listener.cpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
#include "listener.hpp"

#include <QApplication>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QBluetoothSocket>
#include <QDebug>
#include <QDir>
#include <QEventLoop>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
#include <QStandardPaths>

#include "connection.hpp"
#include "devicechooser.hpp"
#include "logger.hpp"

Listener::Listener(ScreenLocker &screenLocker, QObject *parent)
Listener::Listener(ScreenLocker &screenLocker, bool autorestart, int seconds, QObject *parent)
: QObject{parent}
, m_dbusConnection(QDBusConnection::sessionBus())
, m_screenLocker(screenLocker)
, m_restarting(false)
, m_autorestart(autorestart)
, m_seconds(seconds)
, m_logger(Logger::instance())
, m_stopped(false)
{

if (not m_localDevice.isValid()) {
auto message = tr("There isn't a valid Bluetooth device on this machine. Can't do anything.");
QMessageBox::critical(nullptr,
tr("Error"),
message);
m_logger.log(message, Q_FUNC_INFO, Logger::FATAL);

if (not m_autorestart) {
QMessageBox::critical(nullptr, tr("Error"), message);
m_logger.log(message, Q_FUNC_INFO, Logger::FATAL);
}

message += tr(" Restarting in %1 seconds.").arg(QString::number(m_seconds));
QMessageBox::warning(nullptr, tr("Warning"), message);
m_logger.log(message, Q_FUNC_INFO);
restart();
} else {
m_localDevice.powerOn();
}
Expand Down Expand Up @@ -81,6 +91,10 @@ Listener::~Listener()

void Listener::start()
{
if (m_restarting) {
return;
}

if (m_settings->allKeys().isEmpty()) {
startDiscovery();
return;
Expand All @@ -99,6 +113,10 @@ void Listener::start()

void Listener::startDiscovery()
{
if (m_restarting) {
return;
}

/* If constructor started it, but in main.cpp user started discovery. */
m_lookForTrustedDeviceTimer.stop();
m_logger.log(tr("Discoverying devices..."), Q_FUNC_INFO);
Expand All @@ -110,18 +128,46 @@ void Listener::startDiscovery()
tr("Please wait up to 30 seconds, I'll show you the devices I discover."));
}

void Listener::restart()
{
m_restarting = true;
m_deviceDiscoverTimer.stop();
m_lookForTrustedDeviceTimer.stop();

QTimer::singleShot(m_seconds * 1'000, [] () {
auto *app = QApplication::instance();
app->quit();
QProcess::startDetached(app->arguments()[0], app->arguments().mid(1));
});
}

void Listener::hostModeStateChanged(QBluetoothLocalDevice::HostMode state)
{
if (state == QBluetoothLocalDevice::HostPoweredOff) {
m_lookForTrustedDeviceTimer.stop();
m_deviceDiscoverTimer.stop();
auto message = tr("Bluetooth device: %1, %2 became unavailable.\n"
"Ending program execution because of this!\n\n"

auto message = tr("Bluetooth device: %1, %2 became unavailable. ")
.arg(m_localDevice.address().toString(), m_localDevice.name());

if (m_autorestart) {
message += tr("Restarting in %1 seconds.").arg(QString::number(m_seconds));
} else {
message += tr("Ending program execution because of this!\n\n"
"If at some point the device: %3 becomes available again, please re-run me.")
.arg(m_localDevice.name(), m_localDevice.address().toString(), m_localDevice.name());
.arg(m_localDevice.address().toString());
}

QMessageBox::critical(nullptr, tr("Error"), message);
m_logger.log(message, Q_FUNC_INFO, Logger::ERROR);
emit quit();
if (not m_autorestart) {
emit quit();
return;
}

m_logger.log(tr("Restarting in %1 seconds to be able to use Bluetooth adapter again.")
.arg(QString::number(m_seconds)));
restart();
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/listener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ class Listener : public QObject
ScreenLocker &m_screenLocker;
Logger &m_logger;
bool m_stopped;
bool m_restarting;
bool m_autorestart;
int m_seconds;

QString deviceClassToString(const QBluetoothDeviceInfo &deviceInfo);
void restart();
public:
explicit Listener(ScreenLocker &locker, QObject *parent = nullptr);
explicit Listener(ScreenLocker &locker, bool autorestart = false, int seconds = -1, QObject *parent = nullptr);
~Listener();
void start();
void startDiscovery();
Expand Down
39 changes: 38 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QLocale>
#include <QSharedPointer>
#include <QStandardPaths>
Expand Down Expand Up @@ -96,8 +97,25 @@ int main(int argc, char *argv[])
return enableAutostart(parser, logger, argv[0]);
}

QString timeToRestart = parser.value("time-to-restart");
bool autorestart = parser.isSet("auto-restart");
bool ok {false};
int seconds = timeToRestart.toInt(&ok);

if (autorestart) {
if (not timeToRestart.isEmpty() and not ok) {
auto message = QObject::tr("%1 is not a valid value for 'seconds'.").arg(timeToRestart);
QMessageBox::critical(nullptr, QObject::tr("Error"), message);
logger.log(message, Q_FUNC_INFO, Logger::TYPE::FATAL);
}

if (timeToRestart.isEmpty()) {
seconds = 10; /* Default to 10 seconds if user didn't provide it. */
}
}

ScreenLocker locker;
Listener listener(locker);
Listener listener(locker, autorestart, seconds);
a.connect(&listener, &Listener::lockScreen, &locker, &ScreenLocker::lockScreen);
a.connect(&listener, &Listener::quit, &a, &QApplication::quit);
/* When screen is locked, no scan is done.
Expand Down Expand Up @@ -133,6 +151,12 @@ QList<QCommandLineOption> commandLineOptions(const char *name)
{
QList<QCommandLineOption> options;

options.append(QCommandLineOption(QStringList() << "A" << "auto-restart",
QObject::tr("Allow %1 to restart itself when your Bluetooth device "
"becomes unavailable and availabe again, e.g. when your machine suspends. "
"Default is 10 seconds.").arg(name))
);

options.append(QCommandLineOption(QStringList() << "a" << "autostart",
QObject::tr("Register %1 to automatically start on boot.\n"
"(Will always autostart with passed parameters).").arg(name))
Expand Down Expand Up @@ -170,6 +194,11 @@ QList<QCommandLineOption> commandLineOptions(const char *name)
QObject::tr("Same as --discover, but for an already running %1 instance.").arg(name))
);

options.append(QCommandLineOption(QStringList() << "t" << "time-to-restart",
QObject::tr("Time to wait before auto-restarting %1. (Only useful when combined with -A)").arg(name),
"seconds")
);

options.append(QCommandLineOption(QStringList() << "V" << "verbose",
QObject::tr("Enable verbose log."))
);
Expand Down Expand Up @@ -221,6 +250,14 @@ int enableAutostart(const QCommandLineParser &parser, Logger &logger, const char
}

QStringList args;
if (parser.isSet("auto-restart")) {
args << "-A";
}

if (parser.isSet("time-to-restart")) {
args << "-t" << parser.value("time-to-restart");
}

if (parser.isSet("debug")) {
args << "-D";
}
Expand Down
Binary file modified translations/BtScreenLocker_es_US.qm
Binary file not shown.
42 changes: 41 additions & 1 deletion translations/BtScreenLocker_es_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ Puede estar lejos o tener el Bluetooth desactivado.</translation>
Ending program execution because of this!

If at some point the device: %3 becomes available again, please re-run me.</source>
<translation>El dispositivo Bluetooth: %1, %2 ya no está disponible.
<translation type="vanished">El dispositivo Bluetooth: %1, %2 ya no está disponible.
¡Terminando ejecución del programa!

Si en algún momento el dispositivo: %3 vuelve a estar disponible, por favor ejecútame de nuevo.</translation>
Expand Down Expand Up @@ -300,6 +300,30 @@ Would you like to pair it?</source>
<translation>El dispositivo Bluetooth: %1 - %2 no está emparejado. Es una buena idea tenerlo emparejado.
¿Te gustaría emparejarlo?</translation>
</message>
<message>
<source>Restarting in %1 seconds to be able to use Bluetooth adapter again.</source>
<translation>Reiniciando en %1 segundos para ser capaz de usar el adaptador Bluetooth de nuevo.</translation>
</message>
<message>
<source>Bluetooth device: %1, %2 became unavailable. </source>
<translation>El dispositivo Bluetooth %1, %2 dejó de estar disponible. </translation>
</message>
<message>
<source>Restarting in %1 seconds.</source>
<translation>Reiniciando en %1 segundos.</translation>
</message>
<message>
<source>Ending program execution because of this!

If at some point the device: %3 becomes available again, please re-run me.</source>
<translation>¡Finalizando la ejecución del programa por esto!

Si en algún momento el dispositivo: %3 vuelve a estar disponible de nuevo, por favor ejecútame de nuevo.</translation>
</message>
<message>
<source> Restarting in %1 seconds.</source>
<translation> Reiniciando en %1 segundos.</translation>
</message>
</context>
<context>
<name>QObject</name>
Expand Down Expand Up @@ -423,6 +447,22 @@ Error message: %1</source>
<translation>No se pudo registrar el servicio D-BUS. No será posible responder a mensajes IPC.
Mensaje de error: %1</translation>
</message>
<message>
<source>Time to wait before auto-restarting %1. (Only useful when combined with -A)</source>
<translation>Tiempo para esperar antes de reiniciar %1 automáticamente. (Útil únicamente cuando está combinado con -A)</translation>
</message>
<message>
<source>%1 is not a valid value for &apos;seconds&apos;.</source>
<translation>%1 no es un valor válido para &apos;segundos&apos;.</translation>
</message>
<message>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
<source>Allow %1 to restart itself when your Bluetooth device becomes unavailable and availabe again, e.g. when your machine suspends. Default is 10 seconds.</source>
<translation>Permitir que %1 se reinicie cuando tu dispositivo Bluetooth se vuelve inaccesible and vuelve a estar disponible de nuevo, por ejemplo, cuando tu computadora se suspende. 10 segundos por defecto.</translation>
</message>
</context>
<context>
<name>ScreenLocker</name>
Expand Down

0 comments on commit 5cbb24b

Please sign in to comment.