From f9bfbe713d1779d7f53db906e3b6a3b016996f32 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 May 2020 03:15:42 +0200 Subject: [PATCH] Add a QgsFocusKeeper class to avoid crashes related to focus loss Will be use to solve crash of #30210 Credits to @nyalldawson for pointing out the fix of #31905 as a reference. --- src/gui/CMakeLists.txt | 1 + src/gui/qgsfocuskeeper.cpp | 40 +++++++++++++++++++++++++++++++ src/gui/qgsfocuskeeper.h | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 src/gui/qgsfocuskeeper.cpp create mode 100644 src/gui/qgsfocuskeeper.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index b8bc7282ee27..952151ef91d3 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -416,6 +416,7 @@ SET(QGIS_GUI_SRCS qgsfilterlineedit.cpp qgsfindfilesbypatternwidget.cpp qgsfloatingwidget.cpp + qgsfocuskeeper.cpp qgsfocuswatcher.cpp qgsfontbutton.cpp qgsformannotation.cpp diff --git a/src/gui/qgsfocuskeeper.cpp b/src/gui/qgsfocuskeeper.cpp new file mode 100644 index 000000000000..386f8808f9fa --- /dev/null +++ b/src/gui/qgsfocuskeeper.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + qgsfocuskeeper.cpp + ----------------- + Date : May 2020 + Copyright : (C) 2020 Even Rouault + Email : even dot rouault at spatialys dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsfocuskeeper.h" + +#include +#include +#include + +QgsFocusKeeper::QgsFocusKeeper(): mWidgetToKeepFocused( QApplication::focusWidget() ) +{ + mWidgetToKeepFocused->installEventFilter( this ); +} + +QgsFocusKeeper::~QgsFocusKeeper() +{ + mWidgetToKeepFocused->removeEventFilter( this ); +} + +bool QgsFocusKeeper::eventFilter( QObject *obj, QEvent *event ) +{ + if ( obj == mWidgetToKeepFocused && event && + ( event->type() == QEvent::FocusOut || event->type() == QEvent::FocusAboutToChange ) ) + { + return true; + } + return QObject::eventFilter( obj, event ); +} diff --git a/src/gui/qgsfocuskeeper.h b/src/gui/qgsfocuskeeper.h new file mode 100644 index 000000000000..1d86054aa88c --- /dev/null +++ b/src/gui/qgsfocuskeeper.h @@ -0,0 +1,48 @@ +/*************************************************************************** + qgsfocuskeeper.h + --------------- + Date : May 2020 + Copyright : (C) 2020 Even Rouault + Email : even dot rouault at spatialys dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSFOCUSKEEPER_H +#define QGSFOCUSKEEPER_H + +#include "qgis_gui.h" + +#define SIP_NO_FILE + +#include + +class QWidget; + +/** + * \ingroup gui + * \class QgsFocusKeeper + * Trick to keep a widget focused and avoid QT crashes + * \note not available in Python bindings + * \since QGIS 3.14 + */ +class GUI_EXPORT QgsFocusKeeper : public QObject +{ + Q_OBJECT + + QWidget *mWidgetToKeepFocused = nullptr; + + public: + QgsFocusKeeper(); + ~QgsFocusKeeper() override; + + protected: + bool eventFilter( QObject *obj, QEvent *event ) override; +}; + +#endif // QGSFOCUSKEEPER_H