async: add Promise and use it for AsyncDialogBox
This commit is contained in:
parent
4f868a1f3c
commit
0302bfdc22
7 changed files with 208 additions and 36 deletions
|
|
@ -169,7 +169,14 @@ void CANRManager::SANRData::runDialog(const std::string& title, const std::strin
|
|||
appClass.empty() ? "unknown" : appClass),
|
||||
std::vector<std::string>{"Terminate", "Wait"});
|
||||
|
||||
dialogBox->open([dialogWmPID, this](std::string result) {
|
||||
dialogBox->open()->then([dialogWmPID, this](SP<CPromiseResult<std::string>> r) {
|
||||
if (r->hasError()) {
|
||||
Debug::log(ERR, "CANRManager::SANRData::runDialog: error spawning dialog");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& result = r->result();
|
||||
|
||||
if (result.starts_with("Terminate"))
|
||||
::kill(dialogWmPID, SIGKILL);
|
||||
else if (result.starts_with("Wait"))
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ static const char* permissionToString(eDynamicPermissionType type) {
|
|||
switch (type) {
|
||||
case PERMISSION_TYPE_UNKNOWN: return "PERMISSION_TYPE_UNKNOWN";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "PERMISSION_TYPE_SCREENCOPY";
|
||||
case PERMISSION_TYPE_PLUGIN: return "PERMISSION_TYPE_PLUGIN";
|
||||
}
|
||||
|
||||
return "error";
|
||||
|
|
@ -57,6 +58,7 @@ static const char* permissionToHumanString(eDynamicPermissionType type) {
|
|||
switch (type) {
|
||||
case PERMISSION_TYPE_UNKNOWN: return "requesting an unknown permission";
|
||||
case PERMISSION_TYPE_SCREENCOPY: return "trying to capture your screen";
|
||||
case PERMISSION_TYPE_PLUGIN: return "trying to load a plugin";
|
||||
}
|
||||
|
||||
return "error";
|
||||
|
|
@ -210,10 +212,22 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||
return;
|
||||
}
|
||||
|
||||
rule->m_dialogBox->open([r = WP<CDynamicPermissionRule>(rule), binaryPath](std::string result) {
|
||||
rule->m_promise = rule->m_dialogBox->open();
|
||||
rule->m_promise->then([r = WP<CDynamicPermissionRule>(rule), binaryPath](SP<CPromiseResult<std::string>> pr) {
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
if (pr->hasError()) {
|
||||
// not reachable for now
|
||||
Debug::log(TRACE, "CDynamicPermissionRule: error spawning dialog box");
|
||||
if (r->m_promiseResolverForExternal)
|
||||
r->m_promiseResolverForExternal->reject("error spawning dialog box");
|
||||
r->m_promiseResolverForExternal.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& result = pr->result();
|
||||
|
||||
Debug::log(TRACE, "CDynamicPermissionRule: user returned {}", result);
|
||||
|
||||
if (result.starts_with("Allow once"))
|
||||
|
|
@ -226,9 +240,29 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||
r->m_binaryPath = binaryPath;
|
||||
} else if (result.starts_with("Allow"))
|
||||
r->m_allowMode = PERMISSION_RULE_ALLOW_MODE_ALLOW;
|
||||
|
||||
if (r->m_promiseResolverForExternal)
|
||||
r->m_promiseResolverForExternal->resolve(r->m_allowMode);
|
||||
|
||||
r->m_promise.reset();
|
||||
r->m_promiseResolverForExternal.reset();
|
||||
});
|
||||
}
|
||||
|
||||
SP<CPromise<eDynamicPermissionAllowMode>> CDynamicPermissionManager::promiseFor(wl_client* client, eDynamicPermissionType permission) {
|
||||
auto rule = std::ranges::find_if(m_rules, [client, permission](const auto& e) { return e->m_client == client && e->m_type == permission; });
|
||||
if (rule == m_rules.end())
|
||||
return nullptr;
|
||||
|
||||
if (!(*rule)->m_promise)
|
||||
return nullptr;
|
||||
|
||||
if ((*rule)->m_promiseResolverForExternal)
|
||||
return nullptr;
|
||||
|
||||
return CPromise<eDynamicPermissionAllowMode>::make([rule](SP<CPromiseResolver<eDynamicPermissionAllowMode>> r) { (*rule)->m_promiseResolverForExternal = r; });
|
||||
}
|
||||
|
||||
void CDynamicPermissionManager::removeRulesForClient(wl_client* client) {
|
||||
std::erase_if(m_rules, [client](const auto& e) { return e->m_client == client; });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "../../helpers/AsyncDialogBox.hpp"
|
||||
#include <vector>
|
||||
#include <wayland-server-core.h>
|
||||
#include <optional>
|
||||
#include "../../helpers/defer/Promise.hpp"
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
namespace re2 {
|
||||
|
|
@ -15,6 +15,7 @@ namespace re2 {
|
|||
enum eDynamicPermissionType : uint8_t {
|
||||
PERMISSION_TYPE_UNKNOWN = 0,
|
||||
PERMISSION_TYPE_SCREENCOPY,
|
||||
PERMISSION_TYPE_PLUGIN,
|
||||
};
|
||||
|
||||
enum eDynamicPermissionRuleSource : uint8_t {
|
||||
|
|
@ -50,16 +51,18 @@ class CDynamicPermissionRule {
|
|||
// user rule
|
||||
CDynamicPermissionRule(wl_client* const client, eDynamicPermissionType type, eDynamicPermissionAllowMode defaultAllowMode = PERMISSION_RULE_ALLOW_MODE_ASK);
|
||||
|
||||
const eDynamicPermissionType m_type = PERMISSION_TYPE_UNKNOWN;
|
||||
const eDynamicPermissionRuleSource m_source = PERMISSION_RULE_SOURCE_UNKNOWN;
|
||||
wl_client* const m_client = nullptr;
|
||||
std::string m_binaryPath = "";
|
||||
UP<re2::RE2> m_binaryRegex;
|
||||
const eDynamicPermissionType m_type = PERMISSION_TYPE_UNKNOWN;
|
||||
const eDynamicPermissionRuleSource m_source = PERMISSION_RULE_SOURCE_UNKNOWN;
|
||||
wl_client* const m_client = nullptr;
|
||||
std::string m_binaryPath = "";
|
||||
UP<re2::RE2> m_binaryRegex;
|
||||
|
||||
eDynamicPermissionAllowMode m_allowMode = PERMISSION_RULE_ALLOW_MODE_ASK;
|
||||
SP<CAsyncDialogBox> m_dialogBox; // for pending
|
||||
eDynamicPermissionAllowMode m_allowMode = PERMISSION_RULE_ALLOW_MODE_ASK;
|
||||
SP<CAsyncDialogBox> m_dialogBox; // for pending
|
||||
SP<CPromise<std::string>> m_promise; // for pending
|
||||
SP<CPromiseResolver<eDynamicPermissionAllowMode>> m_promiseResolverForExternal; // for external promise
|
||||
|
||||
SDynamicPermissionRuleDestroyWrapper m_destroyWrapper;
|
||||
SDynamicPermissionRuleDestroyWrapper m_destroyWrapper;
|
||||
|
||||
friend class CDynamicPermissionManager;
|
||||
};
|
||||
|
|
@ -73,7 +76,11 @@ class CDynamicPermissionManager {
|
|||
// (will continue returning false if the user does not agree, of course.)
|
||||
eDynamicPermissionAllowMode clientPermissionMode(wl_client* client, eDynamicPermissionType permission);
|
||||
|
||||
void removeRulesForClient(wl_client* client);
|
||||
// get a promise for the result. Returns null if there already was one requested for the client.
|
||||
// Returns null if state is not pending
|
||||
SP<CPromise<eDynamicPermissionAllowMode>> promiseFor(wl_client* client, eDynamicPermissionType permission);
|
||||
|
||||
void removeRulesForClient(wl_client* client);
|
||||
|
||||
private:
|
||||
void askForPermission(wl_client* client, const std::string& binaryName, eDynamicPermissionType type);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue