Skip to content

Commit

Permalink
fixez
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Jul 19, 2024
1 parent c788a59 commit 518213b
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 143 deletions.
69 changes: 57 additions & 12 deletions src/Hyprpaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <fstream>
#include <signal.h>
#include <sys/types.h>
#include <sys/poll.h>
#include "render/Egl.hpp"

#include "protocols/wayland.hpp"
Expand All @@ -21,15 +22,11 @@ static void handleGlobal(CCWlRegistry* registry, uint32_t name, const char* inte
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
g_pHyprpaper->m_pSHM = makeShared<CCWlShm>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_shm_interface, 1));
} else if (strcmp(interface, wl_output_interface.name) == 0) {
g_pHyprpaper->m_mtTickMutex.lock();

const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
PMONITOR->wayland_name = name;
PMONITOR->name = "";
PMONITOR->output = makeShared<CCWlOutput>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_output_interface, 4));
PMONITOR->registerListeners();

g_pHyprpaper->m_mtTickMutex.unlock();
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
g_pHyprpaper->createSeat(makeShared<CCWlSeat>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_seat_interface, 1)));
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
Expand Down Expand Up @@ -124,18 +121,66 @@ void CHyprpaper::init() {
if (std::any_cast<Hyprlang::INT>(g_pConfigManager->config->getConfigValue("ipc")))
g_pIPCSocket->initialize();

do {
std::lock_guard<std::mutex> lg(m_mtTickMutex);
tick(true);
} while (wl_display_dispatch(m_sDisplay) != -1);
pollfd pollFDs[] = {
{
.fd = wl_display_get_fd(m_sDisplay),
.events = POLLIN,
},
{
.fd = g_pIPCSocket->fd,
.events = POLLIN,
},
};

tick(true);

while (1) {
int ret = poll(pollFDs, 2, 5000 /* 5 seconds, reasonable. Just in case we need to terminate and the signal fails */);

if (ret < 0) {
if (errno == EINTR)
continue;

Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
exit(1);
}

for (size_t i = 0; i < 2; ++i) {
if (pollFDs[i].revents & POLLHUP) {
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
exit(1);
}
}

if (ret != 0) {
if (pollFDs[0].revents & POLLIN) { // wayland
wl_display_flush(m_sDisplay);
if (wl_display_prepare_read(m_sDisplay) == 0) {
wl_display_read_events(m_sDisplay);
wl_display_dispatch_pending(m_sDisplay);
} else
wl_display_dispatch(m_sDisplay);
}

if (pollFDs[1].revents & POLLIN) { // socket
if (g_pIPCSocket->parseRequest())
tick(true);
}

// finalize wayland dispatching. Dispatch pending on the queue
int ret2 = 0;
do {
ret2 = wl_display_dispatch_pending(m_sDisplay);
wl_display_flush(m_sDisplay);
} while (ret2 > 0);
}
}

unlockSingleInstance();
}

void CHyprpaper::tick(bool force) {
bool reload = g_pIPCSocket && g_pIPCSocket->mainThreadParseRequest();

if (!reload && !force)
if (!force)
return;

preloadAllWallpapersFromConfig();
Expand Down Expand Up @@ -388,7 +433,7 @@ void CHyprpaper::ensureMonitorHasActiveWallpaper(SMonitor* pMonitor) {
}

void CHyprpaper::createLSForMonitor(SMonitor* pMonitor) {
pMonitor->pCurrentLayerSurface = pMonitor->layerSurfaces.emplace_back(std::make_unique<CLayerSurface>(pMonitor)).get();
pMonitor->pCurrentLayerSurface = pMonitor->layerSurfaces.emplace_back(makeShared<CLayerSurface>(pMonitor));
}

bool CHyprpaper::lockSingleInstance() {
Expand Down
2 changes: 0 additions & 2 deletions src/Hyprpaper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ class CHyprpaper {
bool lockSingleInstance(); // fails on multi-instance
void unlockSingleInstance();

std::mutex m_mtTickMutex;

SMonitor* m_pLastMonitor = nullptr;

private:
Expand Down
1 change: 0 additions & 1 deletion src/helpers/Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ void SMonitor::registerListeners() {

output->setDone([this](CCWlOutput* r) {
readyForLS = true;
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
if (g_pConfigManager) // don't tick if this is the first roundtrip
g_pHyprpaper->tick(true);
});
Expand Down
32 changes: 16 additions & 16 deletions src/helpers/Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@
class CCWlOutput;

struct SMonitor {
std::string name = "";
std::string description = "";
SP<CCWlOutput> output;
uint32_t wayland_name = 0;
Vector2D size;
int scale;
std::string name = "";
std::string description = "";
SP<CCWlOutput> output;
uint32_t wayland_name = 0;
Vector2D size;
int scale;

bool readyForLS = false;
bool hasATarget = true;
bool readyForLS = false;
bool hasATarget = true;

bool wildcard = true;
bool wildcard = true;

uint32_t configureSerial = 0;
uint32_t configureSerial = 0;

bool wantsReload = false;
bool wantsACK = false;
bool initialized = false;
bool wantsReload = false;
bool wantsACK = false;
bool initialized = false;

std::vector<std::unique_ptr<CLayerSurface>> layerSurfaces;
CLayerSurface* pCurrentLayerSurface = nullptr;
std::vector<SP<CLayerSurface>> layerSurfaces;
SP<CLayerSurface> pCurrentLayerSurface = nullptr;

void registerListeners();
void registerListeners();
};
173 changes: 76 additions & 97 deletions src/ipc/Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,155 +15,134 @@
#include <thread>

void CIPCSocket::initialize() {
std::thread([&]() {
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
fd = socket(AF_UNIX, SOCK_STREAM, 0);

if (SOCKET < 0) {
Debug::log(ERR, "Couldn't start the hyprpaper Socket. (1) IPC will not work.");
return;
}

sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};

const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR");
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
if (fd < 0) {
Debug::log(ERR, "Couldn't start the hyprpaper Socket. (1) IPC will not work.");
return;
}

const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/";
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};

std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock";
const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR");
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);

if (!HISenv)
mkdir(USERDIR.c_str(), S_IRWXU);
const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/";

unlink(socketPath.c_str());
std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock";

strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
if (!HISenv)
mkdir(USERDIR.c_str(), S_IRWXU);

bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
unlink(socketPath.c_str());

// 10 max queued.
listen(SOCKET, 10);
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());

sockaddr_in clientAddress = {};
socklen_t clientSize = sizeof(clientAddress);
if (bind(fd, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) {
Debug::log(ERR, "Couldn't bind the hyprpaper Socket. IPC will not work.");
fd = -1;
return;
}

char readBuffer[1024] = {0};
// 10 max queued.
listen(fd, 10);

Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), SOCKET);
while (1) {
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
if (ACCEPTEDCONNECTION < 0) {
Debug::log(ERR, "Couldn't listen on the hyprpaper Socket. (3) IPC will not work.");
break;
} else {
do {
Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION);
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);

auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
if (messageSize == 0)
break;
std::string request(readBuffer);

m_szRequest = request;
m_bRequestReady = true;

g_pHyprpaper->tick(true);
while (!m_bReplyReady) { // wait for Hyprpaper to finish processing the request
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
write(ACCEPTEDCONNECTION, m_szReply.c_str(), m_szReply.length());
m_bReplyReady = false;
m_szReply = "";

} while (1);
Debug::log(LOG, "Closing Accepted Connection");
close(ACCEPTEDCONNECTION);
}
}
Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), fd);
}

