Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Suchanek <msuchanek@suse.de>2020-02-24 14:33:43 +0300
committerJonathan White <support@dmapps.us>2020-02-28 07:25:44 +0300
commitb9daed20558103e3c8e799f3e0575522bf823df6 (patch)
tree8950af13395e12d39f836a07910d67f69b026081
parenteb88b8cc0c1440f958a7ec625e5733b3b33f8c7d (diff)
Correct issues with hiding and minimizing the MainWindow
The GUI features depend on windowing system used, not just OS. There is an issue with the WM sometimes producing an event that keepassxc interprets as request to hide the main window just after it is shown. A workaround with immediately firing a timer was implemented. However, there is no guarantee on execution ordering of the timer callback and other application code. Remove the timer and override show() and hide() on main window to only hide if the window has not been shown recently. The user can set an option to hide window instead of minimizing when tray icon is enabled. This is not honored in most places where the main windows is minimized. Fix it. This also allows using the tray icon as a workaround for minimization not working under some circumstances in X11. Signed-off-by: Michal Suchanek <msuchanek@suse.de>
-rw-r--r--src/core/Clock.cpp5
-rw-r--r--src/core/Clock.h1
-rw-r--r--src/gui/DatabaseWidget.cpp9
-rw-r--r--src/gui/MainWindow.cpp60
-rw-r--r--src/gui/MainWindow.h7
-rw-r--r--src/gui/TotpDialog.cpp2
-rw-r--r--src/gui/TotpExportSettingsDialog.cpp2
7 files changed, 67 insertions, 19 deletions
diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp
index be9e91dcf..5704d4bff 100644
--- a/src/core/Clock.cpp
+++ b/src/core/Clock.cpp
@@ -34,6 +34,11 @@ uint Clock::currentSecondsSinceEpoch()
return instance().currentDateTimeImpl().toTime_t();
}
+qint64 Clock::currentMilliSecondsSinceEpoch()
+{
+ return instance().currentDateTimeImpl().toMSecsSinceEpoch();
+}
+
QDateTime Clock::serialized(const QDateTime& dateTime)
{
auto time = dateTime.time();
diff --git a/src/core/Clock.h b/src/core/Clock.h
index 8f81b0961..4d1ee2537 100644
--- a/src/core/Clock.h
+++ b/src/core/Clock.h
@@ -28,6 +28,7 @@ public:
static QDateTime currentDateTime();
static uint currentSecondsSinceEpoch();
+ static qint64 currentMilliSecondsSinceEpoch();
static QDateTime serialized(const QDateTime& dateTime);
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 3d6598fb2..0eb713dad 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -49,6 +49,7 @@
#include "gui/EntryPreviewWidget.h"
#include "gui/FileDialog.h"
#include "gui/KeePass1OpenWidget.h"
+#include "gui/MainWindow.h"
#include "gui/MessageBox.h"
#include "gui/OpVaultOpenWidget.h"
#include "gui/TotpDialog.h"
@@ -677,7 +678,7 @@ void DatabaseWidget::setClipboardTextAndMinimize(const QString& text)
clipboard()->setText(text);
if (config()->get("HideWindowOnCopy").toBool()) {
if (config()->get("MinimizeOnCopy").toBool()) {
- window()->showMinimized();
+ getMainWindow()->minimizeOrHide();
} else if (config()->get("DropToBackgroundOnCopy").toBool()) {
window()->lower();
}
@@ -782,7 +783,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
QProcess::startDetached(cmdString.mid(6));
if (config()->get("MinimizeOnOpenUrl").toBool()) {
- window()->showMinimized();
+ getMainWindow()->minimizeOrHide();
}
}
} else {
@@ -791,7 +792,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
QDesktopServices::openUrl(url);
if (config()->get("MinimizeOnOpenUrl").toBool()) {
- window()->showMinimized();
+ getMainWindow()->minimizeOrHide();
}
}
}
@@ -972,7 +973,7 @@ void DatabaseWidget::loadDatabase(bool accepted)
m_saveAttempts = 0;
emit databaseUnlocked();
if (config()->get("MinimizeAfterUnlock").toBool()) {
- window()->showMinimized();
+ getMainWindow()->minimizeOrHide();
}
} else {
if (m_databaseOpenWidget->database()) {
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index b225165a6..620a509bc 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -294,7 +294,7 @@ MainWindow::MainWindow()
connect(m_ui->menuGroups, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
// Control window state
- new QShortcut(Qt::CTRL + Qt::Key_M, this, SLOT(showMinimized()));
+ new QShortcut(Qt::CTRL + Qt::Key_M, this, SLOT(minimizeOrHide()));
new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M, this, SLOT(hideWindow()));
// Control database tabs
new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(selectNextDatabaseTab()));
@@ -1072,7 +1072,7 @@ void MainWindow::changeEvent(QEvent* event)
if (isTrayIconEnabled() && m_trayIcon && m_trayIcon->isVisible()
&& config()->get("GUI/MinimizeToTray").toBool()) {
event->ignore();
- QTimer::singleShot(0, this, SLOT(hide()));
+ hide();
}
if (config()->get("security/lockdatabaseminimize").toBool()) {
@@ -1245,7 +1245,7 @@ void MainWindow::applySettingsChanges()
void MainWindow::focusWindowChanged(QWindow* focusWindow)
{
if (focusWindow != windowHandle()) {
- m_lastFocusOutTime = Clock::currentSecondsSinceEpoch();
+ m_lastFocusOutTime = Clock::currentMilliSecondsSinceEpoch();
}
}
@@ -1269,9 +1269,9 @@ void MainWindow::processTrayIconTrigger()
|| m_trayIconTriggerReason == QSystemTrayIcon::MiddleClick) {
// Toggle window if is not in front.
#ifdef Q_OS_WIN
- // If on Windows, check if focus switched within the last second because
+ // If on Windows, check if focus switched within the 500 milliseconds since
// clicking the tray icon removes focus from main window.
- if (isHidden() || (Clock::currentSecondsSinceEpoch() - m_lastFocusOutTime) <= 1) {
+ if (isHidden() || (Clock::currentMilliSecondsSinceEpoch() - m_lastFocusOutTime) <= 500) {
#else
// If on Linux or macOS, check if the window has focus.
if (hasFocus() || isHidden() || windowHandle()->isActive()) {
@@ -1283,16 +1283,43 @@ void MainWindow::processTrayIconTrigger()
}
}
+void MainWindow::show()
+{
+#ifndef Q_OS_WIN
+ m_lastShowTime = Clock::currentMilliSecondsSinceEpoch();
+#endif
+ QMainWindow::show();
+}
+
+bool MainWindow::shouldHide()
+{
+#ifndef Q_OS_WIN
+ qint64 current_time = Clock::currentMilliSecondsSinceEpoch();
+
+ if (current_time - m_lastShowTime < 50) {
+ return false;
+ }
+#endif
+ return true;
+}
+
+void MainWindow::hide()
+{
+ if (shouldHide()) {
+ QMainWindow::hide();
+ }
+}
+
void MainWindow::hideWindow()
{
saveWindowInformation();
-#if !defined(Q_OS_LINUX) && !defined(Q_OS_MACOS)
- // 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.
- // TODO: Add an explanation for why this is also not done on Mac (or remove the check)
- setWindowState(windowState() | Qt::WindowMinimized);
-#endif
+ if (QGuiApplication::platformName() != "xcb") {
+ // In X11 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.
+ setWindowState(windowState() | Qt::WindowMinimized);
+ }
// Only hide if tray icon is active, otherwise window will be gone forever
if (isTrayIconEnabled()) {
hide();
@@ -1305,6 +1332,15 @@ void MainWindow::hideWindow()
}
}
+void MainWindow::minimizeOrHide()
+{
+ if (config()->get("GUI/MinimizeToTray").toBool()) {
+ hideWindow();
+ } else {
+ showMinimized();
+ }
+}
+
void MainWindow::toggleWindow()
{
if (isVisible() && !isMinimized()) {
diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h
index 0e74edf60..83a504f82 100644
--- a/src/gui/MainWindow.h
+++ b/src/gui/MainWindow.h
@@ -70,7 +70,10 @@ public slots:
void hideGlobalMessage();
void showYubiKeyPopup();
void hideYubiKeyPopup();
+ void hide();
+ void show();
void hideWindow();
+ void minimizeOrHide();
void toggleWindow();
void bringToFront();
void closeAllDatabases();
@@ -133,6 +136,7 @@ private:
static const QString BaseWindowTitle;
+ bool shouldHide();
void saveWindowInformation();
bool saveLastDatabases();
void updateTrayIcon();
@@ -163,7 +167,8 @@ private:
bool m_appExitCalled = false;
bool m_appExiting = false;
bool m_contextMenuFocusLock = false;
- uint m_lastFocusOutTime = 0;
+ qint64 m_lastFocusOutTime = 0;
+ qint64 m_lastShowTime = 0;
QTimer m_trayIconTriggerTimer;
QSystemTrayIcon::ActivationReason m_trayIconTriggerReason;
};
diff --git a/src/gui/TotpDialog.cpp b/src/gui/TotpDialog.cpp
index 639eb0ebd..7292cfcd3 100644
--- a/src/gui/TotpDialog.cpp
+++ b/src/gui/TotpDialog.cpp
@@ -67,7 +67,7 @@ void TotpDialog::copyToClipboard()
clipboard()->setText(m_entry->totp());
if (config()->get("HideWindowOnCopy").toBool()) {
if (config()->get("MinimizeOnCopy").toBool()) {
- getMainWindow()->showMinimized();
+ getMainWindow()->minimizeOrHide();
} else if (config()->get("DropToBackgroundOnCopy").toBool()) {
getMainWindow()->lower();
window()->lower();
diff --git a/src/gui/TotpExportSettingsDialog.cpp b/src/gui/TotpExportSettingsDialog.cpp
index 178cd6d96..ea14eabdb 100644
--- a/src/gui/TotpExportSettingsDialog.cpp
+++ b/src/gui/TotpExportSettingsDialog.cpp
@@ -105,7 +105,7 @@ void TotpExportSettingsDialog::copyToClipboard()
clipboard()->setText(m_totpUri);
if (config()->get("HideWindowOnCopy").toBool()) {
if (config()->get("MinimizeOnCopy").toBool()) {
- getMainWindow()->showMinimized();
+ getMainWindow()->minimizeOrHide();
} else if (config()->get("DropToBackgroundOnCopy").toBool()) {
getMainWindow()->lower();
window()->lower();