diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 9ab307063..50b68f5f1 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -56,19 +56,6 @@ namespace } return false; } - - bool canPerformQuickUnlock(const QString& filename) - { - if (isQuickUnlockAvailable()) { -#if defined(Q_CC_MSVC) - return getWindowsHello()->hasKey(filename); -#elif defined(Q_OS_MACOS) - return TouchID::getInstance().containsKey(filename); -#endif - } - Q_UNUSED(filename); - return false; - } } // namespace DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) @@ -191,50 +178,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 (!canPerformQuickUnlock(m_filename)) { + 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() @@ -257,12 +251,7 @@ void DatabaseOpenWidget::load(const QString& filename) } } - if (canPerformQuickUnlock(m_filename)) { - m_ui->centralStack->setCurrentIndex(1); - m_ui->quickUnlockButton->setFocus(); - } else { - m_ui->editPassword->setFocus(); - } + toggleQuickUnlockScreen(); #ifdef WITH_XC_YUBIKEY // Do initial auto-poll @@ -279,8 +268,11 @@ void DatabaseOpenWidget::clearForms() m_ui->keyFileLineEdit->setShowPassword(false); m_ui->keyFileLineEdit->setClearButtonEnabled(true); m_ui->hardwareKeyCombo->clear(); - m_ui->centralStack->setCurrentIndex(0); - m_db.reset(); + toggleQuickUnlockScreen(); + + QString error; + m_db.reset(new Database()); + m_db->open(m_filename, nullptr, &error); } QSharedPointer DatabaseOpenWidget::database() @@ -403,7 +395,7 @@ QSharedPointer DatabaseOpenWidget::buildDatabaseKey() { auto databaseKey = QSharedPointer::create(); - if (canPerformQuickUnlock(m_filename)) { + if (!m_db.isNull() && canPerformQuickUnlock()) { // try to retrieve the stored password using Windows Hello QByteArray keyData; #ifdef Q_CC_MSVC @@ -602,11 +594,34 @@ void DatabaseOpenWidget::setUserInteractionLock(bool state) m_unlockingDatabase = state; } -bool DatabaseOpenWidget::isOnQuickUnlockScreen() +bool DatabaseOpenWidget::canPerformQuickUnlock() const +{ + if (!m_db.isNull() && isQuickUnlockAvailable()) { +#if defined(Q_CC_MSVC) + return getWindowsHello()->hasKey(m_filename); +#elif defined(Q_OS_MACOS) + return TouchID::getInstance().containsKey(m_filename); +#endif + } + return false; +} + +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 0aa23a38f..0ba120210 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/touchid/TouchID.mm b/src/touchid/TouchID.mm index 688ddc451..045658f51 100644 --- a/src/touchid/TouchID.mm +++ b/src/touchid/TouchID.mm @@ -341,9 +341,7 @@ bool TouchID::isAvailable() // 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(); } /**