close(SOCKET);
}).detach();
CIPCSocket::~CIPCSocket() {
if (fd >= 0)
close(fd);
}

bool CIPCSocket::mainThreadParseRequest() {
bool CIPCSocket::parseRequest() {
sockaddr_in clientAddress = {};
socklen_t clientSize = sizeof(clientAddress);

char readBuffer[1024] = {0};

if (!m_bRequestReady)
const auto ACCEPTEDCONNECTION = accept(fd, (sockaddr*)&clientAddress, &clientSize);
if (ACCEPTEDCONNECTION < 0) {
Debug::log(ERR, "Couldn't listen on the hyprpaper Socket. (3)");
return false;
} else {

Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION);
std::string body = "";
do {
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
body += std::string{readBuffer, messageSize};
if (messageSize < 1024)
break;
} while (1);

std::string copy = m_szRequest;
auto reply = processRequest(body);
write(ACCEPTEDCONNECTION, reply.c_str(), reply.length());

if (copy == "")
return false;
Debug::log(LOG, "Closing Accepted Connection");
close(ACCEPTEDCONNECTION);
}

return true;
}

// now we can work on the copy
std::string CIPCSocket::processRequest(const std::string& body) {

Debug::log(LOG, "Received a request: %s", copy.c_str());
std::string reply = "ok";

// set default reply
m_szReply = "ok";
m_bReplyReady = true;
m_bRequestReady = false;
Debug::log(LOG, "Received a request: %s", body.c_str());

// config commands
if (copy.find("wallpaper") == 0 || copy.find("preload") == 0 || copy.find("unload") == 0 || copy.find("reload") == 0) {
if (body.find("wallpaper") == 0 || body.find("preload") == 0 || body.find("unload") == 0 || body.find("reload") == 0) {

const auto RESULT = g_pConfigManager->config->parseDynamic(copy.substr(0, copy.find_first_of(' ')).c_str(), copy.substr(copy.find_first_of(' ') + 1).c_str());
const auto RESULT = g_pConfigManager->config->parseDynamic(body.substr(0, body.find_first_of(' ')).c_str(), body.substr(body.find_first_of(' ') + 1).c_str());

if (RESULT.error) {
m_szReply = RESULT.getError();
return false;
}
if (RESULT.error)
reply = RESULT.getError();

return true;
return reply;
}

if (copy.find("listloaded") == 0) {
if (body.find("listloaded") == 0) {

const auto numWallpapersLoaded = g_pHyprpaper->m_mWallpaperTargets.size();
Debug::log(LOG, "numWallpapersLoaded: %d", numWallpapersLoaded);

if (numWallpapersLoaded == 0) {
m_szReply = "no wallpapers loaded";
return false;
}
if (numWallpapersLoaded == 0)
return "no wallpapers loaded";

m_szReply = "";
reply = "";
long unsigned int i = 0;
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
m_szReply += name;
reply += name;
i++;
if (i < numWallpapersLoaded)
m_szReply += '\n'; // dont add newline on last entry
reply += '\n'; // dont add newline on last entry
}

return true;
return reply;
}

if (copy.find("listactive") == 0) {
if (body.find("listactive") == 0) {

const auto numWallpapersActive = g_pHyprpaper->m_mMonitorActiveWallpapers.size();
Debug::log(LOG, "numWallpapersActive: %d", numWallpapersActive);

if (numWallpapersActive == 0) {
m_szReply = "no wallpapers active";
return false;
}
if (numWallpapersActive == 0)
return "no wallpapers active";

m_szReply = "";
reply = "";
long unsigned int i = 0;
for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) {
m_szReply += mon + " = " + path1;
reply += mon + " = " + path1;
i++;
if (i < numWallpapersActive)
m_szReply += '\n'; // dont add newline on last entry
reply += '\n'; // dont add newline on last entry
}

return true;
return reply;
}

m_szReply = "invalid command";
return false;
return "invalid command";
}
Loading

0 comments on commit 518213b

Please sign in to comment.