diff options
| author | saturneric <[email protected]> | 2026-09-24 19:47:50 +0200 |
|---|---|---|
| committer | saturneric <[email protected]> | 2026-09-24 19:47:50 +0200 |
| commit | efb3e1b27c4b9118e35eca29793836f59559199e (patch) | |
| tree | 1e6a6105caa09099d53079dd08fd71f2ce8d4414 /src/m_gpg_info | |
| parent | refactor(mail): centralize worker thread shutdown (diff) | |
| download | modules-efb3e1b27c4b9118e35eca29793836f59559199e.tar.gz modules-efb3e1b27c4b9118e35eca29793836f59559199e.zip | |
refactor(gnupg): trigger info gathering from tab
- remove the gathering event handler and module event declaration
- start collection from the tab watcher when the UI is shown
- scope gathering state to the GnuPG module
- own command contexts with smart pointers to prevent leaks
- remove callback-based context deallocation
- include required memory and vector headers
Diffstat (limited to 'src/m_gpg_info')
| -rw-r--r-- | src/m_gpg_info/GnuPGInfoGatheringModule.cpp | 55 | ||||
| -rw-r--r-- | src/m_gpg_info/GnupgTab.cpp | 4 | ||||
| -rw-r--r-- | src/m_gpg_info/module.json | 4 |
3 files changed, 28 insertions, 35 deletions
diff --git a/src/m_gpg_info/GnuPGInfoGatheringModule.cpp b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp index 2405910..4ea4bc9 100644 --- a/src/m_gpg_info/GnuPGInfoGatheringModule.cpp +++ b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp @@ -41,7 +41,9 @@ #include <QVBoxLayout> // c++ +#include <memory> #include <optional> +#include <vector> #include "GFModule.h" #include "GFModuleIdentity.h" @@ -77,7 +79,7 @@ namespace { class GnupgInfoWidget : public QWidget, public gf::ui::DialogWidget { public: GnupgInfoWidget() { - auto* layout = new QVBoxLayout(this); + auto *layout = new QVBoxLayout(this); layout->addWidget(new GnupgTab(this)); } }; @@ -85,15 +87,18 @@ class GnupgInfoWidget : public QWidget, public gf::ui::DialogWidget { /// Help > GnuPG. Its title and whereabouts are the command's and the /// script's; it only opens the module's own dialog. struct ShowGnupgInfo { - static constexpr gf::cmd::Meta kMeta{ - GF_MODULE_ID ".show_gnupg_info", GC_TR("GnuPG"), - GC_TR("Information about GnuPG"), "", 0, gf::cmd::kNeedsGuiThread}; + static constexpr gf::cmd::Meta kMeta{GF_MODULE_ID ".show_gnupg_info", + GC_TR("GnuPG"), + GC_TR("Information about GnuPG"), + "", + 0, + gf::cmd::kNeedsGuiThread}; using Args = gf::cmd::Unit; using Result = gf::cmd::Unit; }; -auto DoShowGnupgInfo(const gf::cmd::CommandContext& /*ctx*/, - const gf::cmd::Unit& /*args*/) +auto DoShowGnupgInfo(const gf::cmd::CommandContext & /*ctx*/, + const gf::cmd::Unit & /*args*/) -> gf::cmd::Outcome<gf::cmd::Unit> { Commands().Invoke<gf::cmd::host::ViewOpen>( {gf::cmd::ViewRef{QStringLiteral(GF_MODULE_ID ".info")}}); @@ -106,27 +111,19 @@ auto OnActivate() -> GFResult { LOG_INFO("gnupg info gathering module registering"); const bool ok = gf::ui::RegisterNativeWidget<GnupgInfoWidget>( "info", {GC_TR("GnuPG"), "", "", "", ":/icons/key.png", 500, 600}, - [](const QCborMap& /*args*/) { return new GnupgInfoWidget(); }); + [](const QCborMap & /*args*/) { return new GnupgInfoWidget(); }); return ok ? GFResult::Ok() : GFResult::Fail("the GnuPG information widget was not registered"); } -auto OnRequestGatheringAllGnuPGInfo(const GFEvent & /*event*/) - -> GFEventResult { - StartGatheringAllGnuPGInfo(); - return GFEventResult::Ok(); -} - auto OnUnload() -> void { LOG_INFO("gnupg info gathering module unregistering"); } -// The module's whole framework surface: which events it handles, what it -// provides, what runs at each lifecycle point, and one forwarder to the -// runtime that implements all of it. Everything above is business logic. -constexpr std::array<GFEventBinding, 1> kEvents = {{ - {"REQUEST_GATHERING_ALL_GNUPG_INFO", &OnRequestGatheringAllGnuPGInfo}, -}}; +// The module's whole framework surface: what it provides, what runs at each +// lifecycle point, and one forwarder to the runtime that implements all of +// it. Everything above is business logic. It handles no events: the tab +// gathers what it shows itself, when it is shown. const std::array<gf::cmd::Binding, 1> kCommands = { gf::cmd::Bind<ShowGnupgInfo, &DoShowGnupgInfo>(), @@ -140,8 +137,8 @@ const GFModuleHooks kHooks = { &OnActivate, nullptr, // the Host withdraws the command, widget and script itself &OnUnload, - kEvents.data(), - kEvents.size(), + nullptr, + 0, kCommands.data(), kCommands.size(), }; @@ -194,6 +191,7 @@ auto StartGatheringAllGnuPGInfo() -> int { // process.execute borrows everything it is given; RunCommands keeps the // strings alive for the call, so nothing here is allocated for the host. QList<gf::sdk::Command> commands; + std::vector<std::unique_ptr<Context>> contexts; commands.push_back({gpgconf_path, {"--homedir", default_home_path, "--list-dirs"}, GetGpgDirectoryInfos, @@ -225,16 +223,16 @@ auto StartGatheringAllGnuPGInfo() -> int { continue; } - auto *context = - new (GFMemAlloc(GFModuleSdkContext(), GF_ARENA_NORMAL, sizeof(Context))) - Context{gpgme_version, gpgconf_path, component_info}; - - // The context is freed by GetGpgOptionInfos once the command finishes. + // Owned here, not by the callback: RunCommands() returns only once every + // command has finished, and a callback that bails out early -- or never + // runs at all -- used to leak its context. + contexts.push_back(std::make_unique<Context>( + Context{gpgme_version, gpgconf_path, component_info})); commands.push_back({gpgconf_path, {"--homedir", default_home_path, "--list-options", component_info.name}, GetGpgOptionInfos, - context}); + contexts.back().get()}); } gf::sdk::RunCommands(GFModuleSdkContext(), commands); @@ -496,7 +494,4 @@ void GetGpgOptionInfos(void *data, int exit_code, const char *out, (QJsonDocument(jsonlized_option_info).toJson()).constData()); options_infos.push_back(info); } - - context->~Context(); - GFMemFree(GFModuleSdkContext(), GF_ARENA_NORMAL, context); }
\ No newline at end of file diff --git a/src/m_gpg_info/GnupgTab.cpp b/src/m_gpg_info/GnupgTab.cpp index a340551..e165654 100644 --- a/src/m_gpg_info/GnupgTab.cpp +++ b/src/m_gpg_info/GnupgTab.cpp @@ -316,7 +316,7 @@ GnupgTabWatcher::GnupgTabWatcher(GnupgTab* tab) { auto future = QtConcurrent::run(QThreadPool::globalInstance(), [=]() { if (StartGatheringAllGnuPGInfo() >= 0) { - gf::sdk::SetStateBool(GFModuleSdkContext(), "ui", + gf::sdk::SetStateBool(GFModuleSdkContext(), GFModuleId(), "env.state.gnupg_info_gathering", 1); emit SignalGnuPGInfoGathered(); } @@ -327,7 +327,7 @@ GnupgTabWatcher::GnupgTabWatcher(GnupgTab* tab) { void GnupgTab::showEvent(QShowEvent* event) { QWidget::showEvent(event); - int gathered = gf::sdk::StateBool(GFModuleSdkContext(), "ui", + int gathered = gf::sdk::StateBool(GFModuleSdkContext(), GFModuleId(), "env.state.gnupg_info_gathering", 0); if (gathered == 1) { slot_process_software_info(); diff --git a/src/m_gpg_info/module.json b/src/m_gpg_info/module.json index 0f3efd4..2065fcd 100644 --- a/src/m_gpg_info/module.json +++ b/src/m_gpg_info/module.json @@ -12,9 +12,7 @@ "ui", "ui.custom" ], - "events": [ - "REQUEST_GATHERING_ALL_GNUPG_INFO" - ], + "events": [], "commands": [ "com.bktus.gpgfrontend.module.gnupg_info_gathering.show_gnupg_info" ], |
