summaryrefslogtreecommitdiff
path: root/src/managers/ANRManager.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-04-06 17:31:58 +0200
committerGitHub <noreply@github.com>2025-04-06 17:31:58 +0200
commit3c128679ee8c86bbbeb5ae38621f6de622525cf1 (patch)
tree08a920819d766099d7a3d7fde9a8f968992c3a2c /src/managers/ANRManager.cpp
parente96b8ce4cc5e5856b6da653f1d92af856b5e72c9 (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.cpp73
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 {