mirror of
https://github.com/hyprwm/hypridle.git
synced 2024-11-16 23:25:58 +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:unlock_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();
|
||||
|
||||
|
|
|
@ -93,11 +93,15 @@ void CHypridle::enterEventLoop() {
|
|||
.fd = wl_display_get_fd(m_sWaylandState.display),
|
||||
.events = POLLIN,
|
||||
},
|
||||
{
|
||||
.fd = m_sDBUSState.screenSaverServiceConnection ? m_sDBUSState.screenSaverServiceConnection->getEventLoopPollData().fd : 0,
|
||||
.events = POLLIN,
|
||||
},
|
||||
};
|
||||
|
||||
std::thread pollThr([this, &pollfds]() {
|
||||
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) {
|
||||
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
||||
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
|
||||
int ret = 0;
|
||||
do {
|
||||
|
@ -268,6 +279,27 @@ void CHypridle::onResumed(SIdleListener* pListener) {
|
|||
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) {
|
||||
// lock & unlock
|
||||
static auto* const PLOCKCMD = (Hyprlang::STRING const*)g_pConfigManager->getValuePtr("general:lock_cmd");
|
||||
|
@ -310,6 +342,46 @@ void handleDbusSleep(sdbus::Message& msg) {
|
|||
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() {
|
||||
auto proxy = sdbus::createProxy("org.freedesktop.login1", "/org/freedesktop/login1");
|
||||
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='/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 = "";
|
||||
};
|
||||
|
||||
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 onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
|
||||
void run();
|
||||
|
||||
void onIdled(SIdleListener*);
|
||||
void onResumed(SIdleListener*);
|
||||
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
|
||||
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:
|
||||
void setupDBUS();
|
||||
void enterEventLoop();
|
||||
void setupDBUS();
|
||||
void enterEventLoop();
|
||||
|
||||
bool m_bTerminate = false;
|
||||
bool m_bTerminate = false;
|
||||
int64_t m_iInhibitLocks = 0;
|
||||
|
||||
struct {
|
||||
wl_display* display = nullptr;
|
||||
|
@ -45,7 +56,9 @@ class CHypridle {
|
|||
|
||||
struct {
|
||||
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;
|
||||
|
||||
struct {
|
||||
|
|
Loading…
Reference in a new issue