summaryrefslogblamecommitdiffstats
path: root/src/saverwidget.cpp
blob: 359c2bdd8b807d343d995ddb562547ee9d206602 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                        
                         
                   




                    
                
                 

                       
 
                               






                                           
                             







                                                                                                                                          


                         
                                         
                            


                                                        
 



                                    
                                       


                                        





                                        
                                              




                                                                   










                                                                                                               
                    
                                               
             


                            
         
                                                                                       
                                                                                                          




                                                                










                                                         









                                


                                        
     












                                                                                                                                       

 
                                   
 

















































                                                                                                  
 
#include "saverwidget.h"
#include "ui_saver.h"
#include "screensaver.h"
#include "deadlinetype.h"
#include "config.h"

#include <QTimer>
#include <QX11Info>
#include <QDateTime>
#include <QSettings>
#include <QFile>
#include <QDebug>
#include <QLocalSocket>
#include <QHash>

#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<QLocalSocket::LocalSocketError>::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;
}