From 465e3d979d72da90ea4f715393a0d6d3098830b1 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 29 Apr 2025 18:20:06 +0100 Subject: [PATCH] window: make AsyncDialogBoxes not closeable we don't want the user to accidentally close a popup for permissions or ANR. They can dismiss them by clicking an appropriate option. --- src/events/Windows.cpp | 6 ++++++ src/helpers/AsyncDialogBox.cpp | 9 +++++++++ src/helpers/AsyncDialogBox.hpp | 1 + 3 files changed, 16 insertions(+) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 9e0d2be5c..f476c6e89 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -2,6 +2,7 @@ #include "../Compositor.hpp" #include "../helpers/WLClasses.hpp" +#include "../helpers/AsyncDialogBox.hpp" #include "../managers/input/InputManager.hpp" #include "../managers/TokenManager.hpp" #include "../managers/SeatManager.hpp" @@ -327,6 +328,11 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->applyDynamicRule(r); } + // make it uncloseable if it's a Hyprland dialog + // TODO: make some closeable? + if (CAsyncDialogBox::isAsyncDialogBox(PWINDOW->getPID())) + PWINDOW->m_closeableSince = Time::steadyNow() + std::chrono::years(10 /* Should be enough, no? */); + // disallow tiled pinned if (PWINDOW->m_pinned && !PWINDOW->m_isFloating) PWINDOW->m_pinned = false; diff --git a/src/helpers/AsyncDialogBox.cpp b/src/helpers/AsyncDialogBox.cpp index 86eb9e1f0..6cda0d449 100644 --- a/src/helpers/AsyncDialogBox.cpp +++ b/src/helpers/AsyncDialogBox.cpp @@ -6,6 +6,9 @@ using namespace Hyprutils::OS; +static std::vector asyncDialogBoxes; + +// SP CAsyncDialogBox::create(const std::string& title, const std::string& description, std::vector buttons) { if (!NFsUtils::executableExistsInPath("hyprland-dialog")) { Debug::log(ERR, "CAsyncDialogBox: cannot create, no hyprland-dialog"); @@ -19,6 +22,10 @@ SP CAsyncDialogBox::create(const std::string& title, const std: return dialog; } +bool CAsyncDialogBox::isAsyncDialogBox(pid_t pid) { + return std::ranges::contains(asyncDialogBoxes, pid); +} + CAsyncDialogBox::CAsyncDialogBox(const std::string& title, const std::string& description, std::vector buttons) : m_title(title), m_description(description), m_buttons(buttons) { ; @@ -60,6 +67,7 @@ void CAsyncDialogBox::onWrite(int fd, uint32_t mask) { Debug::log(LOG, "CAsyncDialogBox: dialog {:x} hung up, closed."); m_promiseResolver->resolve(m_stdout); + std::erase(asyncDialogBoxes, m_dialogPid); wl_event_source_remove(m_readEventSource); m_selfReference.reset(); @@ -103,6 +111,7 @@ SP> CAsyncDialogBox::open() { } m_dialogPid = proc.pid(); + asyncDialogBoxes.emplace_back(m_dialogPid); // close the write fd, only the dialog owns it now close(outPipe[1]); diff --git a/src/helpers/AsyncDialogBox.hpp b/src/helpers/AsyncDialogBox.hpp index 0cb95846b..4018a857d 100644 --- a/src/helpers/AsyncDialogBox.hpp +++ b/src/helpers/AsyncDialogBox.hpp @@ -15,6 +15,7 @@ struct wl_event_source; class CAsyncDialogBox { public: static SP create(const std::string& title, const std::string& description, std::vector buttons); + static bool isAsyncDialogBox(pid_t pid); CAsyncDialogBox(const CAsyncDialogBox&) = delete; CAsyncDialogBox(CAsyncDialogBox&&) = delete;