Skip to content

Commit

Permalink
core: disallow multiple instances of hyprpaper at once
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed May 29, 2023
1 parent b82254e commit cd86c19
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/Hyprpaper.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
#include "Hyprpaper.hpp"
#include <filesystem>
#include <fstream>
#include <sys/types.h>
#include <signal.h>

CHyprpaper::CHyprpaper() = default;

void CHyprpaper::init() {

if (!lockSingleInstance()) {
Debug::log(CRIT, "Cannot launch multiple instances of Hyprpaper at once!");
exit(1);
}

removeOldHyprpaperImages();

g_pConfigManager = std::make_unique<CConfigManager>();
Expand All @@ -29,6 +38,8 @@ void CHyprpaper::init() {
std::lock_guard<std::mutex> lg(m_mtTickMutex);
tick(true);
}

unlockSingleInstance();
}

void CHyprpaper::tick(bool force) {
Expand Down Expand Up @@ -552,3 +563,38 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
}
}
}

bool CHyprpaper::lockSingleInstance() {
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");

const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";

if (std::filesystem::exists(LOCKFILE)) {
std::ifstream ifs(LOCKFILE);
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));

try {
kill(std::stoull(content), 0);

if (errno != ESRCH)
return false;
} catch (std::exception& e) {
;
}
}

// create lockfile
std::ofstream ofs(LOCKFILE, std::ios::trunc);

ofs << std::to_string(getpid());

ofs.close();

return true;
}

void CHyprpaper::unlockSingleInstance() {
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");
const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";
unlink(LOCKFILE.c_str());
}
2 changes: 2 additions & 0 deletions src/Hyprpaper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class CHyprpaper {
SPoolBuffer* getPoolBuffer(SMonitor*, CWallpaperTarget*);
void unloadWallpaper(const std::string&);
void createSeat(wl_seat*);
bool lockSingleInstance(); // fails on multi-instance
void unlockSingleInstance();

std::mutex m_mtTickMutex;

Expand Down

0 comments on commit cd86c19

Please sign in to comment.