From 9b63e6a289fd4dcba4ca3a9e5acf4b4e79229adb Mon Sep 17 00:00:00 2001 From: varjolintu Date: Sun, 5 Jul 2020 14:32:23 +0300 Subject: [PATCH] macOS: Fix hiding window after using database unlock dialog * Properly hide window after Browser Integration and Auto-Type unlock, if needed * Fix #4904 --- src/autotype/AutoType.cpp | 40 +++++++++++++++++++++++++++++++--- src/autotype/AutoType.h | 9 ++++++++ src/browser/BrowserService.cpp | 18 ++++++++++----- src/browser/BrowserService.h | 1 + 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 117df903b6..01ef9d7621 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -35,6 +35,7 @@ #include "core/ListDeleter.h" #include "core/Resources.h" #include "core/Tools.h" +#include "gui/MainWindow.h" #include "gui/MessageBox.h" #ifdef Q_OS_MAC @@ -51,6 +52,7 @@ AutoType::AutoType(QObject* parent, bool test) , m_pluginLoader(new QPluginLoader(this)) , m_plugin(nullptr) , m_executor(nullptr) + , m_windowState(WindowState::Normal) , m_windowForGlobal(0) { // prevent crash when the plugin has unresolved symbols @@ -227,6 +229,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c "KeePassXC.")); return; } + macUtils()->raiseLastActiveWindow(); m_plugin->hideOwnWindow(); #else @@ -286,6 +289,18 @@ void AutoType::startGlobalAutoType() { m_windowForGlobal = m_plugin->activeWindow(); m_windowTitleForGlobal = m_plugin->activeWindowTitle(); +#ifdef Q_OS_MACOS + m_windowState = WindowState::Normal; + if (getMainWindow()) { + if (getMainWindow()->isMinimized()) { + m_windowState = WindowState::Minimized; + } + if (getMainWindow()->isHidden()) { + m_windowState = WindowState::Hidden; + } + } +#endif + emit globalAutoTypeTriggered(); } @@ -332,9 +347,12 @@ void AutoType::performGlobalAutoType(const QList>& dbLi .append(m_windowTitleForGlobal)); msgBox->setIcon(QMessageBox::Information); msgBox->setStandardButtons(QMessageBox::Ok); - msgBox->show(); - msgBox->raise(); - msgBox->activateWindow(); +#ifdef Q_OS_MACOS + m_plugin->raiseOwnWindow(); + Tools::wait(200); +#endif + msgBox->exec(); + restoreWindowState(); } m_inGlobalAutoTypeDialog.unlock(); @@ -361,8 +379,23 @@ void AutoType::performGlobalAutoType(const QList>& dbLi } } +void AutoType::restoreWindowState() +{ +#ifdef Q_OS_MAC + if (getMainWindow()) { + if (m_windowState == WindowState::Minimized) { + getMainWindow()->showMinimized(); + } else if (m_windowState == WindowState::Hidden) { + getMainWindow()->hideWindow(); + } + } +#endif +} + void AutoType::performAutoTypeFromGlobal(AutoTypeMatch match) { + restoreWindowState(); + m_plugin->raiseWindow(m_windowForGlobal); executeAutoTypeActions(match.entry, nullptr, match.sequence, m_windowForGlobal); @@ -380,6 +413,7 @@ void AutoType::autoTypeRejectedFromGlobal() m_windowForGlobal = 0; m_windowTitleForGlobal.clear(); + restoreWindowState(); emit autotypeRejected(); } diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index ad8607529e..7f9e3ab22a 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -73,6 +73,13 @@ private slots: void unloadPlugin(); private: + enum WindowState + { + Normal, + Minimized, + Hidden + }; + explicit AutoType(QObject* parent = nullptr, bool test = false); ~AutoType() override; void loadPlugin(const QString& pluginPath); @@ -86,6 +93,7 @@ private slots: bool windowMatchesTitle(const QString& windowTitle, const QString& resolvedTitle); bool windowMatchesUrl(const QString& windowTitle, const QString& resolvedUrl); bool windowMatches(const QString& windowTitle, const QString& windowPattern); + void restoreWindowState(); QMutex m_inAutoType; QMutex m_inGlobalAutoTypeDialog; @@ -98,6 +106,7 @@ private slots: static AutoType* m_instance; QString m_windowTitleForGlobal; + WindowState m_windowState; WId m_windowForGlobal; Q_DISABLE_COPY(AutoType) diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index f90a91f981..1f54e33cae 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -64,6 +64,7 @@ BrowserService::BrowserService() : QObject() , m_browserHost(new BrowserHost) , m_dialogActive(false) + , m_bringToFrontRequested(false) , m_prevWindowState(WindowState::Normal) , m_keepassBrowserUUID(Tools::hexToUuid("de887cc3036343b8974b5911b8816224")) { @@ -109,6 +110,8 @@ bool BrowserService::openDatabase(bool triggerUnlock) } if (triggerUnlock) { + m_bringToFrontRequested = true; + updateWindowState(); emit requestUnlock(); } @@ -751,7 +754,7 @@ QList BrowserService::confirmEntries(QList& pwEntriesToConfirm, } m_dialogActive = true; - bool wasAppActive = qApp->activeWindow() == getMainWindow()->window(); + updateWindowState(); BrowserAccessControlDialog accessControlDialog; connect(m_currentDatabaseWidget, SIGNAL(databaseLocked()), &accessControlDialog, SLOT(reject())); @@ -796,11 +799,7 @@ QList BrowserService::confirmEntries(QList& pwEntriesToConfirm, #ifdef Q_OS_MAC // Re-hide the application if it wasn't visible before // only affects macOS because dialogs force the main window to show - if (!wasAppActive) { - hideWindow(); - } -#else - Q_UNUSED(wasAppActive); + hideWindow(); #endif m_dialogActive = false; @@ -1247,6 +1246,13 @@ void BrowserService::databaseLocked(DatabaseWidget* dbWidget) void BrowserService::databaseUnlocked(DatabaseWidget* dbWidget) { if (dbWidget) { +#ifdef Q_OS_MAC + if (m_bringToFrontRequested) { + m_bringToFrontRequested = false; + hideWindow(); + } +#endif + QJsonObject msg; msg["action"] = QString("database-unlocked"); m_browserHost->sendClientMessage(msg); diff --git a/src/browser/BrowserService.h b/src/browser/BrowserService.h index 1a9af80820..6567a44d05 100644 --- a/src/browser/BrowserService.h +++ b/src/browser/BrowserService.h @@ -154,6 +154,7 @@ private slots: QHash> m_browserClients; bool m_dialogActive; + bool m_bringToFrontRequested; WindowState m_prevWindowState; QUuid m_keepassBrowserUUID;