diff --git a/snapcraft.yaml b/snapcraft.yaml index d9c08ec9..f7bc1434 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -38,8 +38,8 @@ parts: - g++ - libgcrypt20-dev - libqt5x11extras5-dev + - libqt5svg5-dev - qtbase5-dev - - qtsvg5-dev - qttools5-dev - qttools5-dev-tools - zlib1g-dev @@ -59,6 +59,7 @@ parts: - libsodium23 - libxtst6 - libqt5x11extras5 + - libqt5svg5 - libusb-1.0-0 - qtwayland5 override-build: | diff --git a/src/core/Bootstrap.cpp b/src/core/Bootstrap.cpp index 2c25b250..70ca7eec 100644 --- a/src/core/Bootstrap.cpp +++ b/src/core/Bootstrap.cpp @@ -71,20 +71,10 @@ void bootstrapApplication() void restoreMainWindowState(MainWindow& mainWindow) { // start minimized if configured - bool minimizeOnStartup = config()->get("GUI/MinimizeOnStartup").toBool(); - bool minimizeToTray = config()->get("GUI/MinimizeToTray").toBool(); -#ifndef Q_OS_LINUX - if (minimizeOnStartup) { -#else - // On some Linux systems, the window should NOT be minimized and hidden (i.e. not shown), at - // the same time (which would happen if both minimize on startup and minimize to tray are set) - // since otherwise it causes problems on restore as seen on issue #1595. Hiding it is enough. - if (minimizeOnStartup && !minimizeToTray) { -#endif - mainWindow.setWindowState(Qt::WindowMinimized); - } - if (!(minimizeOnStartup && minimizeToTray)) { - mainWindow.show(); + if (config()->get("GUI/MinimizeOnStartup").toBool()) { + mainWindow.showMinimized(); + } else { + mainWindow.bringToFront(); } if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) { diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 0e80f2fc..c23e2bfa 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -159,7 +159,7 @@ void ApplicationSettingsWidget::loadSettings() m_generalUi->systrayShowCheckBox->setChecked(config()->get("GUI/ShowTrayIcon").toBool()); m_generalUi->systrayDarkIconCheckBox->setChecked(config()->get("GUI/DarkTrayIcon").toBool()); m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool()); - m_generalUi->systrayMinimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool()); + m_generalUi->minimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool()); m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get("GUI/MinimizeOnStartup").toBool()); m_generalUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool()); @@ -235,7 +235,7 @@ void ApplicationSettingsWidget::saveSettings() config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked()); config()->set("GUI/DarkTrayIcon", m_generalUi->systrayDarkIconCheckBox->isChecked()); config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked()); - config()->set("GUI/MinimizeOnClose", m_generalUi->systrayMinimizeOnCloseCheckBox->isChecked()); + config()->set("GUI/MinimizeOnClose", m_generalUi->minimizeOnCloseCheckBox->isChecked()); config()->set("GUI/MinimizeOnStartup", m_generalUi->systrayMinimizeOnStartup->isChecked()); config()->set("security/autotypeask", m_generalUi->autoTypeAskCheckBox->isChecked()); @@ -299,5 +299,4 @@ void ApplicationSettingsWidget::enableSystray(bool checked) { m_generalUi->systrayDarkIconCheckBox->setEnabled(checked); m_generalUi->systrayMinimizeToTrayCheckBox->setEnabled(checked); - m_generalUi->systrayMinimizeOnCloseCheckBox->setEnabled(checked); } diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index 157e5229..f8e304cc 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -186,6 +186,13 @@ + + + + Minimize instead of app exit + + + @@ -193,6 +200,42 @@ + + + + 0 + + + QLayout::SetMaximumSize + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + false + + + Dark system tray icon + + + + + @@ -250,78 +293,6 @@ - - - - 0 - - - QLayout::SetMaximumSize - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - false - - - Hide window to system tray instead of app exit - - - - - - - - - 0 - - - QLayout::SetMaximumSize - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - false - - - Dark system tray icon - - - - - diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index effae45c..e34a363b 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -116,10 +116,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) m_previewView->hide(); connect(this, SIGNAL(pressedEntry(Entry*)), m_previewView, SLOT(setEntry(Entry*))); connect(this, SIGNAL(pressedGroup(Group*)), m_previewView, SLOT(setGroup(Group*))); - connect(this, - SIGNAL(currentModeChanged(DatabaseWidget::Mode)), - m_previewView, - SLOT(setDatabaseMode(DatabaseWidget::Mode))); + connect(this, SIGNAL(currentModeChanged(DatabaseWidget::Mode)), + m_previewView, SLOT(setDatabaseMode(DatabaseWidget::Mode))); connect(m_previewView, SIGNAL(errorOccurred(QString)), this, SLOT(showErrorMessage(QString))); auto* vLayout = new QVBoxLayout(rightHandSideWidget); @@ -138,8 +136,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) rightHandSideWidget->setLayout(vLayout); - setTabOrder(m_entryView, m_groupView); - m_mainSplitter->addWidget(m_groupView); m_mainSplitter->addWidget(rightHandSideWidget); @@ -1342,29 +1338,16 @@ QStringList DatabaseWidget::customEntryAttributes() const } /* - * Restores the focus on the group and entry that was focused - * before the database was locked or reloaded. + * Restores the focus on the group and entry provided */ void DatabaseWidget::restoreGroupEntryFocus(const QUuid& groupUuid, const QUuid& entryUuid) { - Group* restoredGroup = nullptr; - const QList groups = m_db->rootGroup()->groupsRecursive(true); - for (Group* group : groups) { - if (group->uuid() == groupUuid) { - restoredGroup = group; - break; - } - } - - if (restoredGroup != nullptr) { - m_groupView->setCurrentGroup(restoredGroup); - - const QList entries = restoredGroup->entries(); - for (Entry* entry : entries) { - if (entry->uuid() == entryUuid) { - m_entryView->setCurrentEntry(entry); - break; - } + auto group = m_db->resolveGroup(groupUuid); + if (group) { + m_groupView->setCurrentGroup(group); + auto entry = group->findEntryByUuid(entryUuid); + if (entry) { + m_entryView->setCurrentEntry(entry); } } } diff --git a/src/gui/EntryPreviewWidget.ui b/src/gui/EntryPreviewWidget.ui index b7b8445a..65b779d4 100644 --- a/src/gui/EntryPreviewWidget.ui +++ b/src/gui/EntryPreviewWidget.ui @@ -2,6 +2,14 @@ EntryPreviewWidget + + + 0 + 0 + 280 + 267 + + 0 @@ -107,6 +115,9 @@ + + Qt::ClickFocus + Generate TOTP Token @@ -120,6 +131,9 @@ + + Qt::ClickFocus + Close @@ -135,6 +149,9 @@ + + Qt::ClickFocus + 0 @@ -732,6 +749,13 @@
gui/widgets/ElidedLabel.h
+ + entryTotpButton + entryAutotypeTree + entryTabWidget + groupCloseButton + groupTabWidget +
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index a729f588..bee57516 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -207,6 +207,11 @@ MainWindow::MainWindow() m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_U); new QShortcut(Qt::CTRL + Qt::Key_M, this, SLOT(showMinimized())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M, this, SLOT(hideWindow())); + new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(selectNextDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(selectNextDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(selectPreviousDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(selectPreviousDatabaseTab())); m_ui->actionDatabaseNew->setIcon(filePath()->icon("actions", "document-new")); m_ui->actionDatabaseOpen->setIcon(filePath()->icon("actions", "document-open")); @@ -697,6 +702,30 @@ void MainWindow::databaseStatusChanged(DatabaseWidget*) updateTrayIcon(); } +void MainWindow::selectNextDatabaseTab() +{ + if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { + int index = m_ui->tabWidget->currentIndex() + 1; + if (index >= m_ui->tabWidget->count()) { + m_ui->tabWidget->setCurrentIndex(0); + } else { + m_ui->tabWidget->setCurrentIndex(index); + } + } +} + +void MainWindow::selectPreviousDatabaseTab() +{ + if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { + int index = m_ui->tabWidget->currentIndex() - 1; + if (index < 0) { + m_ui->tabWidget->setCurrentIndex(m_ui->tabWidget->count() - 1); + } else { + m_ui->tabWidget->setCurrentIndex(index); + } + } +} + void MainWindow::databaseTabChanged(int tabIndex) { if (tabIndex != -1 && m_ui->stackedWidget->currentIndex() == WelcomeScreen) { @@ -716,15 +745,9 @@ void MainWindow::closeEvent(QCloseEvent* event) return; } - bool minimizeOnClose = isTrayIconEnabled() && config()->get("GUI/MinimizeOnClose").toBool(); - if (minimizeOnClose && !m_appExitCalled) { - event->accept(); + if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled) { + event->ignore(); hideWindow(); - - if (config()->get("security/lockdatabaseminimize").toBool()) { - m_ui->tabWidget->lockDatabases(); - } - return; } @@ -908,7 +931,12 @@ void MainWindow::hideWindow() // TODO: Add an explanation for why this is also not done on Mac (or remove the check) setWindowState(windowState() | Qt::WindowMinimized); #endif - QTimer::singleShot(0, this, SLOT(hide())); + // Only hide if tray icon is active, otherwise window will be gone forever + if (isTrayIconEnabled()) { + hide(); + } else { + showMinimized(); + } if (config()->get("security/lockdatabaseminimize").toBool()) { m_ui->tabWidget->lockDatabases(); diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 566034c8..9c2f41ce 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -69,6 +69,8 @@ public slots: void hideGlobalMessage(); void showYubiKeyPopup(); void hideYubiKeyPopup(); + void hideWindow(); + void toggleWindow(); void bringToFront(); void closeAllDatabases(); void lockAllDatabases(); @@ -103,13 +105,13 @@ private slots: void rememberOpenDatabases(const QString& filePath); void applySettingsChanges(); void trayIconTriggered(QSystemTrayIcon::ActivationReason reason); - void hideWindow(); - void toggleWindow(); void lockDatabasesAfterInactivity(); void forgetTouchIDAfterInactivity(); void hideTabMessage(); void handleScreenLock(); void showErrorMessage(const QString& message); + void selectNextDatabaseTab(); + void selectPreviousDatabaseTab(); private: static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);