From aace1dc913abc29f9ddba866a295e7cc39c474fa Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Thu, 22 Feb 2024 13:39:59 +0100 Subject: [PATCH] Fix TouchID not being shown after lid close Fixes #8945 Fixes #10315 --- src/gui/DatabaseOpenWidget.cpp | 106 ++++++++++++++++++--------------- src/gui/DatabaseOpenWidget.h | 7 ++- src/quickunlock/TouchID.mm | 4 +- 3 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 10856b149..2a43c529c 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -34,6 +34,7 @@ #include #include #include + namespace { constexpr int clearFormsDelay = 30000; @@ -45,15 +46,6 @@ namespace } return false; } - - bool canPerformQuickUnlock(const QUuid& dbUuid) - { - if (isQuickUnlockAvailable()) { - return getQuickUnlock()->hasKey(dbUuid); - } - Q_UNUSED(dbUuid); - return false; - } } // namespace DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) @@ -174,50 +166,57 @@ void DatabaseOpenWidget::toggleHardwareKeyComponent(bool state) } } -void DatabaseOpenWidget::showEvent(QShowEvent* event) +bool DatabaseOpenWidget::event(QEvent* event) { - DialogyWidget::showEvent(event); - if (isOnQuickUnlockScreen()) { - m_ui->quickUnlockButton->setFocus(); - if (m_db.isNull() || !canPerformQuickUnlock(m_db->publicUuid())) { + bool ret = DialogyWidget::event(event); + + switch (event->type()) { + case QEvent::Show: + case QEvent::WindowActivate: { + if (isOnQuickUnlockScreen() && (m_db.isNull() || !canPerformQuickUnlock())) { resetQuickUnlock(); } - } else { - m_ui->editPassword->setFocus(); - } - m_hideTimer.stop(); + toggleQuickUnlockScreen(); + m_hideTimer.stop(); #ifdef WITH_XC_YUBIKEY #ifdef Q_OS_WIN - m_deviceListener->registerHotplugCallback(true, - true, - YubiKeyInterfaceUSB::YUBICO_USB_VID, - DeviceListener::MATCH_ANY, - &DeviceListenerWin::DEV_CLS_KEYBOARD); - m_deviceListener->registerHotplugCallback(true, - true, - YubiKeyInterfaceUSB::ONLYKEY_USB_VID, - DeviceListener::MATCH_ANY, - &DeviceListenerWin::DEV_CLS_KEYBOARD); + m_deviceListener->registerHotplugCallback(true, + true, + YubiKeyInterfaceUSB::YUBICO_USB_VID, + DeviceListener::MATCH_ANY, + &DeviceListenerWin::DEV_CLS_KEYBOARD); + m_deviceListener->registerHotplugCallback(true, + true, + YubiKeyInterfaceUSB::ONLYKEY_USB_VID, + DeviceListener::MATCH_ANY, + &DeviceListenerWin::DEV_CLS_KEYBOARD); #else - m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::YUBICO_USB_VID); - m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::ONLYKEY_USB_VID); + m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::YUBICO_USB_VID); + m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::ONLYKEY_USB_VID); #endif #endif -} -void DatabaseOpenWidget::hideEvent(QHideEvent* event) -{ - DialogyWidget::hideEvent(event); - - // Schedule form clearing if we are hidden - if (!isVisible()) { - m_hideTimer.start(); + return true; } + case QEvent::Hide: { + // Schedule form clearing if we are hidden + if (!isVisible()) { + m_hideTimer.start(); + } + #ifdef WITH_XC_YUBIKEY - m_deviceListener->deregisterAllHotplugCallbacks(); + m_deviceListener->deregisterAllHotplugCallbacks(); #endif + + return true; + } + + default:; + } + + return ret; } bool DatabaseOpenWidget::unlockingDatabase() @@ -246,12 +245,7 @@ void DatabaseOpenWidget::load(const QString& filename) } } - if (canPerformQuickUnlock(m_db->publicUuid())) { - m_ui->centralStack->setCurrentIndex(1); - m_ui->quickUnlockButton->setFocus(); - } else { - m_ui->editPassword->setFocus(); - } + toggleQuickUnlockScreen(); #ifdef WITH_XC_YUBIKEY // Do initial auto-poll @@ -268,7 +262,7 @@ void DatabaseOpenWidget::clearForms() m_ui->keyFileLineEdit->setShowPassword(false); m_ui->keyFileLineEdit->setClearButtonEnabled(true); m_ui->hardwareKeyCombo->clear(); - m_ui->centralStack->setCurrentIndex(0); + toggleQuickUnlockScreen(); QString error; m_db.reset(new Database()); @@ -387,7 +381,7 @@ QSharedPointer DatabaseOpenWidget::buildDatabaseKey() { auto databaseKey = QSharedPointer::create(); - if (!m_db.isNull() && canPerformQuickUnlock(m_db->publicUuid())) { + if (!m_db.isNull() && canPerformQuickUnlock()) { // try to retrieve the stored password using Windows Hello QByteArray keyData; if (!getQuickUnlock()->getKey(m_db->publicUuid(), keyData)) { @@ -574,11 +568,27 @@ void DatabaseOpenWidget::setUserInteractionLock(bool state) m_unlockingDatabase = state; } -bool DatabaseOpenWidget::isOnQuickUnlockScreen() +bool DatabaseOpenWidget::canPerformQuickUnlock() const +{ + return !m_db.isNull() && isQuickUnlockAvailable() && getQuickUnlock()->hasKey(m_db->publicUuid()); +} + +bool DatabaseOpenWidget::isOnQuickUnlockScreen() const { return m_ui->centralStack->currentIndex() == 1; } +void DatabaseOpenWidget::toggleQuickUnlockScreen() +{ + if (canPerformQuickUnlock()) { + m_ui->centralStack->setCurrentIndex(1); + m_ui->quickUnlockButton->setFocus(); + } else { + m_ui->centralStack->setCurrentIndex(0); + m_ui->editPassword->setFocus(); + } +} + void DatabaseOpenWidget::triggerQuickUnlock() { if (isOnQuickUnlockScreen()) { diff --git a/src/gui/DatabaseOpenWidget.h b/src/gui/DatabaseOpenWidget.h index bc76f6737..2236e52d8 100644 --- a/src/gui/DatabaseOpenWidget.h +++ b/src/gui/DatabaseOpenWidget.h @@ -53,7 +53,9 @@ public: bool unlockingDatabase(); // Quick Unlock helper functions - bool isOnQuickUnlockScreen(); + bool canPerformQuickUnlock() const; + bool isOnQuickUnlockScreen() const; + void toggleQuickUnlockScreen(); void triggerQuickUnlock(); void resetQuickUnlock(); @@ -61,8 +63,7 @@ signals: void dialogFinished(bool accepted); protected: - void showEvent(QShowEvent* event) override; - void hideEvent(QHideEvent* event) override; + bool event(QEvent* event) override; QSharedPointer buildDatabaseKey(); void setUserInteractionLock(bool state); diff --git a/src/quickunlock/TouchID.mm b/src/quickunlock/TouchID.mm index 502a508c4..77960beba 100644 --- a/src/quickunlock/TouchID.mm +++ b/src/quickunlock/TouchID.mm @@ -338,9 +338,7 @@ bool TouchID::isAvailable() const // note: we cannot cache the check results because the configuration // is dynamic in its nature. User can close the laptop lid or take off // the watch, thus making one (or both) of the authentication types unavailable. - const bool watchAvailable = isWatchAvailable(); - const bool touchIdAvailable = isTouchIdAvailable(); - return watchAvailable || touchIdAvailable; + return isWatchAvailable() || isTouchIdAvailable(); } /**