diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index f1ce19eed..3c06aceb5 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -1177,6 +1177,10 @@ bool BrowserService::checkLegacySettings(QSharedPointer db) bool legacySettingsFound = false; QList entries = db->rootGroup()->entriesRecursive(); for (const auto& e : entries) { + if (e->isRecycled()) { + continue; + } + if ((e->attributes()->contains(KEEPASSHTTP_NAME) || e->attributes()->contains(KEEPASSXCBROWSER_NAME)) || (e->title() == KEEPASSHTTP_NAME || e->title().contains(KEEPASSXCBROWSER_NAME, Qt::CaseInsensitive))) { legacySettingsFound = true; diff --git a/src/browser/BrowserShared.cpp b/src/browser/BrowserShared.cpp index 08b9fe537..69d0db49f 100644 --- a/src/browser/BrowserShared.cpp +++ b/src/browser/BrowserShared.cpp @@ -37,7 +37,7 @@ namespace BrowserShared : path + serverName; #elif defined(Q_OS_WIN) // Windows uses named pipes - return serverName; + return serverName + "_" + qgetenv("USERNAME"); #else // Q_OS_MACOS and others return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + serverName; #endif diff --git a/src/core/AsyncTask.h b/src/core/AsyncTask.h index f74d7c738..b113134d9 100644 --- a/src/core/AsyncTask.h +++ b/src/core/AsyncTask.h @@ -58,6 +58,28 @@ namespace AsyncTask return waitForFuture(QtConcurrent::run(task)); } + /** + * Run a given task then call the defined callback. Prevents event loop blocking and + * ensures the validity of the follow-on task through the context. If the context is + * deleted, the callback will not be processed preventing use after free errors. + * + * @param task std::function object to run + * @param context QObject responsible for calling this function + * @param callback std::function object to run after the task completess + */ + template + void runThenCallback(FunctionObject task, QObject* context, FunctionObject2 callback) + { + typedef QFutureWatcher::type> FutureWatcher; + auto future = QtConcurrent::run(task); + auto watcher = new FutureWatcher(context); + QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() { + watcher->deleteLater(); + callback(future.result()); + }); + watcher->setFuture(future); + } + }; // namespace AsyncTask #endif // KEEPASSXC_ASYNCTASK_HPP diff --git a/src/core/FileWatcher.cpp b/src/core/FileWatcher.cpp index 2d37734aa..430e60274 100644 --- a/src/core/FileWatcher.cpp +++ b/src/core/FileWatcher.cpp @@ -118,13 +118,16 @@ void FileWatcher::checkFileChanged() // Prevent reentrance m_ignoreFileChange = true; - auto checksum = AsyncTask::runAndWaitForFuture([this]() -> QByteArray { return calculateChecksum(); }); - if (checksum != m_fileChecksum) { - m_fileChecksum = checksum; - m_fileChangeDelayTimer.start(0); - } + AsyncTask::runThenCallback([=] { return calculateChecksum(); }, + this, + [=](QByteArray checksum) { + if (checksum != m_fileChecksum) { + m_fileChecksum = checksum; + m_fileChangeDelayTimer.start(0); + } - m_ignoreFileChange = false; + m_ignoreFileChange = false; + }); } QByteArray FileWatcher::calculateChecksum() diff --git a/src/gui/FileDialog.cpp b/src/gui/FileDialog.cpp index df713c44b..406fbe50c 100644 --- a/src/gui/FileDialog.cpp +++ b/src/gui/FileDialog.cpp @@ -21,20 +21,6 @@ #include -namespace -{ - QString modFilter(const QString& filter) - { -#ifdef Q_OS_MACOS - // Fix macOS bug that causes the file dialog to freeze when a dot is included in the filters - // See https://github.com/keepassxreboot/keepassxc/issues/3895#issuecomment-586724167 - auto mod = filter; - return mod.replace("*.", "*"); -#endif - return filter; - } -} // namespace - FileDialog* FileDialog::m_instance(nullptr); QString FileDialog::getOpenFileName(QWidget* parent, @@ -51,7 +37,7 @@ QString FileDialog::getOpenFileName(QWidget* parent, } else { const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators( - QFileDialog::getOpenFileName(parent, caption, workingDir, modFilter(filter), selectedFilter, options)); + QFileDialog::getOpenFileName(parent, caption, workingDir, filter, selectedFilter, options)); #ifdef Q_OS_MACOS // on Mac OS X the focus is lost after closing the native dialog @@ -77,8 +63,7 @@ QStringList FileDialog::getOpenFileNames(QWidget* parent, return results; } else { const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; - auto results = - QFileDialog::getOpenFileNames(parent, caption, workingDir, modFilter(filter), selectedFilter, options); + auto results = QFileDialog::getOpenFileNames(parent, caption, workingDir, filter, selectedFilter, options); for (auto& path : results) { path = QDir::toNativeSeparators(path); @@ -111,7 +96,7 @@ QString FileDialog::getSaveFileName(QWidget* parent, } else { const auto& workingDir = dir.isEmpty() ? config()->get(Config::LastDir).toString() : dir; const auto result = QDir::toNativeSeparators( - QFileDialog::getSaveFileName(parent, caption, workingDir, modFilter(filter), selectedFilter, options)); + QFileDialog::getSaveFileName(parent, caption, workingDir, filter, selectedFilter, options)); #ifdef Q_OS_MACOS // on Mac OS X the focus is lost after closing the native dialog diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index a8d502cb3..bf6c1f1ae 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -259,8 +259,15 @@ MainWindow::MainWindow() m_ui->actionEntryAutoType->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U); m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::Key_U); - m_ui->actionEntryAddToAgent->setShortcut(Qt::CTRL + Qt::Key_H); - m_ui->actionEntryRemoveFromAgent->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_H); + + // Prevent conflicts with global Mac shortcuts (force Control on all platforms) +#ifdef Q_OS_MAC + auto modifier = Qt::META; +#else + auto modifier = Qt::CTRL; +#endif + m_ui->actionEntryAddToAgent->setShortcut(modifier + Qt::Key_H); + m_ui->actionEntryRemoveFromAgent->setShortcut(modifier + Qt::SHIFT + Qt::Key_H); #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) // Qt 5.10 introduced a new "feature" to hide shortcuts in context menus