Skip to content

Commit

Permalink
Switch browser integration to use native raising of windows
Browse files Browse the repository at this point in the history
  • Loading branch information
varjolintu authored and droidmonkey committed Dec 24, 2018
1 parent c630214 commit 5488f1b
Show file tree
Hide file tree
Showing 16 changed files with 229 additions and 34 deletions.
6 changes: 4 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ if(APPLE)
set(keepassx_SOURCES
${keepassx_SOURCES}
core/ScreenLockListenerMac.cpp
core/MacPasteboard.cpp)
core/MacPasteboard.cpp
gui/macutils/MacUtils.cpp
gui/macutils/AppKitImpl.mm)
endif()
if(UNIX AND NOT APPLE)
set(keepassx_SOURCES
Expand Down Expand Up @@ -272,7 +274,7 @@ target_link_libraries(keepassx_core
${ZXCVBN_LIBRARIES})

if(APPLE)
target_link_libraries(keepassx_core "-framework Foundation")
target_link_libraries(keepassx_core "-framework Foundation -framework AppKit")
if(Qt5MacExtras_FOUND)
target_link_libraries(keepassx_core Qt5::MacExtras)
endif()
Expand Down
12 changes: 6 additions & 6 deletions src/autotype/mac/AutoTypeMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include "AutoTypeMac.h"
#include "gui/macutils/MacUtils.h"

#include <ApplicationServices/ApplicationServices.h>

Expand All @@ -25,8 +26,7 @@
#define INVALID_KEYCODE 0xFFFF

AutoTypePlatformMac::AutoTypePlatformMac()
: m_appkit(new AppKit())
, m_hotkeyRef(nullptr)
: m_hotkeyRef(nullptr)
, m_hotkeyId({ 'kpx2', HOTKEY_ID })
{
EventTypeSpec eventSpec;
Expand Down Expand Up @@ -79,7 +79,7 @@ QStringList AutoTypePlatformMac::windowTitles()
//
WId AutoTypePlatformMac::activeWindow()
{
return m_appkit->activeProcessId();
return macUtils()->activeWindow();
}

//
Expand Down Expand Up @@ -159,23 +159,23 @@ AutoTypeExecutor* AutoTypePlatformMac::createExecutor()
//
bool AutoTypePlatformMac::raiseWindow(WId pid)
{
return m_appkit->activateProcess(pid);
return macUtils()->raiseWindow(pid);
}

//
// Activate last active window
//
bool AutoTypePlatformMac::raiseLastActiveWindow()
{
return m_appkit->activateProcess(m_appkit->lastActiveProcessId());
return macUtils()->raiseLastActiveWindow();
}

//
// Activate keepassx window
//
bool AutoTypePlatformMac::raiseOwnWindow()
{
return m_appkit->activateProcess(m_appkit->ownProcessId());
return macUtils()->raiseOwnWindow();
}

//
Expand Down
2 changes: 0 additions & 2 deletions src/autotype/mac/AutoTypeMac.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <QtPlugin>
#include <memory>

#include "AppKit.h"
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"

Expand Down Expand Up @@ -55,7 +54,6 @@ class AutoTypePlatformMac : public QObject, public AutoTypePlatformInterface
void globalShortcutTriggered();

private:
std::unique_ptr<AppKit> m_appkit;
EventHotKeyRef m_hotkeyRef;
EventHotKeyID m_hotkeyId;

Expand Down
4 changes: 3 additions & 1 deletion src/autotype/mac/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
set(autotype_mac_SOURCES AutoTypeMac.cpp)

set(autotype_mac_mm_SOURCES AppKitImpl.mm)
set(autotype_mac_mm_SOURCES
${CMAKE_SOURCE_DIR}/src/gui/macutils/AppKitImpl.mm
${CMAKE_SOURCE_DIR}/src/gui/macutils/MacUtils.cpp)

add_library(keepassx-autotype-cocoa MODULE ${autotype_mac_SOURCES} ${autotype_mac_mm_SOURCES})
set_target_properties(keepassx-autotype-cocoa PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit -framework Carbon")
Expand Down
50 changes: 47 additions & 3 deletions src/browser/BrowserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@
#include "core/Group.h"
#include "core/Metadata.h"
#include "core/PasswordGenerator.h"
#include "core/Tools.h"
#include "gui/MainWindow.h"
#include "gui/MessageBox.h"
#ifdef Q_OS_MACOS
#include "gui/macutils/MacUtils.h"
#endif

const char BrowserService::KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings";
const char BrowserService::KEEPASSXCBROWSER_OLD_NAME[] = "keepassxc-browser Settings";
Expand All @@ -50,6 +54,7 @@ BrowserService::BrowserService(DatabaseTabWidget* parent)
: m_dbTabWidget(parent)
, m_dialogActive(false)
, m_bringToFrontRequested(false)
, m_wasMinimized(false)
, m_keepassBrowserUUID(QUuid::fromRfc4122(QByteArray::fromHex("de887cc3036343b8974b5911b8816224")))
{
// Don't connect the signals when used from DatabaseSettingsWidgetBrowser (parent is nullptr)
Expand Down Expand Up @@ -90,8 +95,9 @@ bool BrowserService::openDatabase(bool triggerUnlock)
}

if (triggerUnlock) {
getMainWindow()->bringToFront();
m_bringToFrontRequested = true;
m_wasMinimized = getMainWindow()->isMinimized();
raiseWindow(true);
}

return false;
Expand Down Expand Up @@ -168,6 +174,7 @@ QString BrowserService::storeKey(const QString& key)
"give it a unique name to identify and accept it."));
keyDialog.setOkButtonText(tr("Save and allow access"));
keyDialog.setWindowFlags(keyDialog.windowFlags() | Qt::WindowStaysOnTopHint);
raiseWindow();
keyDialog.show();
keyDialog.activateWindow();
keyDialog.raise();
Expand All @@ -176,6 +183,7 @@ QString BrowserService::storeKey(const QString& key)
id = keyDialog.textValue();

if (ok != QDialog::Accepted || id.isEmpty()) {
hideWindow();
return {};
}

Expand All @@ -191,6 +199,7 @@ QString BrowserService::storeKey(const QString& key)
}
} while (contains && dialogResult == MessageBox::Cancel);

