Skip to content

Commit

Permalink
core: allow signaling a parent that the screen was locked
Browse files Browse the repository at this point in the history
  • Loading branch information
dkondor committed Jan 3, 2025
1 parent 002e44f commit f8c2ae8
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
14 changes: 13 additions & 1 deletion src/core/hyprlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@

using namespace Hyprutils::OS;

CHyprlock::CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn) {
CHyprlock::CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn, const int notifyFd) {
m_iNotifyFd = notifyFd;

m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str());
if (!m_sWaylandState.display) {
Debug::log(CRIT, "Couldn't connect to a wayland compositor");
Expand Down Expand Up @@ -1013,6 +1015,16 @@ void CHyprlock::onLockLocked() {
Debug::log(LOG, "onLockLocked called");

m_bLocked = true;

if (m_iNotifyFd >= 0) {
const char ready = '\n';
while (true) {
if (write(m_iNotifyFd, &ready, 1) == 1 || errno != EINTR)
break;
}
close(m_iNotifyFd);
m_iNotifyFd = -1;
}
}

void CHyprlock::onLockFinished() {
Expand Down
4 changes: 3 additions & 1 deletion src/core/hyprlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct SDMABUFModifier {

class CHyprlock {
public:
CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn);
CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn, const int notifyFd);
~CHyprlock();

void run();
Expand Down Expand Up @@ -168,6 +168,8 @@ class CHyprlock {
std::vector<std::shared_ptr<CTimer>> m_vTimers;

std::vector<uint32_t> m_vPressedKeys;

int m_iNotifyFd;
};

inline std::unique_ptr<CHyprlock> g_pHyprlock;
55 changes: 54 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <cstddef>
#include <iostream>
#include <string_view>
#include <charconv>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

void help() {
std::cout << "Usage: hyprlock [options]\n\n"
Expand All @@ -16,6 +20,8 @@ void help() {
" --immediate - Lock immediately, ignoring any configured grace period\n"
" --immediate-render - Do not wait for resources before drawing the background\n"
" --no-fade-in - Disable the fade-in animation when the lock screen appears\n"
" -R, --ready-fd FD - Write a single newline character to this file descriptor after locking the screen\n"
" -D, --daemonize - Run hyprlock in the background. This command will return after the screen has been locked\n"
" -V, --version - Show version information\n"
" -h, --help - Show this help message\n";
}
Expand All @@ -35,6 +41,8 @@ int main(int argc, char** argv, char** envp) {
bool immediate = false;
bool immediateRender = false;
bool noFadeIn = false;
bool daemonize = false;
int notifyFd = -1;

std::vector<std::string> args(argv, argv + argc);

Expand Down Expand Up @@ -83,13 +91,58 @@ int main(int argc, char** argv, char** envp) {
else if (arg == "--no-fade-in")
noFadeIn = true;

else if (arg == "--ready-fd" || arg == "-R") {
if (auto value = parseArg(args, arg, i); value) {
auto [ptr, ec] = std::from_chars(value->data(), value->data() + value->size(), notifyFd);
if (ptr != value->data() + value->size() || notifyFd < 0)
return 1;
} else
return 1;
}

else if (arg == "--daemonize" || arg == "-D")
daemonize = true;

else {
std::cerr << "Unknown option: " << arg << "\n";
help();
return 1;
}
}

if (daemonize) {
int pipe_fds[2];
if (pipe(pipe_fds) != 0) {
Debug::log(CRIT, "Cannot open pipe to child process\n");
return 1;
}

pid_t pid = fork();
if (pid < 0) {
Debug::log(CRIT, "Cannot create child process\n");
return 1;
}

if (pid > 0) {
close(pipe_fds[1]);

char tmp;
ssize_t n_read;
do {
// if the child exits without writing, read() will return zero
n_read = read(pipe_fds[0], &tmp, 1);
} while (n_read == -1 && errno == EINTR);

if (n_read == 1) return 0; // screen is now locked
return 1; // child failed to lock the screen
}

int flags = fcntl(pipe_fds[1], F_GETFD);
fcntl(pipe_fds[1], F_SETFD, flags | FD_CLOEXEC);
close(pipe_fds[0]);
notifyFd = pipe_fds[1];
}

try {
g_pConfigManager = std::make_unique<CConfigManager>(configPath);
g_pConfigManager->init();
Expand All @@ -102,7 +155,7 @@ int main(int argc, char** argv, char** envp) {
}

try {
g_pHyprlock = std::make_unique<CHyprlock>(wlDisplay, immediate, immediateRender, noFadeIn);
g_pHyprlock = std::make_unique<CHyprlock>(wlDisplay, immediate, immediateRender, noFadeIn, notifyFd);
g_pHyprlock->run();
} catch (const std::exception& ex) {
Debug::log(CRIT, "Hyprlock threw: {}", ex.what());
Expand Down

0 comments on commit f8c2ae8

Please sign in to comment.