#include "saverwidget.h" #include "ui_saver.h" #include "screensaver.h" #include "deadlinetype.h" #include "config.h" #include #include #include #include #include #include #include #include #define C_ZERO QLatin1Char('0') static QString formatTime(qlonglong span) { QString ret; qlonglong days = span / 86400; if (days > 0) { ret = QString::number(days) + "d "; span -= 86400 * days; } return ret + QString("%1:%2:%3").arg(span / 3600, 2, 10, C_ZERO).arg((span % 3600) / 60, 2, 10, C_ZERO).arg(span % 60, 2, 10, C_ZERO); } SaverWidget::SaverWidget(WId parentWinId, QWidget *parent) : QWidget(parent), ui(new Ui::Saver), _parentWinId(parentWinId), _logoutDeadline(0), _shutdownDeadline(0), _counter(0), _deadlineType(DeadlineType::Unknown), _standbyDisabled(false), _isLocked(false), _unixSocket(nullptr), _display(QString::fromLocal8Bit(qgetenv("DISPLAY"))) { int i = _display.indexOf('.'); if (i != -1) { _display = _display.left(i); } QString qss = Config::getMainQss(); qDebug() << "Applying QSS: " << qss; this->setStyleSheet(qss); ui->setupUi(this); QTimer *t = new QTimer(this); t->setInterval(1000); connect(t, &QTimer::timeout, [=]() { if (_counter % 60 == 0) { this->reloadValues(); } if (!_isLocked && _counter % 4 == 0) { _isLocked = ScreenSaver::isLocked(); } _counter++; qlonglong now = QDateTime::currentMSecsSinceEpoch() / 1000; // Determine what's timing out next (session/schedule) const DeadlineType *type; qlonglong remaining = 0; do { qlonglong shutdownRemaining = _shutdownDeadline - now; qlonglong logoutRemaining = _logoutDeadline - now; if (shutdownRemaining > -330 && (shutdownRemaining < logoutRemaining || logoutRemaining <= -330)) { type = DeadlineType::Shutdown; remaining = shutdownRemaining; } else if (logoutRemaining > -330) { type = DeadlineType::IdleKill; remaining = logoutRemaining; } else { type = DeadlineType::NoTimeout; } } while (0); if (remaining < 0) { remaining = 0; } ui->lblHeader->setText(type->headerLine(_isLocked).arg(formatTime(remaining))); ui->lblClock->setText(QDateTime::currentDateTime().toString(QLocale().dateFormat() + " HH:mm ")); if (_deadlineType != type) { _deadlineType = type; ui->lblText->setText(type->bodyText(_isLocked)); } bool shouldDisable = (remaining > 0 && remaining < 310); if (_standbyDisabled != shouldDisable) { _standbyDisabled = shouldDisable; if (shouldDisable) { ScreenSaver::allowSaverAndStandby(false); ScreenSaver::forceScreenOn(); } else { ScreenSaver::allowSaverAndStandby(true); } } }); t->start(); reloadValues(); } SaverWidget::~SaverWidget() { delete ui; } void SaverWidget::reloadValues() { if (_unixSocket != nullptr) { _unixSocket->blockSignals(true); _unixSocket->deleteLater(); } _unixSocket = new QLocalSocket(); connect(_unixSocket, &QLocalSocket::connected, [=]() { qDebug() << "Connected to daewmweon"; _unixSocket->write((QLatin1String("get ") + _display).toLocal8Bit()); QTimer::singleShot(1000, [this]() { _unixSocket->disconnectFromServer(); }); }); connect(_unixSocket, QOverload::of(&QLocalSocket::error), [=](QLocalSocket::LocalSocketError err) { qDebug() << "Local socket error:" << err; }); connect(_unixSocket, &QLocalSocket::disconnected, this, &SaverWidget::parseDaemonData); _unixSocket->connectToServer("/run/idle-daemon"); } void SaverWidget::parseDaemonData() { QTextStream ts(_unixSocket); QString line; #define SEC_NONE 0 #define SEC_GENERAL 1 #define SEC_ME 2 #define STORE(x) else if (key == QLatin1String( #x )) x = value.toString() int sec = SEC_NONE; QString nextAction, nextActionTime, logoutTime, locked; while (!ts.atEnd()) { line = ts.readLine(); if (line.isEmpty()) continue; if (line.at(0) == QLatin1Char('[')) { // Section if (line == QLatin1String("[General]")) { sec = SEC_GENERAL; } else if ( line == "[" + _display + "]") { sec = SEC_ME; } else { sec = SEC_NONE; } } else { // Value int i = line.indexOf(QLatin1Char('=')); if (i == -1) continue; const QStringRef key(&line, 0, i); const QStringRef value(&line, i+ 1, line.size() - (i + 1)); if (sec == SEC_GENERAL) { if (false); STORE(nextAction); STORE(nextActionTime); } else if (sec == SEC_ME) { if (false); STORE(logoutTime); STORE(locked); } } } if (nextAction.isEmpty() || nextAction == QLatin1String("none") || nextActionTime.isEmpty()) { _shutdownDeadline = 0; } else { _shutdownDeadline = nextActionTime.toLongLong(); } _logoutDeadline = logoutTime.toLongLong(); if (!_isLocked && locked.toInt() != 0) { _isLocked = true; } // TODO: Load text strings for everything _deadlineType = DeadlineType::Unknown; }