core: release inhibit cookies on app disconnect from dbus (#93)

* core: release inhibit cookies on app disconnect from dbus

* core: clang-format
This commit is contained in:
André Silva 2024-10-20 23:04:37 +01:00 committed by GitHub
parent cc23f97836
commit 0ed59e861c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 21 deletions

View file

@ -334,14 +334,26 @@ void CHypridle::registerDbusInhibitCookie(CHypridle::SDbusInhibitCookie& cookie)
m_sDBUSState.inhibitCookies.push_back(cookie); m_sDBUSState.inhibitCookies.push_back(cookie);
} }
void CHypridle::unregisterDbusInhibitCookie(const CHypridle::SDbusInhibitCookie& cookie) { bool CHypridle::unregisterDbusInhibitCookie(const CHypridle::SDbusInhibitCookie& cookie) {
const auto IT = std::find_if(m_sDBUSState.inhibitCookies.begin(), m_sDBUSState.inhibitCookies.end(), const auto IT = std::find_if(m_sDBUSState.inhibitCookies.begin(), m_sDBUSState.inhibitCookies.end(),
[&cookie](const CHypridle::SDbusInhibitCookie& item) { return item.cookie == cookie.cookie; }); [&cookie](const CHypridle::SDbusInhibitCookie& item) { return item.cookie == cookie.cookie; });
if (IT == m_sDBUSState.inhibitCookies.end()) if (IT == m_sDBUSState.inhibitCookies.end())
Debug::log(WARN, "BUG THIS: attempted to unregister unknown cookie"); return false;
else
m_sDBUSState.inhibitCookies.erase(IT); m_sDBUSState.inhibitCookies.erase(IT);
return true;
}
bool CHypridle::unregisterDbusInhibitCookies(const std::string& ownerID) {
const auto IT = std::remove_if(m_sDBUSState.inhibitCookies.begin(), m_sDBUSState.inhibitCookies.end(),
[&ownerID](const CHypridle::SDbusInhibitCookie& item) { return item.ownerID == ownerID; });
if (IT == m_sDBUSState.inhibitCookies.end())
return false;
m_sDBUSState.inhibitCookies.erase(IT, m_sDBUSState.inhibitCookies.end());
return true;
} }
void handleDbusLogin(sdbus::Message& msg) { void handleDbusLogin(sdbus::Message& msg) {
@ -420,6 +432,7 @@ void handleDbusBlockInhibitsPropertyChanged(sdbus::Message& msg) {
void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) { void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) {
std::string app = "?", reason = "?"; std::string app = "?", reason = "?";
std::string ownerID = call.getSender();
if (inhibit) { if (inhibit) {
call >> app; call >> app;
@ -434,11 +447,15 @@ void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) {
} else { } else {
app = COOKIE.app; app = COOKIE.app;
reason = COOKIE.reason; reason = COOKIE.reason;
g_pHypridle->unregisterDbusInhibitCookie(COOKIE); ownerID = COOKIE.ownerID;
if (!g_pHypridle->unregisterDbusInhibitCookie(COOKIE)) {
Debug::log(WARN, "BUG THIS: attempted to unregister unknown cookie");
};
} }
} }
Debug::log(LOG, "ScreenSaver inhibit: {} dbus message from {} with content {}", inhibit, app, reason); Debug::log(LOG, "ScreenSaver inhibit: {} dbus message from {} (owner: {}) with content {}", inhibit, app, ownerID, reason);
if (inhibit) if (inhibit)
g_pHypridle->onInhibit(true); g_pHypridle->onInhibit(true);
@ -448,7 +465,7 @@ void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) {
static int cookieID = 1337; static int cookieID = 1337;
if (inhibit) { if (inhibit) {
auto cookie = CHypridle::SDbusInhibitCookie{uint32_t{cookieID}, app, reason}; auto cookie = CHypridle::SDbusInhibitCookie{uint32_t{cookieID}, app, reason, ownerID};
auto reply = call.createReply(); auto reply = call.createReply();
reply << uint32_t{cookieID++}; reply << uint32_t{cookieID++};
@ -464,6 +481,19 @@ void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) {
} }
} }
void handleDbusNameOwnerChanged(sdbus::Message& msg) {
std::string name, oldOwner, newOwner;
msg >> name >> oldOwner >> newOwner;
if (!newOwner.empty())
return;
if (g_pHypridle->unregisterDbusInhibitCookies(oldOwner)) {
Debug::log(LOG, "App with owner {} disconnected", oldOwner);
g_pHypridle->onInhibit(false);
}
}
void CHypridle::setupDBUS() { void CHypridle::setupDBUS() {
static auto const IGNORE_DBUS_INHIBIT = **(Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:ignore_dbus_inhibit"); static auto const IGNORE_DBUS_INHIBIT = **(Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:ignore_dbus_inhibit");
static auto const IGNORE_SYSTEMD_INHIBIT = **(Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:ignore_systemd_inhibit"); static auto const IGNORE_SYSTEMD_INHIBIT = **(Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:ignore_systemd_inhibit");
@ -479,14 +509,13 @@ void CHypridle::setupDBUS() {
m_sDBUSState.connection->addMatch("type='signal',path='" + path + "',interface='org.freedesktop.login1.Session'", handleDbusLogin, sdbus::floating_slot_t{}); m_sDBUSState.connection->addMatch("type='signal',path='" + path + "',interface='org.freedesktop.login1.Session'", handleDbusLogin, sdbus::floating_slot_t{});
m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.login1.Manager'", handleDbusSleep, sdbus::floating_slot_t{}); m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.login1.Manager'", handleDbusSleep, sdbus::floating_slot_t{});
} catch (std::exception& e) { } catch (std::exception& e) { Debug::log(WARN, "Couldn't connect to logind service ({})", e.what()); }
Debug::log(WARN, "Couldn't connect to logind service ({})", e.what());
}
Debug::log(LOG, "Using dbus path {}", path.c_str()); Debug::log(LOG, "Using dbus path {}", path.c_str());
if (!IGNORE_SYSTEMD_INHIBIT) { if (!IGNORE_SYSTEMD_INHIBIT) {
m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.DBus.Properties'", handleDbusBlockInhibitsPropertyChanged, sdbus::floating_slot_t{}); m_sDBUSState.connection->addMatch("type='signal',path='/org/freedesktop/login1',interface='org.freedesktop.DBus.Properties'", handleDbusBlockInhibitsPropertyChanged,
sdbus::floating_slot_t{});
try { try {
std::string value = proxy->getProperty("BlockInhibited").onInterface("org.freedesktop.login1.Manager"); std::string value = proxy->getProperty("BlockInhibited").onInterface("org.freedesktop.login1.Manager");
@ -504,7 +533,7 @@ void CHypridle::setupDBUS() {
try { try {
m_sDBUSState.screenSaverServiceConnection = sdbus::createSessionBusConnection("org.freedesktop.ScreenSaver"); m_sDBUSState.screenSaverServiceConnection = sdbus::createSessionBusConnection("org.freedesktop.ScreenSaver");
for (const std::string& path: paths) { for (const std::string& path : paths) {
try { try {
auto obj = sdbus::createObject(*m_sDBUSState.screenSaverServiceConnection, path); auto obj = sdbus::createObject(*m_sDBUSState.screenSaverServiceConnection, path);
obj->registerMethod("org.freedesktop.ScreenSaver", "Inhibit", "ss", "u", [&](sdbus::MethodCall c) { handleDbusScreensaver(c, true); }); obj->registerMethod("org.freedesktop.ScreenSaver", "Inhibit", "ss", "u", [&](sdbus::MethodCall c) { handleDbusScreensaver(c, true); });
@ -514,6 +543,9 @@ void CHypridle::setupDBUS() {
m_sDBUSState.screenSaverObjects.push_back(std::move(obj)); m_sDBUSState.screenSaverObjects.push_back(std::move(obj));
} catch (std::exception& e) { Debug::log(ERR, "Failed registering for {}, perhaps taken?\nerr: {}", path, e.what()); } } catch (std::exception& e) { Debug::log(ERR, "Failed registering for {}, perhaps taken?\nerr: {}", path, e.what()); }
} }
m_sDBUSState.screenSaverServiceConnection->addMatch("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
handleDbusNameOwnerChanged, sdbus::floating_slot_t{});
} catch (std::exception& e) { Debug::log(ERR, "Couldn't connect to session dbus\nerr: {}", e.what()); } } catch (std::exception& e) { Debug::log(ERR, "Couldn't connect to session dbus\nerr: {}", e.what()); }
} }
} }

View file

@ -20,7 +20,7 @@ class CHypridle {
struct SDbusInhibitCookie { struct SDbusInhibitCookie {
uint32_t cookie = 0; uint32_t cookie = 0;
std::string app, reason; std::string app, reason, ownerID;
}; };
void run(); void run();
@ -35,7 +35,8 @@ class CHypridle {
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie); SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
void registerDbusInhibitCookie(SDbusInhibitCookie& cookie); void registerDbusInhibitCookie(SDbusInhibitCookie& cookie);
void unregisterDbusInhibitCookie(const SDbusInhibitCookie& cookie); bool unregisterDbusInhibitCookie(const SDbusInhibitCookie& cookie);
bool unregisterDbusInhibitCookies(const std::string& ownerID);
private: private:
void setupDBUS(); void setupDBUS();