diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-04-06 17:31:58 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-06 17:31:58 +0200 |
| commit | 3c128679ee8c86bbbeb5ae38621f6de622525cf1 (patch) | |
| tree | 08a920819d766099d7a3d7fde9a8f968992c3a2c /src/managers/ANRManager.cpp | |
| parent | e96b8ce4cc5e5856b6da653f1d92af856b5e72c9 (diff) | |
helpers: Add an async dialog box impl (#9919)
Adds an async dialog box, way safer than our previous local solution for ANR
Diffstat (limited to 'src/managers/ANRManager.cpp')
| -rw-r--r-- | src/managers/ANRManager.cpp | 73 |
1 files changed, 23 insertions, 50 deletions
diff --git a/src/managers/ANRManager.cpp b/src/managers/ANRManager.cpp index 3debcda8..acdb39b7 100644 --- a/src/managers/ANRManager.cpp +++ b/src/managers/ANRManager.cpp @@ -39,8 +39,6 @@ CANRManager::CANRManager() { } void CANRManager::onTick() { - std::erase_if(m_data, [](const auto& e) { return e->isDefunct(); }); - static auto PENABLEANR = CConfigValue<Hyprlang::INT>("misc:enable_anr_dialog"); static auto PANRTHRESHOLD = CConfigValue<Hyprlang::INT>("misc:anr_missed_pings"); @@ -68,7 +66,7 @@ void CANRManager::onTick() { continue; if (data->missedResponses >= *PANRTHRESHOLD) { - if (!data->isThreadRunning() && !data->dialogThreadSaidWait) { + if (!data->isRunning() && !data->dialogSaidWait) { data->runDialog("Application Not Responding", firstWindow->m_szTitle, firstWindow->m_szClass, data->getPid()); for (const auto& w : g_pCompositor->m_vWindows) { @@ -81,11 +79,11 @@ void CANRManager::onTick() { *w->m_notRespondingTint = 0.2F; } } - } else if (data->isThreadRunning()) + } else if (data->isRunning()) data->killDialog(); if (data->missedResponses == 0) - data->dialogThreadSaidWait = false; + data->dialogSaidWait = false; data->missedResponses++; @@ -115,7 +113,7 @@ void CANRManager::onResponse(SP<CXWaylandSurface> pXwaylandSurface) { void CANRManager::onResponse(SP<CANRManager::SANRData> data) { data->missedResponses = 0; - if (data->isThreadRunning()) + if (data->isRunning()) data->killDialog(); } @@ -158,64 +156,39 @@ CANRManager::SANRData::SANRData(PHLWINDOW pWindow) : } CANRManager::SANRData::~SANRData() { - if (dialogThread.joinable()) { + if (dialogBox && dialogBox->isRunning()) killDialog(); - // dangerous: might lock if the above failed!! - dialogThread.join(); - } } void CANRManager::SANRData::runDialog(const std::string& title, const std::string& appName, const std::string appClass, pid_t dialogWmPID) { - if (!dialogThreadExited) + if (dialogBox && dialogBox->isRunning()) killDialog(); - // dangerous: might lock if the above failed!! - if (dialogThread.joinable()) - dialogThread.join(); - - dialogThreadExited = false; - dialogThreadSaidWait = false; - dialogThread = std::thread([title, appName, appClass, dialogWmPID, this]() { - SP<CProcess> proc = makeShared<CProcess>("hyprland-dialog", - std::vector<std::string>{"--title", title, "--text", - std::format("Application {} with class of {} is not responding.\nWhat do you want to do with it?", - appName.empty() ? "unknown" : appName, appClass.empty() ? "unknown" : appClass), - "--buttons", "Terminate;Wait"}); - - dialogProc = proc; - proc->runSync(); - - dialogThreadExited = true; - - if (proc->stdOut().empty()) - return; - - if (proc->stdOut().starts_with("Terminate")) - kill(dialogWmPID, SIGKILL); - if (proc->stdOut().starts_with("Wait")) - dialogThreadSaidWait = true; + dialogBox = CAsyncDialogBox::create(title, + std::format("Application {} with class of {} is not responding.\nWhat do you want to do with it?", appName.empty() ? "unknown" : appName, + appClass.empty() ? "unknown" : appClass), + std::vector<std::string>{"Terminate", "Wait"}); + + dialogBox->open([dialogWmPID, this](std::string result) { + if (result.starts_with("Terminate")) + ::kill(dialogWmPID, SIGKILL); + else if (result.starts_with("Wait")) + dialogSaidWait = true; + else + Debug::log(ERR, "CANRManager::SANRData::runDialog: lambda: unrecognized result: {}", result); }); } -bool CANRManager::SANRData::isThreadRunning() { - if (dialogThread.native_handle() == 0) - return false; - if (dialogThreadExited) - return false; - return pthread_kill(dialogThread.native_handle(), 0) != ESRCH; +bool CANRManager::SANRData::isRunning() { + return dialogBox && dialogBox->isRunning(); } void CANRManager::SANRData::killDialog() { - if (!dialogProc) + if (!dialogBox) return; - if (!dialogProc->pid()) { - Debug::log(ERR, "ANR: cannot kill dialogProc, as it doesn't have a pid."); - dialogProc = nullptr; - return; - } - - kill(dialogProc->pid(), SIGKILL); + dialogBox->kill(); + dialogBox = nullptr; } bool CANRManager::SANRData::fitsWindow(PHLWINDOW pWindow) const { |
