mirror of
https://github.com/hyprwm/hypridle.git
synced 2025-05-13 05:30:40 +01:00
core: fix sleep delay and simplify process spawning (#127)
* core: fix sleep delay and simplify process spawning * core: duplicate the inhibit fd with F_DUPFD_CLOEXEC * nullptr and static * core: use hyprutils CProcess
This commit is contained in:
parent
3e30a63b5d
commit
9d97c22883
2 changed files with 26 additions and 52 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <hyprutils/os/Process.hpp>
|
||||||
|
|
||||||
CHypridle::CHypridle() {
|
CHypridle::CHypridle() {
|
||||||
m_sWaylandState.display = wl_display_connect(nullptr);
|
m_sWaylandState.display = wl_display_connect(nullptr);
|
||||||
|
@ -235,53 +236,13 @@ void CHypridle::enterEventLoop() {
|
||||||
static void spawn(const std::string& args) {
|
static void spawn(const std::string& args) {
|
||||||
Debug::log(LOG, "Executing {}", args);
|
Debug::log(LOG, "Executing {}", args);
|
||||||
|
|
||||||
int socket[2];
|
Hyprutils::OS::CProcess proc("/bin/sh", {"-c", args});
|
||||||
if (pipe(socket) != 0) {
|
if (!proc.runAsync()) {
|
||||||
Debug::log(LOG, "Unable to create pipe for fork");
|
Debug::log(ERR, "Failed run \"{}\"", args);
|
||||||
}
|
|
||||||
|
|
||||||
pid_t child, grandchild;
|
|
||||||
child = fork();
|
|
||||||
if (child < 0) {
|
|
||||||
close(socket[0]);
|
|
||||||
close(socket[1]);
|
|
||||||
Debug::log(LOG, "Fail to create the first fork");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (child == 0) {
|
|
||||||
// run in child
|
|
||||||
|
|
||||||
sigset_t set;
|
|
||||||
sigemptyset(&set);
|
|
||||||
sigprocmask(SIG_SETMASK, &set, nullptr);
|
|
||||||
|
|
||||||
grandchild = fork();
|
|
||||||
if (grandchild == 0) {
|
|
||||||
// run in grandchild
|
|
||||||
close(socket[0]);
|
|
||||||
close(socket[1]);
|
|
||||||
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
|
|
||||||
// exit grandchild
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
close(socket[0]);
|
|
||||||
write(socket[1], &grandchild, sizeof(grandchild));
|
|
||||||
close(socket[1]);
|
|
||||||
// exit child
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
// run in parent
|
|
||||||
close(socket[1]);
|
|
||||||
read(socket[0], &grandchild, sizeof(grandchild));
|
|
||||||
close(socket[0]);
|
|
||||||
// clear child and leave grandchild to init
|
|
||||||
waitpid(child, nullptr, 0);
|
|
||||||
if (grandchild < 0) {
|
|
||||||
Debug::log(LOG, "Failed to create the second fork");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Process Created with pid {}", grandchild);
|
Debug::log(LOG, "Process Created with pid {}", proc.pid());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHypridle::onIdled(SIdleListener* pListener) {
|
void CHypridle::onIdled(SIdleListener* pListener) {
|
||||||
|
@ -424,7 +385,7 @@ static void handleDbusLogin(sdbus::Message msg) {
|
||||||
Debug::log(LOG, "Got Unlock from dbus");
|
Debug::log(LOG, "Got Unlock from dbus");
|
||||||
|
|
||||||
if (!std::string{*UNLOCKCMD}.empty()) {
|
if (!std::string{*UNLOCKCMD}.empty()) {
|
||||||
Debug::log(LOG, "Locking with {}", *UNLOCKCMD);
|
Debug::log(LOG, "Unlocking with {}", *UNLOCKCMD);
|
||||||
spawn(*UNLOCKCMD);
|
spawn(*UNLOCKCMD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +417,7 @@ static void handleDbusSleep(sdbus::Message msg) {
|
||||||
g_pHypridle->handleInhibitOnDbusSleep(toSleep);
|
g_pHypridle->handleInhibitOnDbusSleep(toSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDbusBlockInhibits(const std::string& inhibits) {
|
static void handleDbusBlockInhibits(const std::string& inhibits) {
|
||||||
static auto inhibited = false;
|
static auto inhibited = false;
|
||||||
// BlockInhibited is a colon separated list of inhibit types. Wrapping in additional colons allows for easier checking if there are active inhibits we are interested in
|
// BlockInhibited is a colon separated list of inhibit types. Wrapping in additional colons allows for easier checking if there are active inhibits we are interested in
|
||||||
auto inhibits_ = ":" + inhibits + ":";
|
auto inhibits_ = ":" + inhibits + ":";
|
||||||
|
@ -609,6 +570,11 @@ void CHypridle::handleInhibitOnDbusSleep(bool toSleep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHypridle::inhibitSleep() {
|
void CHypridle::inhibitSleep() {
|
||||||
|
if (m_sDBUSState.sleepInhibitFd.isValid()) {
|
||||||
|
Debug::log(WARN, "Called inhibitSleep, but previous sleep inhibitor is still active!");
|
||||||
|
m_sDBUSState.sleepInhibitFd.reset();
|
||||||
|
}
|
||||||
|
|
||||||
auto method = m_sDBUSState.login->createMethodCall(sdbus::InterfaceName{"org.freedesktop.login1.Manager"}, sdbus::MethodName{"Inhibit"});
|
auto method = m_sDBUSState.login->createMethodCall(sdbus::InterfaceName{"org.freedesktop.login1.Manager"}, sdbus::MethodName{"Inhibit"});
|
||||||
method << "sleep";
|
method << "sleep";
|
||||||
method << "hypridle";
|
method << "hypridle";
|
||||||
|
@ -628,11 +594,18 @@ void CHypridle::inhibitSleep() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply >> m_sDBUSState.sleepInhibitFd;
|
sdbus::UnixFd fd;
|
||||||
Debug::log(TRACE, "Inhibited sleep with fd {}", m_sDBUSState.sleepInhibitFd.get());
|
// This calls dup on the fd, no F_DUPFD_CLOEXEC :(
|
||||||
} catch (const std::exception& e) { Debug::log(ERR, "Failed to inhibit sleep ({})", e.what()); }
|
// There seems to be no way to get the file descriptor out of the reply other than that.
|
||||||
|
reply >> fd;
|
||||||
|
|
||||||
Debug::log(LOG, "Inhibited sleep!");
|
// Setting the O_CLOEXEC flag does not work for some reason. Instead we make our own dupe and close the one from UnixFd.
|
||||||
|
auto immidiateFD = Hyprutils::OS::CFileDescriptor(fd.release());
|
||||||
|
m_sDBUSState.sleepInhibitFd = immidiateFD.duplicate(F_DUPFD_CLOEXEC);
|
||||||
|
immidiateFD.reset(); // close the fd that was opened with dup
|
||||||
|
|
||||||
|
Debug::log(LOG, "Inhibited sleep with fd {}", m_sDBUSState.sleepInhibitFd.get());
|
||||||
|
} catch (const std::exception& e) { Debug::log(ERR, "Failed to inhibit sleep ({})", e.what()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHypridle::uninhibitSleep() {
|
void CHypridle::uninhibitSleep() {
|
||||||
|
@ -642,5 +615,5 @@ void CHypridle::uninhibitSleep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Releasing the sleep inhibitor!");
|
Debug::log(LOG, "Releasing the sleep inhibitor!");
|
||||||
close(m_sDBUSState.sleepInhibitFd.release());
|
m_sDBUSState.sleepInhibitFd.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sdbus-c++/sdbus-c++.h>
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <hyprutils/os/FileDescriptor.hpp>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
#include "wayland.hpp"
|
#include "wayland.hpp"
|
||||||
|
@ -83,7 +84,7 @@ class CHypridle {
|
||||||
std::unique_ptr<sdbus::IProxy> login;
|
std::unique_ptr<sdbus::IProxy> login;
|
||||||
std::vector<std::unique_ptr<sdbus::IObject>> screenSaverObjects;
|
std::vector<std::unique_ptr<sdbus::IObject>> screenSaverObjects;
|
||||||
std::vector<SDbusInhibitCookie> inhibitCookies;
|
std::vector<SDbusInhibitCookie> inhibitCookies;
|
||||||
sdbus::UnixFd sleepInhibitFd;
|
Hyprutils::OS::CFileDescriptor sleepInhibitFd;
|
||||||
} m_sDBUSState;
|
} m_sDBUSState;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
Loading…
Reference in a new issue