Fixed a potential segfault cause by recursive call of paintEvent

This may happen when painting triggers some action that itself
triggers progress reporter (which paints itself).

The solution consists of blocking process_events during painting.
This commit is contained in:
Matthias Koefferlein 2022-12-27 22:57:14 +01:00
parent e8cf51df1c
commit 8575791fd9
3 changed files with 18 additions and 5 deletions

View File

@ -1479,6 +1479,19 @@ GuiApplication::initialize ()
bool
GuiApplication::notify (QObject *receiver, QEvent *e)
{
if (dynamic_cast<QPaintEvent *> (e)) {
// NOTE: we don't want recursive paint events - the painters are not reentrant.
// Hence we disable process_events_impl (specifically for progress reporters).
lay::BusySection busy;
return do_notify (receiver, e);
} else {
return do_notify (receiver, e);
}
}
bool
GuiApplication::do_notify (QObject *receiver, QEvent *e)
{
bool in_notify = (m_in_notify > 0);

View File

@ -480,6 +480,8 @@ private:
MainWindow *mp_mw;
gtf::Recorder *mp_recorder;
int m_in_notify;
bool do_notify (QObject *receiver, QEvent *e);
};
/**

View File

@ -28,6 +28,7 @@
#include "layProgress.h"
#include "layMainWindow.h"
#include "layProgressWidget.h"
#include "layApplication.h"
#include "tlProgress.h"
#include "tlDeferredExecution.h"
@ -211,11 +212,8 @@ ProgressReporter::update_and_yield ()
void
ProgressReporter::process_events ()
{
// Don't execute deferred methods during progress handling (undesired side effects)
tl::NoDeferredMethods silent;
if (m_pw_visible && lay::MainWindow::instance () && QApplication::instance ()) {
QApplication::instance ()->processEvents (QEventLoop::AllEvents);
if (m_pw_visible && lay::MainWindow::instance () && lay::ApplicationBase::instance ()) {
lay::ApplicationBase::instance ()->process_events (QEventLoop::AllEvents, true /* no deferred methods */);
}
}