split program into multiple files

This commit is contained in:
willifan 2024-11-13 18:00:42 +01:00
parent 89bbb229b8
commit 5b3527e9ce
39 changed files with 3897 additions and 261 deletions

266
src/clients.cpp Normal file
View file

@ -0,0 +1,266 @@
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <nlohmann/json.hpp>
#include "clients.hpp"
using json = nlohmann::json;
json workspacesOutput;
std::map<std::string, std::string> iconMap;
std::map<int, std::string> monitorMap;
std::map<std::string, int> specialWorkspaceMap = {{"special:ctrl", 0},
{"special:alt", 1},
{"special:altgr", 2},
{"special:strg", 3}};
/*json workspacesOutput = json::parse(R"(
[
"normal":
{
"activeOn": str
"icon": str
"id": int
"occupied": int
},
"special":
{
"activeOn": str
"icon": str
"id": str
"occupied": int
}
]
)");*/
std::string command(std::string inputCommand) {
const char *command = inputCommand.c_str();
char buffer[128];
std::string result;
FILE *pipe = popen(command, "r");
if (!pipe) {
std::cerr << "No pipe opened" << std::endl;
return "";
}
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL) {
result += buffer;
}
}
pclose(pipe);
return result;
}
void generateIconMap() {
json clients = json::parse(command("hyprctl clients -j"));
for (const json &client : clients) {
std::string pid = std::to_string(static_cast<int>(client["pid"]));
if (pid == "-1") {
continue;
}
std::string initClass = client["initialClass"];
if (initClass == "") {
initClass = "aguiienagi";
}
// TODO unjank
std::string cmd = "cd /home/willifan/.config/eww/scripts/ && ./test.sh ";
std::string test =
std::string("cd /home/willifan/.config/desktop-utils/ewwScripts && "
"./test.sh ") +
initClass + " " + pid;
std::cout << test << std::endl;
iconMap[client["address"]] = command(test);
}
return;
}
void generateMonitorMap() {
json monitorsInput = json::parse(command("hyprctl monitors -j"));
monitorMap.clear();
for (const json &monitor : monitorsInput) {
monitorMap[monitor["activeWorkspace"]["id"]] =
std::to_string(static_cast<int>(monitor["id"]));
}
}
json getWorkspace(json workspaceInput) {
json workspaceOutput;
if (workspaceInput["id"] > 0) // normal workspace
{
workspaceOutput["id"] = workspaceInput["id"];
} else // special workspace
{
workspaceOutput["id"] = workspaceInput["name"];
}
workspaceOutput["activeOn"] = monitorMap[workspaceInput["id"]];
workspaceOutput["occupied"] = workspaceInput["windows"];
if (!(workspaceInput["lastwindow"] == "0x0")) // workspace not empty
{
workspaceOutput["icon"] = iconMap[workspaceInput["lastwindow"]];
} else // workspace empty
{
workspaceOutput["icon"] = "";
}
return workspaceOutput;
}
// TODO fix special workspaces
void getAllWorkspaces() {
json workspacesInput = json::parse(command("hyprctl workspaces -j"));
int specialIndex = 4; // next index after specialWorkspaceMap
for (const auto &workspace : workspacesInput) {
if (workspace["id"] >= 1 && workspace["id"] <= 9) {
int index = workspace["id"].get<int>() - 1;
workspacesOutput[index]["normal"].clear();
workspacesOutput[index]["normal"] = getWorkspace(workspace);
} else if (std::string(workspace["name"]).find("special:") == 0) {
std::string name = workspace["name"];
int currentIndex;
if (specialWorkspaceMap.contains(name)) {
currentIndex = specialWorkspaceMap[name];
} else {
currentIndex = specialIndex;
specialIndex++;
}
workspacesOutput[currentIndex]["special"].clear();
workspacesOutput[currentIndex]["special"] = getWorkspace(workspace);
}
}
return;
}
// TODO optimize whatever
void handle(std::string message) {
/*
Call generateMonitorMap when workspaces change their monitor
Call generateIconMap when clients are opened or closed
*/
if (message.find("workspacev2>>") ==
0) // emitted ONCE when switching to a workspace
{
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("moveworkspacev2>>") ==
0) // emitted when a workspace switches to another monitor, TWICE
// when swaping
{
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("openwindow>>") ==
0) // emitted ONCE when a new client is created
{
generateIconMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("closewindow>>") ==
0) // emitted ONCE when a client gets closed
{
generateIconMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("movewindowv2>>") ==
0) // emitted ONCE when a client changes its workspace
{
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("activewindow>>v2") ==
0) // emitted ONCE when focus changes to another client
{
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
}
}
int clients::clients() {
generateIconMap();
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
std::string socketPath =
std::string(std::getenv("XDG_RUNTIME_DIR")) + "/hypr/" +
std::string(std::getenv("HYPRLAND_INSTANCE_SIGNATURE")) +
"/.socket2.sock";
// Create a socket
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
std::cerr << "Error: Failed to create socket\n";
return 1;
}
// Define the address of the IPC socket
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
// Connect to the IPC socket
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
std::cerr << "Error: Failed to connect to IPC socket\n";
close(sockfd);
return 1;
}
// Receive and print messages from the IPC socket
char buffer[1024];
ssize_t bytes_received;
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) {
std::string message = std::string(buffer, bytes_received);
std::istringstream iss(message);
std::string messageLine;
while (std::getline(iss, messageLine)) {
handle(messageLine);
}
}
if (bytes_received == -1) {
std::cerr << "Error: Failed to receive message\n";
}
// Close the socket
close(sockfd);
return 0;
}

