124 lines
3.7 KiB
C++
124 lines
3.7 KiB
C++
#include "services/hyprland.hpp"
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <glib-unix.h>
|
|
#include <glib.h>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <nlohmann/json.hpp>
|
|
#include <string>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <unistd.h>
|
|
|
|
#include "helpers/hypr.hpp"
|
|
#include "helpers/socket.hpp"
|
|
|
|
#include "gtkmm/box.h"
|
|
#include "gtkmm/button.h"
|
|
|
|
HyprlandService::HyprlandService() {
|
|
auto monitorDataJson = HyprctlHelper::getMonitorData();
|
|
|
|
|
|
for (const auto &item : monitorDataJson) {
|
|
auto monitorPtr = std::make_shared<Monitor>();
|
|
|
|
int monitorId = item["id"].get<int>();
|
|
|
|
monitorPtr->id = monitorId;
|
|
monitorPtr->name = item["name"].get<std::string>();
|
|
this->monitors[monitorPtr->id] = monitorPtr;
|
|
|
|
// Create inidcators for hyprsplit
|
|
for (int i = 1; i <= NUM_WORKSPACES; i++) {
|
|
WorkspaceState state;
|
|
int workspaceId = i + (NUM_WORKSPACES * monitorId);
|
|
|
|
state.id = workspaceId;
|
|
state.monitorId = monitorId;
|
|
|
|
auto view = std::make_shared<WorkspaceIndicator>(std::to_string(i));
|
|
|
|
auto workSpace = std::make_shared<Workspace>();
|
|
workSpace->state = state;
|
|
workSpace->view = view;
|
|
|
|
monitorPtr->monitorWorkspaces[workspaceId] = workSpace;
|
|
this->workspaces[workspaceId] = workSpace;
|
|
}
|
|
}
|
|
|
|
auto workspaceDataJson = HyprctlHelper::getWorkspaceData();
|
|
|
|
for (const auto &workspace : workspaceDataJson) {
|
|
auto workspacePtr = std::make_shared<Workspace>();
|
|
workspacePtr->state.id = workspace["id"].get<int>();
|
|
workspacePtr->state.monitorId = workspace["monitorID"].get<int>();
|
|
workspaces[workspacePtr->state.id] = workspacePtr;
|
|
}
|
|
|
|
bindSocket();
|
|
}
|
|
|
|
void HyprlandService::init() {
|
|
}
|
|
|
|
std::string HyprlandService::getSocketPath() {
|
|
auto sig = std::string(std::getenv("HYPRLAND_INSTANCE_SIGNATURE"));
|
|
auto runtime = std::string(std::getenv("XDG_RUNTIME_DIR"));
|
|
|
|
return std::string(runtime) + "/hypr/" + sig + "/.socket2.sock";
|
|
}
|
|
|
|
void HyprlandService::bindSocket() {
|
|
std::string socketPath = getSocketPath();
|
|
|
|
socketFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
if (socketFd == -1) {
|
|
std::cerr << "[Hyprland] Failed to create socket" << std::endl;
|
|
return;
|
|
}
|
|
|
|
struct sockaddr_un addr;
|
|
memset(&addr, 0, sizeof(addr));
|
|
addr.sun_family = AF_UNIX;
|
|
std::strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
|
|
|
|
if (connect(socketFd, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) == -1) {
|
|
std::cerr << "[Hyprland] Failed to connect to " << socketPath << std::endl;
|
|
close(socketFd);
|
|
socketFd = -1;
|
|
|
|
return;
|
|
}
|
|
|
|
GSource *source = g_unix_fd_source_new(socketFd, static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR));
|
|
|
|
auto onSocketEvent = [](gint fd, GIOCondition condition, gpointer user_data) -> gboolean {
|
|
HyprlandService *self = static_cast<HyprlandService *>(user_data);
|
|
auto messages = SocketHelper::parseSocketMessage(fd, ">>");
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
};
|
|
|
|
g_source_set_callback(source, (GSourceFunc)(+onSocketEvent), this, nullptr);
|
|
g_source_attach(source, g_main_context_default());
|
|
g_source_unref(source);
|
|
}
|
|
|
|
std::shared_ptr<Gtk::Box> HyprlandService::getWorkspaceIndicatorsForMonitor(int monitorId) {
|
|
auto box = std::make_shared<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
|
|
|
|
auto monitor = monitors[monitorId];
|
|
|
|
int i = 0;
|
|
for (const auto &[wsId, wsPair] : monitor->monitorWorkspaces) {
|
|
box->append((Gtk::Box &)*wsPair->view);
|
|
i++;
|
|
}
|
|
|
|
|
|
return box;
|
|
} |