summaryrefslogtreecommitdiffstats
path: root/src/saverwidget.cpp
blob: 17353d6f47f3a7ed951ab023ddf88fcaf05be83a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "saverwidget.h"
#include "ui_saver.h"
#include "screensaver.h"
#include "deadlinetype.h"

#include <QTimer>
#include <QX11Info>
#include <QDateTime>
#include <QSettings>
#include <QFile>
#include <X11/Xlib.h>

static const QChar C_ZERO('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),
    _lastMouseFake(0),
    _logoutDeadline(0),
    _shutdownDeadline(0),
    _counter(0),
    _deadlineType(DeadlineType::Unknown),
    _standbyDisabled(false),
    _isLocked(false)
{
    ui->setupUi(this);
    QTimer *t = new QTimer(this);
    t->setInterval(1000);
    connect(t, &QTimer::timeout, [=]() {
        if (_counter % 60 == 0) {
            this->reloadValues();
        }
        if (_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()
{
    QString display = QString::fromLocal8Bit(qgetenv("DISPLAY"));
    int i = display.indexOf('.');
    if (i != -1) {
        display = display.left(i);
    }
    QSettings s(QString("/run/openslx/idleaction-") + display, QSettings::IniFormat);
    _logoutDeadline = s.value("lockDeadline", 0).toLongLong();
    _shutdownDeadline = s.value("shutdownDeadline", 0).toLongLong();
    // TODO: Load text strings for everything
    _deadlineType = DeadlineType::Unknown;
}

void SaverWidget::mouseMoveEvent(QMouseEvent *)
{
    /*
    // Doesn't work, method is never called :-(
    qint64 now = QDateTime::currentMSecsSinceEpoch();
    if (now - _lastMouseFake < 1000)
        return;
    ui->lblText->setText(QString::number(int(now / 1000)));
    _lastMouseFake = now;
    XEvent ev;
    memset(&ev, 0, sizeof(ev));
    ev.type = ButtonPress;
    ev.xbutton.button = 1;
    ev.xbutton.same_screen = True;
    ev.xbutton.root = ev.xbutton.window = ev.xbutton.subwindow = _parentWinId;
    XSendEvent(QX11Info::display(), _parentWinId, True, 0xfff, &ev);
    ev.type = ButtonRelease;
    ev.xbutton.state = 0x100;
    XSendEvent(QX11Info::display(), _parentWinId, True, 0xfff, &ev);
    */
}