mirror of
https://github.com/hyprwm/hypridle.git
synced 2024-11-16 15:15:59 +01:00
dbus: support ScreenSaver interface
This commit is contained in:
parent
55410176d4
commit
9320017b63
3 changed files with 107 additions and 10 deletions
|
@ -27,6 +27,7 @@ void CConfigManager::init() {
|
||||||
m_config.addConfigValue("general:lock_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:lock_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:unlock_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:unlock_cmd", Hyprlang::STRING{""});
|
||||||
m_config.addConfigValue("general:before_sleep_cmd", Hyprlang::STRING{""});
|
m_config.addConfigValue("general:before_sleep_cmd", Hyprlang::STRING{""});
|
||||||
|
m_config.addConfigValue("general:ignore_dbus_inhibit", Hyprlang::INT{0});
|
||||||
|
|
||||||
m_config.commence();
|
m_config.commence();
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,15 @@ void CHypridle::enterEventLoop() {
|
||||||
.fd = wl_display_get_fd(m_sWaylandState.display),
|
.fd = wl_display_get_fd(m_sWaylandState.display),
|
||||||
.events = POLLIN,
|
.events = POLLIN,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.fd = m_sDBUSState.screenSaverServiceConnection ? m_sDBUSState.screenSaverServiceConnection->getEventLoopPollData().fd : 0,
|
||||||
|
.events = POLLIN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::thread pollThr([this, &pollfds]() {
|
std::thread pollThr([this, &pollfds]() {
|
||||||
while (1) {
|
while (1) {
|
||||||
int ret = poll(pollfds, 2, 5000 /* 5 seconds, reasonable. It's because we might need to terminate */);
|
int ret = poll(pollfds, m_sDBUSState.screenSaverServiceConnection ? 3 : 2, 5000 /* 5 seconds, reasonable. It's because we might need to terminate */);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
||||||
m_bTerminate = true;
|
m_bTerminate = true;
|
||||||
|
@ -159,6 +163,13 @@ void CHypridle::enterEventLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pollfds[2].revents & POLLIN /* dbus2 */) {
|
||||||
|
Debug::log(TRACE, "got dbus event");
|
||||||
|
while (m_sDBUSState.screenSaverServiceConnection->processPendingRequest()) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// finalize wayland dispatching. Dispatch pending on the queue
|
// finalize wayland dispatching. Dispatch pending on the queue
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -268,6 +279,27 @@ void CHypridle::onResumed(SIdleListener* pListener) {
|
||||||
spawn(pListener->onRestore);
|
spawn(pListener->onRestore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHypridle::onInhibit(bool lock) {
|
||||||
|
m_iInhibitLocks += lock ? 1 : -1;
|
||||||
|
if (m_iInhibitLocks < 0)
|
||||||
|
Debug::log(WARN, "BUG THIS: inhibit locks < 0");
|
||||||
|
else
|
||||||
|
Debug::log(LOG, "Inhibit locks: {}", m_iInhibitLocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHypridle::SDbusInhibitCookie CHypridle::getDbusInhibitCookie(uint32_t cookie) {
|
||||||
|
for (auto& c : m_sDBUSState.inhibitCookies) {
|
||||||
|
if (c.cookie == cookie)
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHypridle::registerDbusInhibitCookie(CHypridle::SDbusInhibitCookie& cookie) {
|
||||||
|
m_sDBUSState.inhibitCookies.push_back(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
void handleDbusLogin(sdbus::Message& msg) {
|
void handleDbusLogin(sdbus::Message& msg) {
|
||||||
// lock & unlock
|
// lock & unlock
|
||||||
static auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:lock_cmd");
|
static auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:lock_cmd");
|
||||||
|
@ -310,6 +342,46 @@ void handleDbusSleep(sdbus::Message& msg) {
|
||||||
spawn(*PSLEEPCMD);
|
spawn(*PSLEEPCMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleDbusScreensaver(sdbus::MethodCall call, bool inhibit) {
|
||||||
|
std::string app = "?", reason = "?";
|
||||||
|
|
||||||
|
if (inhibit) {
|
||||||
|
call >> app;
|
||||||
|
call >> reason;
|
||||||
|
} else {
|
||||||
|
uint32_t cookie = 0;
|
||||||
|
call >> cookie;
|
||||||
|
const auto COOKIE = g_pHypridle->getDbusInhibitCookie(cookie);
|
||||||
|
if (COOKIE.cookie == 0) {
|
||||||
|
Debug::log(WARN, "No cookie in uninhibit");
|
||||||
|
} else {
|
||||||
|
app = COOKIE.app;
|
||||||
|
reason = COOKIE.reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "ScreenSaver inhibit: {} dbus message from {} with content {}", inhibit, app, reason);
|
||||||
|
|
||||||
|
static auto* const PIGNORE = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:ignore_dbus_inhibit");
|
||||||
|
|
||||||
|
if (!**PIGNORE) {
|
||||||
|
if (inhibit)
|
||||||
|
g_pHypridle->onInhibit(true);
|
||||||
|
else
|
||||||
|
g_pHypridle->onInhibit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cookieID = 1337;
|
||||||
|
|
||||||
|
if (inhibit) {
|
||||||
|
auto reply = call.createReply();
|
||||||
|
reply << uint32_t{cookieID++};
|
||||||
|
reply.send();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Cookie {} sent", cookieID - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CHypridle::setupDBUS() {
|
void CHypridle::setupDBUS() {
|
||||||
auto proxy = sdbus::createProxy("org.freedesktop.login1", "/org/freedesktop/login1");
|
auto proxy = sdbus::createProxy("org.freedesktop.login1", "/org/freedesktop/login1");
|
||||||
auto method = proxy->createMethodCall("org.freedesktop.login1.Manager", "GetSession");
|
auto method = proxy->createMethodCall("org.freedesktop.login1.Manager", "GetSession");
|
||||||
|
@ -323,4 +395,15 @@ 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{});
|
||||||
|
|
||||||
|
// attempt to register as ScreenSaver
|
||||||
|
try {
|
||||||
|
m_sDBUSState.screenSaverServiceConnection = sdbus::createSessionBusConnection("org.freedesktop.ScreenSaver");
|
||||||
|
m_sDBUSState.screenSaverObject = sdbus::createObject(*m_sDBUSState.screenSaverServiceConnection, "/org/freedesktop/ScreenSaver");
|
||||||
|
|
||||||
|
m_sDBUSState.screenSaverObject->registerMethod("org.freedesktop.ScreenSaver", "Inhibit", "ss", "u", [&](sdbus::MethodCall c) { handleDbusScreensaver(c, true); });
|
||||||
|
m_sDBUSState.screenSaverObject->registerMethod("org.freedesktop.ScreenSaver", "UnInhibit", "u", "", [&](sdbus::MethodCall c) { handleDbusScreensaver(c, false); });
|
||||||
|
|
||||||
|
m_sDBUSState.screenSaverObject->finishRegistration();
|
||||||
|
} catch (std::exception& e) { Debug::log(ERR, "Failed registering for /org/freedesktop/ScreenSaver, perhaps taken?\nerr: {}", e.what()); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,30 @@ class CHypridle {
|
||||||
std::string onRestore = "";
|
std::string onRestore = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
void run();
|
struct SDbusInhibitCookie {
|
||||||
|
uint32_t cookie = 0;
|
||||||
|
std::string app, reason;
|
||||||
|
};
|
||||||
|
|
||||||
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
|
void run();
|
||||||
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
|
|
||||||
|
|
||||||
void onIdled(SIdleListener*);
|
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
|
||||||
void onResumed(SIdleListener*);
|
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
|
||||||
|
|
||||||
|
void onIdled(SIdleListener*);
|
||||||
|
void onResumed(SIdleListener*);
|
||||||
|
|
||||||
|
void onInhibit(bool lock);
|
||||||
|
|
||||||
|
SDbusInhibitCookie getDbusInhibitCookie(uint32_t cookie);
|
||||||
|
void registerDbusInhibitCookie(SDbusInhibitCookie& cookie);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupDBUS();
|
void setupDBUS();
|
||||||
void enterEventLoop();
|
void enterEventLoop();
|
||||||
|
|
||||||
bool m_bTerminate = false;
|
bool m_bTerminate = false;
|
||||||
|
int64_t m_iInhibitLocks = 0;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
wl_display* display = nullptr;
|
wl_display* display = nullptr;
|
||||||
|
@ -45,7 +56,9 @@ class CHypridle {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::unique_ptr<sdbus::IConnection> connection;
|
std::unique_ptr<sdbus::IConnection> connection;
|
||||||
sdbus::Slot login1match;
|
std::unique_ptr<sdbus::IConnection> screenSaverServiceConnection;
|
||||||
|
std::unique_ptr<sdbus::IObject> screenSaverObject;
|
||||||
|
std::vector<SDbusInhibitCookie> inhibitCookies;
|
||||||
} m_sDBUSState;
|
} m_sDBUSState;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
Loading…
Reference in a new issue