#include "saverwidget.h" #include "ui_saver.h" #include "screensaver.h" #include #include #include #include #include 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::Unspecified), _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 % 10 == 0) { _isLocked = ScreenSaver::isLocked(); } _counter++; qlonglong now = QDateTime::currentMSecsSinceEpoch() / 1000; // Determine what's timing out next (session/schedule) DeadlineType type; qlonglong remaining = 0; if (_shutdownDeadline > 0 && _shutdownDeadline < _logoutDeadline) { type = DeadlineType::Shutdown; remaining = _shutdownDeadline - now; } else if (_logoutDeadline > 0) { type = (_isLocked ? DeadlineType::IdleKillLocked : DeadlineType::IdleKill); remaining = _logoutDeadline - now; } else { type = DeadlineType::Unspecified; } if (type == DeadlineType::Shutdown) { // Shutdown is about to happen (sooner than idle logout) if (remaining < 0) { ui->lblHeader->setText(QString("Dieser Rechner ist seit %1 ausgeschaltet (theoretisch zumindest)").arg(formatTime(-remaining))); } else { ui->lblHeader->setText(QString("Achtung: Rechner wird in %1 heruntergefahren!").arg(formatTime(remaining))); } } else if (type == DeadlineType::IdleKillLocked) { // Idle logout is about to happen if (remaining < 0) { ui->lblHeader->setText("Diese Sitzung kann durch einen Klick auf 'New Login' beendet werden..."); } else { ui->lblHeader->setText(QString("Diese Sitzung wird in %1 beendet, wenn sie nicht entsperrt wird.").arg(formatTime(remaining))); } } else if (type == DeadlineType::IdleKill) { // Idle logout is about to happen, but password is not required to reactivate session if (remaining < 0) { ui->lblHeader->setText("Hier hat wohl jemand vergessen sich auszuloggen..."); } else { ui->lblHeader->setText(QString("Diese Sitzung wird in %1 beendet, wenn sie nicht weiter verwendet wird.").arg(formatTime(remaining))); } } else { if (_isLocked) { ui->lblHeader->setText("Rechner gesperrt"); } else { ui->lblHeader->setText("Schon schon schon..."); } } ui->lblClock->setText(QDateTime::currentDateTime().toString(QLocale().dateFormat() + " HH:mm ")); displayText(type); bool shouldDisable = remaining < 300; if (_standbyDisabled != shouldDisable) { _standbyDisabled = shouldDisable; if (shouldDisable) { ScreenSaver::allowSaverAndStandby(false); ScreenSaver::forceScreenOn(); } else { ScreenSaver::allowSaverAndStandby(true); } } }); t->start(); this->setMouseTracking(true); 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/idleaction-") + display, QSettings::IniFormat); _logoutDeadline = s.value("lockDeadline", 0).toLongLong(); _shutdownDeadline = s.value("shutdownDeadline", 0).toLongLong(); // TODO: Load text strings for everything _deadlineType = DeadlineType::Unspecified; } void SaverWidget::displayText(DeadlineType dlt) { if (_deadlineType == dlt) return; _deadlineType = dlt; if (dlt == DeadlineType::IdleKillLocked) { ui->lblText->setText("
" "Zum oben angegebenen Zeitpunkt wird die aktuell laufende Sitzung beendet, " "wenn sie zuvor nicht wieder entsperrt wird.
" "Alle noch laufenden Programme (z.B. Word, Photoshop, Matlab, etc.)
" "werden ohne Nachfrage geschlossen. Stellen Sie daher sicher, bis zum angegebenen Zeitpunkt
" "sämtliche sich in Bearbeitung befindlichen Daten abzuspeichern, bzw. die Sitzung wieder zu entsperren.

" "Dies dient dazu zu vermeiden, dass ein Rechner stundenlang gesperrt wird und somit
" "anderen Nutzern nicht zur Verfügung steht."); } else if (dlt == DeadlineType::IdleKill) { ui->lblText->setText("Keine Nutzeraktivität festgestellt.
" "Zum oben angegebenen Zeitpunkt wird die aktuell laufende Sitzung beendet, " "wenn der Rechner nicht mehr verwendet wird.
" "Alle noch laufenden Programme (z.B. Word, Photoshop, Matlab, etc.)
" "werden ohne Nachfrage geschlossen. Stellen Sie daher sicher, bis zum angegebenen Zeitpunkt
" "sämtliche sich in Bearbeitung befindlichen Daten abzuspeichern.

" "Dies dient dazu zu vermeiden, dass ein Rechner stundenlang gesperrt wird und somit
" "anderen Nutzern nicht zur Verfügung steht."); } else if (dlt == DeadlineType::Shutdown) { ui->lblText->setText("Achtung: Zum oben angegebenen Zeitpunkt wird der Computer heruntergefahren bzw. neugestartet.
" "Alle noch laufenden Programme (z.B. Word, Photoshop, Matlab, etc.)
" "werden ohne Nachfrage beendet. Stellen Sie daher sicher, bis zum angegebenen Zeitpunkt
" "sämtliche Daten abzuspeichern und die Sitzung zu verlassen."); } else { ui->lblText->setText(""); } } 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); */ }