hideWindow();
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + id, key);
return id;
}
Expand Down Expand Up @@ -371,12 +380,13 @@ void BrowserService::updateEntry(const QString& id,
|| entry->password().compare(password, Qt::CaseSensitive) != 0) {
MessageBox::Button dialogResult = MessageBox::No;
if (!browserSettings()->alwaysAllowUpdate()) {
raiseWindow();
dialogResult = MessageBox::question(nullptr,
tr("KeePassXC: Update Entry"),
tr("Do you want to update the information in %1 - %2?")
.arg(QUrl(url).host(), username),
MessageBox::Save | MessageBox::Cancel,
MessageBox::Cancel);
MessageBox::Cancel, MessageBox::Raise);
}

if (browserSettings()->alwaysAllowUpdate() || dialogResult == MessageBox::Save) {
Expand All @@ -385,6 +395,8 @@ void BrowserService::updateEntry(const QString& id,
entry->setPassword(password);
entry->endUpdate();
}

hideWindow();
}
}

Expand Down Expand Up @@ -591,6 +603,11 @@ bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
accessControlDialog.setUrl(url);
accessControlDialog.setItems(pwEntriesToConfirm);

raiseWindow();
accessControlDialog.show();
accessControlDialog.activateWindow();
accessControlDialog.raise();

int res = accessControlDialog.exec();
if (accessControlDialog.remember()) {
for (Entry* entry : pwEntriesToConfirm) {
Expand All @@ -614,6 +631,7 @@ bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
}

m_dialogActive = false;
hideWindow();
if (res == QDialog::Accepted) {
return true;
}
Expand Down Expand Up @@ -909,6 +927,32 @@ bool BrowserService::checkLegacySettings()
return dialogResult == MessageBox::Yes;
}

void BrowserService::hideWindow() const
{
if (m_wasMinimized) {
getMainWindow()->showMinimized();
} else {
#ifdef Q_OS_MACOS
macUtils()->raiseLastActiveWindow();
#else
getMainWindow()->lower();
#endif
}
}

void BrowserService::raiseWindow(const bool force)
{
m_wasMinimized = getMainWindow()->isMinimized();
#ifdef Q_OS_MACOS
macUtils()->raiseOwnWindow();
Tools::wait(500);
#else
if (force) {
getMainWindow()->bringToFront();
}
#endif
}

