]> Nutra Git (v2) - gamesguru/feather.git/commitdiff
Inactivity lock timeout
authortobtoht <thotbot@protonmail.com>
Fri, 4 Mar 2022 16:20:17 +0000 (17:20 +0100)
committertobtoht <thotbot@protonmail.com>
Fri, 4 Mar 2022 16:20:17 +0000 (17:20 +0100)
src/MainWindow.cpp
src/MainWindow.h
src/SettingsDialog.cpp
src/SettingsDialog.ui
src/WindowManager.cpp
src/WindowManager.h
src/main.cpp
src/utils/EventFilter.cpp [new file with mode: 0644]
src/utils/EventFilter.h [new file with mode: 0644]
src/utils/config.cpp
src/utils/config.h

index ef7b9c5d9ed22207d66b7eb7d0852d5ac427e6b0..3f82152b6b9282b0712dd549cc52c5b59c9d8c12 100644 (file)
@@ -87,6 +87,11 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
 #ifdef DONATE_BEG
     this->donationNag();
 #endif
+
+    connect(m_windowManager->eventFilter, &EventFilter::userActivity, this, &MainWindow::userActivity);
+    connect(&m_checkUserActivity, &QTimer::timeout, this, &MainWindow::checkUserActivity);
+    m_checkUserActivity.setInterval(5000);
+    m_checkUserActivity.start();
 }
 
 void MainWindow::initStatusBar() {
@@ -1579,11 +1584,12 @@ void MainWindow::updateRecentlyOpenedMenu() {
 bool MainWindow::verifyPassword() {
     bool ok;
     while (true) {
-        QString password = QInputDialog::getText(this, "Enter password", "Please enter your password:", QLineEdit::EchoMode::Password, "", &ok);
-        if (!ok) { // Dialog cancelled
+        PasswordDialog passwordDialog{this->walletName(), false, this};
+        int ret = passwordDialog.exec();
+        if (ret == QDialog::Rejected) {
             return false;
         }
-        if (password != m_ctx->wallet->getPassword()) {
+        if (passwordDialog.password != m_ctx->wallet->getPassword()) {
             QMessageBox::warning(this, "Error", "Incorrect password");
             continue;
         }
@@ -1600,6 +1606,37 @@ void MainWindow::patchStylesheetMac() {
     qApp->setStyleSheet(styleSheet);
 }
 
+void MainWindow::userActivity() {
+    m_userLastActive = QDateTime::currentSecsSinceEpoch();
+}
+
+void MainWindow::checkUserActivity() {
+    if (!config()->get(Config::inactivityLockEnabled).toBool()) {
+        return;
+    }
+
+    if (m_constructingTransaction) {
+        return;
+    }
+
+    if ((m_userLastActive + (config()->get(Config::inactivityLockTimeout).toInt()*60)) < QDateTime::currentSecsSinceEpoch()) {
+        m_checkUserActivity.stop();
+        qInfo() << "Locking wallet for inactivity";
+        if (!this->verifyPassword()) {
+            this->setEnabled(false);
+            this->close();
+            // This doesn't close the wallet immediately.
+            do {
+                QApplication::processEvents();
+                // Because running it a single time is apparently not enough.
+                // TODO: Qt bug? Need proper fix for this.
+            } while (QApplication::hasPendingEvents());
+        } else {
+            m_checkUserActivity.start();
+        }
+    }
+}
+
 void MainWindow::toggleSearchbar(bool visible) {
     config()->set(Config::showSearchbar, visible);
 
index aa737ecd515d968f55f2470ed7513926cca0c547..3b3ffdbcdb33ae6d2ed005fa1d3671639b1326bb 100644 (file)
@@ -30,6 +30,7 @@
 #include "model/CoinsProxyModel.h"
 #include "utils/networking.h"
 #include "utils/config.h"
+#include "utils/EventFilter.h"
 #include "widgets/CCSWidget.h"
 #include "widgets/RedditWidget.h"
 #include "widgets/TickerWidget.h"
@@ -215,6 +216,8 @@ private:
     void updateWidgetIcons();
     bool verifyPassword();
     void patchStylesheetMac();
+    void userActivity();
+    void checkUserActivity();
 
     QIcon hardwareDevicePairedIcon();
     QIcon hardwareDeviceUnpairedIcon();
@@ -260,6 +263,7 @@ private:
     QMap<QString, ToggleTab*> m_tabShowHideMapper;
 
     QTimer m_updateBytes;
+    QTimer m_checkUserActivity;
 
     QString m_statusText;
     int m_statusDots;
@@ -269,6 +273,9 @@ private:
     QTimer m_txTimer;
 
     bool cleanedUp = false;
+
+    EventFilter *m_eventFilter = nullptr;
+    qint64 m_userLastActive = QDateTime::currentSecsSinceEpoch();
 };
 
 #endif // FEATHER_MAINWINDOW_H
index 18c27ea2a8d8e799eb2df3f346dab587171810f8..77361f708a7edfd7b8f978963e0f6b0aeda75d9d 100644 (file)
@@ -31,6 +31,12 @@ Settings::Settings(QSharedPointer<AppContext> ctx, QWidget *parent)
        config()->set(Config::disableLogging, toggled);
        WalletManager::instance()->setLogLevel(toggled ? -1 : config()->get(Config::logLevel).toInt());
     });
+    connect(ui->checkBox_inactivityLockTimeout, &QCheckBox::toggled, [](bool toggled){
+        config()->set(Config::inactivityLockEnabled, toggled);
+    });
+    connect(ui->spinBox_inactivityLockTimeout, QOverload<int>::of(&QSpinBox::valueChanged), [](int value){
+        config()->set(Config::inactivityLockTimeout, value);
+    });
 
     connect(ui->closeButton, &QDialogButtonBox::accepted, this, &Settings::close);
 
@@ -44,6 +50,8 @@ Settings::Settings(QSharedPointer<AppContext> ctx, QWidget *parent)
     ui->checkBox_externalLink->setChecked(config()->get(Config::warnOnExternalLink).toBool());
     ui->checkBox_hideBalance->setChecked(config()->get(Config::hideBalance).toBool());
     ui->checkBox_disableLogging->setChecked(config()->get(Config::disableLogging).toBool());
+    ui->checkBox_inactivityLockTimeout->setChecked(config()->get(Config::inactivityLockEnabled).toBool());
+    ui->spinBox_inactivityLockTimeout->setValue(config()->get(Config::inactivityLockTimeout).toInt());
 
     // setup comboboxes
     this->setupSkinCombobox();
index 93b437f3e01785e0a0a4ad6dc58f1c2d01981c29..9f83b365cced39c38f68ea8c3cee65fa83becc94 100644 (file)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>915</width>
-    <height>519</height>
+    <height>553</height>
    </rect>
   </property>
   <property name="windowTitle">
          </property>
         </widget>
        </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_9">
+         <item>
+          <widget class="QCheckBox" name="checkBox_inactivityLockTimeout">
+           <property name="text">
+            <string>Lock wallet on inactivity after</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="spinBox_inactivityLockTimeout">
+           <property name="minimum">
+            <number>1</number>
+           </property>
+           <property name="maximum">
+            <number>120</number>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_16">
+           <property name="text">
+            <string>minutes</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>0</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="tab_node">
index a1e87a785ee8fe261f204bc4ee19682332fce792..1c4a1468b4ec3bdc5a063ca5176d880d6f1d7767 100644 (file)
@@ -15,7 +15,9 @@
 #include "utils/TorManager.h"
 #include "utils/WebsocketNotifier.h"
 
-WindowManager::WindowManager() {
+WindowManager::WindowManager(EventFilter *eventFilter)
+    : eventFilter(eventFilter)
+{
     m_walletManager = WalletManager::instance();
     m_splashDialog = new SplashDialog;
     m_cleanupThread = new QThread();
index 93bb9db6ed8b900687feeacbe95081500be4d861..d7a0ee2ce4abfc1b80a1c657c4f9c4ce7259e2f4 100644 (file)
@@ -17,7 +17,7 @@ class WindowManager : public QObject {
 Q_OBJECT
 
 public:
-    explicit WindowManager();
+    explicit WindowManager(EventFilter *eventFilter);
     ~WindowManager() override;
 
     void wizardOpenWallet();
@@ -28,6 +28,8 @@ public:
     void restartApplication(const QString &binaryFilename);
     void raise();
 
+    EventFilter *eventFilter;
+
 signals:
     void torSettingsChanged();
 
index 29c262d53d27a189d74e452df081ef8277dcab6d..243b3f4b1267f6706a5cf9256de992936a39049f 100644 (file)
@@ -11,6 +11,7 @@
 #include "config-feather.h"
 #include "constants.h"
 #include "MainWindow.h"
+#include "utils/EventFilter.h"
 #include "WindowManager.h"
 
 #if defined(Q_OS_WIN)
@@ -223,11 +224,16 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
     qRegisterMetaType<TxProofResult>("TxProofResult");
     qRegisterMetaType<QPair<bool, bool>>();
 
-    WindowManager windowManager;
+    EventFilter filter;
+    app.installEventFilter(&filter);
+
+    WindowManager windowManager(&filter);
 
     QObject::connect(&app, &SingleApplication::instanceStarted, [&windowManager]() {
         windowManager.raise();
     });
 
+
+
     return QApplication::exec();
 }
diff --git a/src/utils/EventFilter.cpp b/src/utils/EventFilter.cpp
new file mode 100644 (file)
index 0000000..60b9d3b
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2022 The Monero Project
+
+#include "EventFilter.h"
+
+#include <QKeyEvent>
+#include <QDebug>
+
+EventFilter::EventFilter(QObject *parent)
+    : QObject(parent)
+{}
+
+bool EventFilter::eventFilter(QObject *obj, QEvent *ev) {
+    if (ev->type() == QEvent::KeyPress || ev->type() == QEvent::MouseButtonRelease) {
+        emit userActivity();
+    }
+
+    return QObject::eventFilter(obj, ev);
+}
\ No newline at end of file
diff --git a/src/utils/EventFilter.h b/src/utils/EventFilter.h
new file mode 100644 (file)
index 0000000..2b807df
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2022 The Monero Project
+
+#ifndef FEATHER_EVENTFILTER_H
+#define FEATHER_EVENTFILTER_H
+
+#include <QObject>
+
+class EventFilter : public QObject
+{
+Q_OBJECT
+
+public:
+    explicit EventFilter(QObject *parent = nullptr);
+
+protected:
+    bool eventFilter(QObject *obj, QEvent *ev);
+
+
+signals:
+    void userActivity();
+};
+
+
+#endif //FEATHER_EVENTFILTER_H
index 8c39d77bc12300211ec41f6852a8cde3804b84c5..5157ee9396b37126731c26e83bfd2791e84bf9b5 100644 (file)
@@ -65,6 +65,8 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
         {Config::dateFormat, {QS("dateFormat"), "yyyy-MM-dd"}},
         {Config::timeFormat, {QS("timeFormat"), "HH:mm"}},
         {Config::balanceDisplay, {QS("balanceDisplay"), Config::BalanceDisplay::spendablePlusUnconfirmed}},
+        {Config::inactivityLockEnabled, {QS("inactivityLockEnabled"), false}},
+        {Config::inactivityLockTimeout, {QS("inactivityLockTimeout"), 10}},
 
         {Config::multiBroadcast, {QS("multiBroadcast"), true}},
         {Config::warnOnExternalLink,{QS("warnOnExternalLink"), true}},
index 3d1f19f43be7b124ed96b95bd24e8eb485cbc43c..7c2a360163e87afba9e857e18f4edaf6c665ebf7 100644 (file)
@@ -69,6 +69,8 @@ public:
         dateFormat,
         timeFormat,
         balanceDisplay,
+        inactivityLockEnabled,
+        inactivityLockTimeout,
 
         multiBroadcast,
         warnOnExternalLink,