3
src/clients.hpp Normal file
View file

@ -0,0 +1,3 @@
namespace clients {
int clients();
}

View file

@ -1,264 +1,9 @@
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "clients.hpp"
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
json workspacesOutput;
std::map<std::string, std::string> iconMap;
std::map<int, std::string> monitorMap;
std::map<std::string, int> specialWorkspaceMap = {{"special:ctrl", 0},
{"special:alt", 1},
{"special:altgr", 2},
{"special:strg", 3}};
/*json workspacesOutput = json::parse(R"(
[
"normal":
{
"activeOn": str
"icon": str
"id": int
"occupied": int
},
"special":
{
"activeOn": str
"icon": str
"id": str
"occupied": int
}
]
)");*/
std::string command(std::string inputCommand) {
const char *command = inputCommand.c_str();
char buffer[128];
std::string result;
FILE *pipe = popen(command, "r");
if (!pipe) {
std::cerr << "No pipe opened" << std::endl;
return "";
}
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL) {
result += buffer;
}
}
pclose(pipe);
return result;
}
void generateIconMap() {
json clients = json::parse(command("hyprctl clients -j"));
for (const json &client : clients) {
std::string pid = std::to_string(static_cast<int>(client["pid"]));
if (pid == "-1") {
continue;
}
std::string initClass = client["initialClass"];
if (initClass == "") {
initClass = "aguiienagi";
}
// TODO unjank
std::string cmd = "cd /home/willifan/.config/eww/scripts/ && ./test.sh ";
std::string test =
std::string("cd /home/willifan/.config/desktop-utils/ewwScripts && "
"./test.sh ") +
initClass + " " + pid;
std::cout << test << std::endl;
iconMap[client["address"]] = command(test);
}
return;
}
void generateMonitorMap() {
json monitorsInput = json::parse(command("hyprctl monitors -j"));
monitorMap.clear();
for (const json &monitor : monitorsInput) {
monitorMap[monitor["activeWorkspace"]["id"]] =
std::to_string(static_cast<int>(monitor["id"]));
}
}
json getWorkspace(json workspaceInput) {
json workspaceOutput;
if (workspaceInput["id"] > 0) // normal workspace
{
workspaceOutput["id"] = workspaceInput["id"];
} else // special workspace
{
workspaceOutput["id"] = workspaceInput["name"];
}
workspaceOutput["activeOn"] = monitorMap[workspaceInput["id"]];
workspaceOutput["occupied"] = workspaceInput["windows"];
if (!(workspaceInput["lastwindow"] == "0x0")) // workspace not empty
{
workspaceOutput["icon"] = iconMap[workspaceInput["lastwindow"]];
} else // workspace empty
{
workspaceOutput["icon"] = "";
}
return workspaceOutput;
}
// TODO fix special workspaces
void getAllWorkspaces() {
json workspacesInput = json::parse(command("hyprctl workspaces -j"));
int specialIndex = 4; // next index after specialWorkspaceMap
for (const auto &workspace : workspacesInput) {
if (workspace["id"] >= 1 && workspace["id"] <= 9) {
int index = workspace["id"].get<int>() - 1;
workspacesOutput[index]["normal"].clear();
workspacesOutput[index]["normal"] = getWorkspace(workspace);
} else if (std::string(workspace["name"]).find("special:") == 0) {
std::string name = workspace["name"];
int currentIndex;
if (specialWorkspaceMap.contains(name)) {
currentIndex = specialWorkspaceMap[name];
} else {
currentIndex = specialIndex;
specialIndex++;
}
workspacesOutput[currentIndex]["special"].clear();
workspacesOutput[currentIndex]["special"] = getWorkspace(workspace);
}
}
return;
}
// TODO optimize whatever
void handle(std::string message) {
/*
Call generateMonitorMap when workspaces change their monitor
Call generateIconMap when clients are opened or closed
*/
if (message.find("workspacev2>>") ==
0) // emitted ONCE when switching to a workspace
{
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("moveworkspacev2>>") ==
0) // emitted when a workspace switches to another monitor, TWICE
// when swaping
{
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("openwindow>>") ==
0) // emitted ONCE when a new client is created
{
generateIconMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("closewindow>>") ==
0) // emitted ONCE when a client gets closed
{
generateIconMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("movewindowv2>>") ==
0) // emitted ONCE when a client changes its workspace
{
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
} else if (message.find("activewindow>>v2") ==
0) // emitted ONCE when focus changes to another client
{
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
}
}
int main(int argc, char const *argv[]) {
generateIconMap();
generateMonitorMap();
getAllWorkspaces();
std::cout << workspacesOutput << std::endl;
std::string socketPath =
std::string(std::getenv("XDG_RUNTIME_DIR")) + "/hypr/" +
std::string(std::getenv("HYPRLAND_INSTANCE_SIGNATURE")) +
"/.socket2.sock";
// Create a socket
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
std::cerr << "Error: Failed to create socket\n";
return 1;
}
// Define the address of the IPC socket
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
// Connect to the IPC socket
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
std::cerr << "Error: Failed to connect to IPC socket\n";
close(sockfd);
return 1;
}
// Receive and print messages from the IPC socket
char buffer[1024];
ssize_t bytes_received;
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) {
std::string message = std::string(buffer, bytes_received);
std::istringstream iss(message);
std::string messageLine;
while (std::getline(iss, messageLine)) {
handle(messageLine);
}
}
if (bytes_received == -1) {
std::cerr << "Error: Failed to receive message\n";
}
// Close the socket
close(sockfd);
return 0;
int main(int argc, char **argv) {
std::cout << "Hello, World!" << std::endl;
clients::clients();
}