Skip to content

Commit

Permalink
macOS: Fix hiding window after using database unlock dialog
Browse files Browse the repository at this point in the history
* Properly hide window after Browser Integration and Auto-Type unlock, if needed
* Fix keepassxreboot#4904
  • Loading branch information
varjolintu authored and droidmonkey committed Jul 6, 2020
1 parent 8ebd1ab commit 9b63e6a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
40 changes: 37 additions & 3 deletions src/autotype/AutoType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -227,6 +229,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c
"KeePassXC."));
return;
}

macUtils()->raiseLastActiveWindow();
m_plugin->hideOwnWindow();
#else
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -332,9 +347,12 @@ void AutoType::performGlobalAutoType(const QList<QSharedPointer<Database>>& 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();
Expand All @@ -361,8 +379,23 @@ void AutoType::performGlobalAutoType(const QList<QSharedPointer<Database>>& 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);

Expand All @@ -380,6 +413,7 @@ void AutoType::autoTypeRejectedFromGlobal()
m_windowForGlobal = 0;
m_windowTitleForGlobal.clear();

restoreWindowState();
emit autotypeRejected();
}

Expand Down
9 changes: 9 additions & 0 deletions src/autotype/AutoType.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -98,6 +106,7 @@ private slots:
static AutoType* m_instance;

QString m_windowTitleForGlobal;
WindowState m_windowState;
WId m_windowForGlobal;

Q_DISABLE_COPY(AutoType)
Expand Down
18 changes: 12 additions & 6 deletions src/browser/BrowserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
{
Expand Down Expand Up @@ -109,6 +110,8 @@ bool BrowserService::openDatabase(bool triggerUnlock)
}

if (triggerUnlock) {
m_bringToFrontRequested = true;
updateWindowState();
emit requestUnlock();
}

Expand Down Expand Up @@ -751,7 +754,7 @@ QList<Entry*> BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
}

m_dialogActive = true;
bool wasAppActive = qApp->activeWindow() == getMainWindow()->window();
updateWindowState();
BrowserAccessControlDialog accessControlDialog;

connect(m_currentDatabaseWidget, SIGNAL(databaseLocked()), &accessControlDialog, SLOT(reject()));
Expand Down Expand Up @@ -796,11 +799,7 @@ QList<Entry*> BrowserService::confirmEntries(QList<Entry*>& 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;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/browser/BrowserService.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ private slots:
QHash<QString, QSharedPointer<BrowserAction>> m_browserClients;

bool m_dialogActive;
bool m_bringToFrontRequested;
WindowState m_prevWindowState;
QUuid m_keepassBrowserUUID;

Expand Down

0 comments on commit 9b63e6a

Please sign in to comment.