void BrowserService::databaseLocked(DatabaseWidget* dbWidget)
{
if (dbWidget) {
Expand All @@ -920,7 +964,7 @@ void BrowserService::databaseUnlocked(DatabaseWidget* dbWidget)
{
if (dbWidget) {
if (m_bringToFrontRequested) {
getMainWindow()->lower();
hideWindow();
m_bringToFrontRequested = false;
}
emit databaseUnlocked();
Expand Down
3 changes: 3 additions & 0 deletions src/browser/BrowserService.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,14 @@ public slots:
bool moveSettingsToCustomData(Entry* entry, const QString& name) const;
int moveKeysToCustomData(Entry* entry, QSharedPointer<Database> db) const;
bool checkLegacySettings();
void hideWindow() const;
void raiseWindow(const bool force = false);

private:
DatabaseTabWidget* const m_dbTabWidget;
bool m_dialogActive;
bool m_bringToFrontRequested;
bool m_wasMinimized;
QUuid m_keepassBrowserUUID;
};

Expand Down
4 changes: 4 additions & 0 deletions src/gui/DatabaseOpenDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ DatabaseOpenDialog::DatabaseOpenDialog(QWidget* parent)
, m_view(new DatabaseOpenWidget(this))
{
setWindowTitle(tr("Unlock Database - KeePassXC"));
#ifdef Q_OS_MACOS
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
#else
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::ForeignWindow);
#endif
connect(m_view, SIGNAL(dialogFinished(bool)), this, SLOT(complete(bool)));
}

Expand Down
9 changes: 5 additions & 4 deletions src/gui/DatabaseOpenDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef KEEPASSX_AUTOTYPEUNLOCKDIALOG_H
#define KEEPASSX_AUTOTYPEUNLOCKDIALOG_H
#ifndef KEEPASSX_UNLOCKDATABASEDIALOG_H
#define KEEPASSX_UNLOCKDATABASEDIALOG_H

#include "core/Global.h"

Expand All @@ -37,7 +37,8 @@ class DatabaseOpenDialog : public QDialog
{
None,
AutoType,
Merge
Merge,
Browser
};

explicit DatabaseOpenDialog(QWidget* parent = nullptr);
Expand All @@ -61,4 +62,4 @@ public slots:
Intent m_intent = Intent::None;
};

#endif // KEEPASSX_AUTOTYPEUNLOCKDIALOG_H
#endif // KEEPASSX_UNLOCKDATABASEDIALOG_H
7 changes: 5 additions & 2 deletions src/gui/DatabaseTabWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#include "gui/DatabaseOpenDialog.h"
#include "gui/entry/EntryView.h"
#include "gui/group/GroupView.h"
#ifdef Q_OS_MACOS
#include "gui/macutils/MacUtils.h"
#endif
#include "gui/wizard/NewDatabaseWizard.h"

DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
Expand Down Expand Up @@ -544,8 +547,8 @@ void DatabaseTabWidget::unlockDatabaseInDialog(DatabaseWidget* dbWidget, Databas
m_databaseOpenDialog->setFilePath(filePath);

#ifdef Q_OS_MACOS
if (intent == DatabaseOpenDialog::Intent::AutoType) {
autoType()->raiseWindow();
if (intent == DatabaseOpenDialog::Intent::AutoType || intent == DatabaseOpenDialog::Intent::Browser) {
macUtils()->raiseOwnWindow();
Tools::wait(500);
}
#endif
Expand Down
28 changes: 19 additions & 9 deletions src/gui/MessageBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ MessageBox::Button MessageBox::messageBox(QWidget* parent,
const QString& title,
const QString& text,
MessageBox::Buttons buttons,
MessageBox::Button defaultButton)
MessageBox::Button defaultButton,
MessageBox::Action action)
{
if (m_nextAnswer == MessageBox::NoButton) {
QMessageBox msgBox(parent);
Expand All @@ -101,6 +102,11 @@ MessageBox::Button MessageBox::messageBox(QWidget* parent,
}
}

if (action == MessageBox::Raise) {
msgBox.setWindowFlags(Qt::WindowStaysOnTopHint);
msgBox.activateWindow();
msgBox.raise();
}
msgBox.exec();

Button returnButton = m_addedButtonLookup[msgBox.clickedButton()];
Expand All @@ -118,36 +124,40 @@ MessageBox::Button MessageBox::critical(QWidget* parent,
const QString& title,
const QString& text,
MessageBox::Buttons buttons,
MessageBox::Button defaultButton)
MessageBox::Button defaultButton,
MessageBox::Action action)
{
return messageBox(parent, QMessageBox::Critical, title, text, buttons, defaultButton);
return messageBox(parent, QMessageBox::Critical, title, text, buttons, defaultButton, action);
}

MessageBox::Button MessageBox::information(QWidget* parent,
const QString& title,
const QString& text,
MessageBox::Buttons buttons,
MessageBox::Button defaultButton)
MessageBox::Button defaultButton,
MessageBox::Action action)
{
return messageBox(parent, QMessageBox::Information, title, text, buttons, defaultButton);
return messageBox(parent, QMessageBox::Information, title, text, buttons, defaultButton, action);
}

MessageBox::Button MessageBox::question(QWidget* parent,
const QString& title,
const QString& text,
MessageBox::Buttons buttons,
MessageBox::Button defaultButton)
MessageBox::Button defaultButton,
MessageBox::Action action)
{
return messageBox(parent, QMessageBox::Question, title, text, buttons, defaultButton);
return messageBox(parent, QMessageBox::Question, title, text, buttons, defaultButton, action);
}

MessageBox::Button MessageBox::warning(QWidget* parent,
const QString& title,
const QString& text,
MessageBox::Buttons buttons,
MessageBox::Button defaultButton)
MessageBox::Button defaultButton,
MessageBox::Action action)
{
return messageBox(parent, QMessageBox::Warning, title, text, buttons, defaultButton);
return messageBox(parent, QMessageBox::Warning, title, text, buttons, defaultButton, action);
}

void MessageBox::setNextAnswer(MessageBox::Button button)
Expand Down
Loading

0 comments on commit 5488f1b

Please sign in to comment.