Fix crashes when interacting with QGIS after a shortcut/action

is destroyed

Most notably happens when the following workflow occurs:
- A plugin adds some actions to QGIS
- The plugin gets reloaded
- Copy some text anywhere in QGIS

We can't safely call "sender()" for QObjects which are partially/
fully destroyed, so use a safer approach to clean up old shortcuts/
actions.

Fixes #52146
This commit is contained in:
Nyall Dawson 2023-03-15 10:19:07 +10:00
parent e0e63867f1
commit 01a995ab5f
2 changed files with 8 additions and 8 deletions

View File

@ -100,7 +100,7 @@ bool QgsShortcutsManager::registerAction( QAction *action, const QString &defaul
#endif
mActions.insert( action, defaultSequence );
connect( action, &QObject::destroyed, this, &QgsShortcutsManager::actionDestroyed );
connect( action, &QObject::destroyed, this, [action, this]() { actionDestroyed( action ); } );
QString actionText = action->text();
actionText.remove( '&' ); // remove the accelerator
@ -138,7 +138,7 @@ bool QgsShortcutsManager::registerShortcut( QShortcut *shortcut, const QString &
#endif
mShortcuts.insert( shortcut, defaultSequence );
connect( shortcut, &QObject::destroyed, this, &QgsShortcutsManager::shortcutDestroyed );
connect( shortcut, &QObject::destroyed, this, [shortcut, this]() { shortcutDestroyed( shortcut ); } );
const QString shortcutName = shortcut->objectName();
@ -321,14 +321,14 @@ QShortcut *QgsShortcutsManager::shortcutByName( const QString &name ) const
return nullptr;
}
void QgsShortcutsManager::actionDestroyed()
void QgsShortcutsManager::actionDestroyed( QAction *action )
{
mActions.remove( qobject_cast<QAction *>( sender() ) );
mActions.remove( action );
}
void QgsShortcutsManager::shortcutDestroyed()
void QgsShortcutsManager::shortcutDestroyed( QShortcut *shortcut )
{
mShortcuts.remove( qobject_cast<QShortcut *>( sender() ) );
mShortcuts.remove( shortcut );
}
void QgsShortcutsManager::updateActionToolTip( QAction *action, const QString &sequence )

View File

@ -244,8 +244,8 @@ class GUI_EXPORT QgsShortcutsManager : public QObject
private slots:
void actionDestroyed();
void shortcutDestroyed();
void actionDestroyed( QAction *action );
void shortcutDestroyed( QShortcut *shortcut );
private: