Fix TouchID not being shown after lid close

Fixes #8945
Fixes #10315
This commit is contained in:
Jonathan White 2024-03-09 08:34:33 -05:00
parent f20b531430
commit 7d0dc67180
3 changed files with 73 additions and 59 deletions

View File

@ -56,19 +56,6 @@ namespace
} }
return false; 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 } // namespace
DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) 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); bool ret = DialogyWidget::event(event);
if (isOnQuickUnlockScreen()) {
m_ui->quickUnlockButton->setFocus(); switch (event->type()) {
if (!canPerformQuickUnlock(m_filename)) { case QEvent::Show:
case QEvent::WindowActivate: {
if (isOnQuickUnlockScreen() && (m_db.isNull() || !canPerformQuickUnlock())) {
resetQuickUnlock(); resetQuickUnlock();
} }
} else { toggleQuickUnlockScreen();
m_ui->editPassword->setFocus(); m_hideTimer.stop();
}
m_hideTimer.stop();
#ifdef WITH_XC_YUBIKEY #ifdef WITH_XC_YUBIKEY
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
m_deviceListener->registerHotplugCallback(true, m_deviceListener->registerHotplugCallback(true,
true, true,
YubiKeyInterfaceUSB::YUBICO_USB_VID, YubiKeyInterfaceUSB::YUBICO_USB_VID,
DeviceListener::MATCH_ANY, DeviceListener::MATCH_ANY,
&DeviceListenerWin::DEV_CLS_KEYBOARD); &DeviceListenerWin::DEV_CLS_KEYBOARD);
m_deviceListener->registerHotplugCallback(true, m_deviceListener->registerHotplugCallback(true,
true, true,
YubiKeyInterfaceUSB::ONLYKEY_USB_VID, YubiKeyInterfaceUSB::ONLYKEY_USB_VID,
DeviceListener::MATCH_ANY, DeviceListener::MATCH_ANY,
&DeviceListenerWin::DEV_CLS_KEYBOARD); &DeviceListenerWin::DEV_CLS_KEYBOARD);
#else #else
m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::YUBICO_USB_VID); m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::YUBICO_USB_VID);
m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::ONLYKEY_USB_VID); m_deviceListener->registerHotplugCallback(true, true, YubiKeyInterfaceUSB::ONLYKEY_USB_VID);
#endif #endif
#endif #endif
}
void DatabaseOpenWidget::hideEvent(QHideEvent* event) return true;
{
DialogyWidget::hideEvent(event);
// Schedule form clearing if we are hidden
if (!isVisible()) {
m_hideTimer.start();
} }
case QEvent::Hide: {
// Schedule form clearing if we are hidden
if (!isVisible()) {
m_hideTimer.start();
}
#ifdef WITH_XC_YUBIKEY #ifdef WITH_XC_YUBIKEY
m_deviceListener->deregisterAllHotplugCallbacks(); m_deviceListener->deregisterAllHotplugCallbacks();
#endif #endif
return true;
}
default:;
}
return ret;
} }
bool DatabaseOpenWidget::unlockingDatabase() bool DatabaseOpenWidget::unlockingDatabase()
@ -257,12 +251,7 @@ void DatabaseOpenWidget::load(const QString& filename)
} }
} }
if (canPerformQuickUnlock(m_filename)) { toggleQuickUnlockScreen();
m_ui->centralStack->setCurrentIndex(1);
m_ui->quickUnlockButton->setFocus();
} else {
m_ui->editPassword->setFocus();
}
#ifdef WITH_XC_YUBIKEY #ifdef WITH_XC_YUBIKEY
// Do initial auto-poll // Do initial auto-poll
@ -279,8 +268,11 @@ void DatabaseOpenWidget::clearForms()
m_ui->keyFileLineEdit->setShowPassword(false); m_ui->keyFileLineEdit->setShowPassword(false);
m_ui->keyFileLineEdit->setClearButtonEnabled(true); m_ui->keyFileLineEdit->setClearButtonEnabled(true);
m_ui->hardwareKeyCombo->clear(); m_ui->hardwareKeyCombo->clear();
m_ui->centralStack->setCurrentIndex(0); toggleQuickUnlockScreen();
m_db.reset();
QString error;
m_db.reset(new Database());
m_db->open(m_filename, nullptr, &error);
} }
QSharedPointer<Database> DatabaseOpenWidget::database() QSharedPointer<Database> DatabaseOpenWidget::database()
@ -403,7 +395,7 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey()
{ {
auto databaseKey = QSharedPointer<CompositeKey>::create(); auto databaseKey = QSharedPointer<CompositeKey>::create();
if (canPerformQuickUnlock(m_filename)) { if (!m_db.isNull() && canPerformQuickUnlock()) {
// try to retrieve the stored password using Windows Hello // try to retrieve the stored password using Windows Hello
QByteArray keyData; QByteArray keyData;
#ifdef Q_CC_MSVC #ifdef Q_CC_MSVC
@ -602,11 +594,34 @@ void DatabaseOpenWidget::setUserInteractionLock(bool state)
m_unlockingDatabase = 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; 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() void DatabaseOpenWidget::triggerQuickUnlock()
{ {
if (isOnQuickUnlockScreen()) { if (isOnQuickUnlockScreen()) {

View File

@ -53,7 +53,9 @@ public:
bool unlockingDatabase(); bool unlockingDatabase();
// Quick Unlock helper functions // Quick Unlock helper functions
bool isOnQuickUnlockScreen(); bool canPerformQuickUnlock() const;
bool isOnQuickUnlockScreen() const;
void toggleQuickUnlockScreen();
void triggerQuickUnlock(); void triggerQuickUnlock();
void resetQuickUnlock(); void resetQuickUnlock();
@ -61,8 +63,7 @@ signals:
void dialogFinished(bool accepted); void dialogFinished(bool accepted);
protected: protected:
void showEvent(QShowEvent* event) override; bool event(QEvent* event) override;
void hideEvent(QHideEvent* event) override;
QSharedPointer<CompositeKey> buildDatabaseKey(); QSharedPointer<CompositeKey> buildDatabaseKey();
void setUserInteractionLock(bool state); void setUserInteractionLock(bool state);

View File

@ -341,9 +341,7 @@ bool TouchID::isAvailable()
// note: we cannot cache the check results because the configuration // note: we cannot cache the check results because the configuration
// is dynamic in its nature. User can close the laptop lid or take off // 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. // the watch, thus making one (or both) of the authentication types unavailable.
const bool watchAvailable = isWatchAvailable(); return isWatchAvailable() || isTouchIdAvailable();
const bool touchIdAvailable = isTouchIdAvailable();
return watchAvailable || touchIdAvailable;
} }
/** /**