From ce9f59ec3e285b4e8f05932f5598d0a40f663047 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 22 Oct 2026 12:50:46 +0200 Subject: [PATCH 1/3] [qt6web] protect teardown process During application shutdown ROOT libraries can be partially unloaded and therefore deletion of timer object registered in the global lists may cause application crash. Same is true for qt6 Url scheme handler. Therefore when gSystem is nullptr - skip objects cleanup --- gui/qt6webdisplay/rootqt6.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gui/qt6webdisplay/rootqt6.cpp b/gui/qt6webdisplay/rootqt6.cpp index d3c28f76a83f0..f9a5e014ab452 100644 --- a/gui/qt6webdisplay/rootqt6.cpp +++ b/gui/qt6webdisplay/rootqt6.cpp @@ -83,12 +83,16 @@ class RQt6WebDisplayHandle : public RWebDisplayHandle { ~Qt6Creator() override { - /** Code executed during exit and sometime crashes. - * Disable it, while not clear if defaultProfile can be still used - seems to be not */ - // if (fHandler) - // QWebEngineProfile::defaultProfile()->removeUrlSchemeHandler(fHandler.get()); - - R__LOG_DEBUG(0, QtWebDisplayLog()) << "Deleting Qt6Creator"; + /** Code executed during program exit and sometime crashes. + * It can be that ROOT libraries already partially unloaded + * Therefore disable objects cleanup when gSystem already vansihed */ + + if (!gSystem) { + fHandler.release(); + fTimer.release(); + } else if (fHandler && QWebEngineProfile::defaultProfile()) { + QWebEngineProfile::defaultProfile()->removeUrlSchemeHandler(fHandler.get()); + } } std::unique_ptr Display(const RWebDisplayArgs &args) override From 0c277bcfceba21119a871011ffb6972ccde9163e Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 22 Oct 2026 12:55:06 +0200 Subject: [PATCH 2/3] [qt6web] increase default timer interval From 1 to 10 ms, change name to WebGui.Qt6Timer, was not documented before --- gui/qt6webdisplay/rootqt6.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gui/qt6webdisplay/rootqt6.cpp b/gui/qt6webdisplay/rootqt6.cpp index f9a5e014ab452..8c833b4002296 100644 --- a/gui/qt6webdisplay/rootqt6.cpp +++ b/gui/qt6webdisplay/rootqt6.cpp @@ -72,10 +72,10 @@ class RQt6WebDisplayHandle : public RWebDisplayHandle { bool fDeleteView = true; ///< is view must be deleted class Qt6Creator : public Creator { - QApplication *qapp{nullptr}; ///< created QApplication - int qargc{1}; ///< arg counter - char *qargv[2]; ///< arg values - std::unique_ptr fTimer; ///< timer to process ROOT events + QApplication *qapp = nullptr; ///< created QApplication + int qargc = 1; ///< arg counter + char *qargv[2] = {nullptr, nullptr}; ///< arg values + std::unique_ptr fTimer; ///< timer to process ROOT events std::unique_ptr fHandler; ///< specialized handler public: @@ -116,7 +116,7 @@ class RQt6WebDisplayHandle : public RWebDisplayHandle { // create timer to process Qt events from inside ROOT process events // very much improve performance, even when Qt even loop runs by QApplication normally if (!fTimer && !args.IsHeadless()) { - Int_t interval = gEnv->GetValue("WebGui.Qt5Timer", 1); + Int_t interval = gEnv->GetValue("WebGui.Qt6Timer", 10); if (interval > 0) { fTimer = std::make_unique(interval, kTRUE); fTimer->TurnOn(); From e171de096e89950490f5f71d4b93248cb1fdf885 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 22 Oct 2026 12:57:29 +0200 Subject: [PATCH 3/3] [webgui] mention Qt6Timer rootrc parameter Was missing in docu --- gui/webdisplay/src/RWebWindowsManager.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/webdisplay/src/RWebWindowsManager.cxx b/gui/webdisplay/src/RWebWindowsManager.cxx index db3457c9badb6..30319c4fdb933 100644 --- a/gui/webdisplay/src/RWebWindowsManager.cxx +++ b/gui/webdisplay/src/RWebWindowsManager.cxx @@ -786,7 +786,8 @@ std::string RWebWindowsManager::GetUrl(RWebWindow &win, bool remote, std::string /// WebGui.LaunchTmout: time required to start process in seconds (default 30 s) /// WebGui.ReconnectTmout: time to reconnect for already existing connection, if negative - no reconnecting possible (default 15 s) /// WebGui.BatchTimeout: time required to produce images in headless (batch) mode (default 30 s) -/// WebGui.CefTimer: periodic time to run CEF event loop (default 10 ms) +/// WebGui.Qt6Timer: periodic timer to run Qt6 event loop, used with 'qt6' web display (default 10 ms) +/// WebGui.CefTimer: periodic timer to run CEF event loop, used with 'cef' web display (default 10 ms) /// WebGui.CefUseViews: "yes" - enable / "no" - disable usage of CEF views frameworks (default is platform/version dependent) /// WebGui.OperationTmout: time required to perform WebWindow operation like execute command or update drawings /// WebGui.RecordData: if specified enables data recording for each web window; "yes" or "no" (default)