Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch Browser Integration to use native raising of windows in macOS #1904

Merged
merged 1 commit into from
Dec 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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