mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-03-13 09:36:42 -04:00
Fix copy-to-clipboard shortcut on macOS
It turns out that the previous implementation, based on installing an event filter in every QAction instance, does not work on macOS, likely due to a Qt bug. Attempt to work around this by using a different implementation of the same idea, by reacting to ShortcutOverride events in the MainWindow object. Fixes #10929.
This commit is contained in:
parent
8bdbccf13f
commit
78cff4b6d9
@ -77,28 +77,6 @@
|
||||
#include "mainwindowadaptor.h"
|
||||
#endif
|
||||
|
||||
// This filter gets installed on all the QAction objects within the MainWindow.
|
||||
bool ActionEventFilter::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
auto databaseWidget = getMainWindow()->m_ui->tabWidget->currentDatabaseWidget();
|
||||
if (databaseWidget && event->type() == QEvent::Shortcut) {
|
||||
// We check if we got a Shortcut event that uses the same key sequence as the
|
||||
// OS default copy-to-clipboard shortcut.
|
||||
static const auto stdCopyShortcuts = QKeySequence::keyBindings(QKeySequence::Copy);
|
||||
if (stdCopyShortcuts.contains(static_cast<QShortcutEvent*>(event)->key())) {
|
||||
// If so, we ask the database widget to check if any of its sub-widgets has text
|
||||
// selected, and to copy it to the clipboard if that is the case. We do this
|
||||
// because that is what the user likely expects to happen, yet Qt does not
|
||||
// behave like that on all platforms.
|
||||
if (databaseWidget->copyFocusedTextSelection()) {
|
||||
// In that case, we return true to stop further processing of this event.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
const QString MainWindow::BaseWindowTitle = "KeePassXC";
|
||||
|
||||
MainWindow* g_MainWindow = nullptr;
|
||||
@ -472,9 +450,6 @@ MainWindow::MainWindow()
|
||||
m_ui->actionEntryRemovePasskey->setIcon(icons()->icon("document-close"));
|
||||
#endif
|
||||
|
||||
// Handle copy to clipboard shortcut interference
|
||||
m_ui->actionEntryCopyPassword->installEventFilter(&m_actionEventFilter);
|
||||
|
||||
m_actionMultiplexer.connect(
|
||||
SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(setMenuActionState(DatabaseWidget::Mode)));
|
||||
m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(setMenuActionState()));
|
||||
@ -1409,6 +1384,33 @@ void MainWindow::databaseTabChanged(int tabIndex)
|
||||
updateEntryCountLabel();
|
||||
}
|
||||
|
||||
bool MainWindow::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ShortcutOverride) {
|
||||
const auto keyevent = static_cast<QKeyEvent*>(event);
|
||||
// Did we get a ShortcutOverride event with the same key sequence as the OS default
|
||||
// copy-to-clipboard shortcut?
|
||||
if (keyevent->matches(QKeySequence::Copy)) {
|
||||
// If so, we ask the database widget to check if any of its sub-widgets has
|
||||
// text selected, and to copy it to the clipboard if that is the case.
|
||||
// We do this because that is what the user likely expects to happen, yet Qt does not
|
||||
// behave like that (at least on some platforms).
|
||||
auto dbWidget = m_ui->tabWidget->currentDatabaseWidget();
|
||||
if (dbWidget && dbWidget->copyFocusedTextSelection()) {
|
||||
// Note: instead of actively copying the selected text to the clipboard
|
||||
// above, simply accepting the event would have a similar effect (Qt
|
||||
// would deliver it as a key press to the current widget, which would
|
||||
// trigger the built-in copy-to-clipboard behaviour). However, that
|
||||
// would not come with our special (configurable) behaviour of
|
||||
// clearing the clipboard after a certain time period.
|
||||
keyevent->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
void MainWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
@ -1494,7 +1496,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
QWidget::keyPressEvent(event);
|
||||
QMainWindow::keyPressEvent(event);
|
||||
}
|
||||
|
||||
bool MainWindow::focusNextPrevChild(bool next)
|
||||
|
@ -39,14 +39,6 @@ class InactivityTimer;
|
||||
class SearchWidget;
|
||||
class MainWindowEventFilter;
|
||||
|
||||
class ActionEventFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
};
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -105,6 +97,7 @@ public slots:
|
||||
void restartApp(const QString& message);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* event) override;
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
@ -177,7 +170,6 @@ private:
|
||||
|
||||
const QScopedPointer<Ui::MainWindow> m_ui;
|
||||
SignalMultiplexer m_actionMultiplexer;
|
||||
ActionEventFilter m_actionEventFilter;
|
||||
QPointer<QAction> m_clearHistoryAction;
|
||||
QPointer<QAction> m_searchWidgetAction;
|
||||
QPointer<QMenu> m_entryContextMenu;
|
||||
@ -209,7 +201,6 @@ private:
|
||||
QTimer m_trayIconTriggerTimer;
|
||||
QSystemTrayIcon::ActivationReason m_trayIconTriggerReason;
|
||||
|
||||
friend class ActionEventFilter;
|
||||
friend class MainWindowEventFilter;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user