add basic workspace parsing

This commit is contained in:
2025-12-09 17:07:01 +01:00
parent cd3a9e6503
commit fb64f542a9
3 changed files with 109 additions and 12 deletions

View File

@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <string>
class SystemHelper
{
public:
static std::string get_command_output(const char *cmd)
{
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, int (*)(FILE *)> pipe(popen(cmd, "r"), pclose);
if (!pipe)
{
throw std::runtime_error("popen() failed!");
}
// Read the output a chunk at a time until the stream ends
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
{
result += buffer.data();
}
return result;
}
};

View File

@@ -1,11 +1,30 @@
#pragma once #pragma once
#include <glibmm.h> #include <glibmm.h>
#include <map>
#include <sigc++/sigc++.h> #include <sigc++/sigc++.h>
#include <string> #include <string>
class HyprlandService class HyprlandService
{ {
typedef struct WorkspaceState
{
int id;
bool active;
bool focused;
bool urgent;
} WorkspaceState;
typedef struct Monitor
{
std::map<int, WorkspaceState> workspaceStates;
std::string name;
int x;
int y;
int id;
int focusedWorkspaceId;
} Monitor;
public: public:
HyprlandService(); HyprlandService();
~HyprlandService(); ~HyprlandService();
@@ -18,6 +37,7 @@ class HyprlandService
private: private:
int m_fd = -1; int m_fd = -1;
std::string m_buffer; std::string m_buffer;
std::map<int, Monitor> monitors;
bool on_socket_read(Glib::IOCondition condition); bool on_socket_read(Glib::IOCondition condition);
void parse_message(const std::string &line); void parse_message(const std::string &line);

View File

@@ -3,10 +3,15 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <nlohmann/json.hpp>
#include <ostream>
#include <string>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include "helpers/systemHelper.hpp"
HyprlandService::HyprlandService() {} HyprlandService::HyprlandService() {}
HyprlandService::~HyprlandService() HyprlandService::~HyprlandService()
@@ -19,21 +24,13 @@ HyprlandService::~HyprlandService()
void HyprlandService::on_hyprland_event(std::string event, std::string data) void HyprlandService::on_hyprland_event(std::string event, std::string data)
{ {
if (event == "workspace")
{ // std::cout << event << " " << data << std::endl;
std::cout << "Switched to workspace: " << data << std::endl;
// Update your UI here...
}
else if (event == "activewindow")
{
std::cout << "Active window changed" << std::endl;
} else {
std::cout << event << " " << data << std::endl;
}
} }
void HyprlandService::start() void HyprlandService::start()
{ {
// setup socket
std::string socket_path = get_socket_path(); std::string socket_path = get_socket_path();
if (socket_path.empty()) if (socket_path.empty())
{ {
@@ -66,6 +63,58 @@ void HyprlandService::start()
sigc::mem_fun(*this, &HyprlandService::on_socket_read), sigc::mem_fun(*this, &HyprlandService::on_socket_read),
m_fd, m_fd,
Glib::IOCondition::IO_IN | Glib::IOCondition::IO_HUP | Glib::IOCondition::IO_ERR); Glib::IOCondition::IO_IN | Glib::IOCondition::IO_HUP | Glib::IOCondition::IO_ERR);
// setup monitors
std::string hyprctlMonitorsOutput = SystemHelper::get_command_output("hyprctl monitors -j");
auto monitorsJson = nlohmann::json::parse(hyprctlMonitorsOutput);
if (monitorsJson.is_array())
{
for (auto &monitorJson : monitorsJson)
{
Monitor monitor;
monitor.id = monitorJson["id"];
monitor.name = monitorJson["name"];
monitor.x = monitorJson["x"];
monitor.y = monitorJson["y"];
monitor.focusedWorkspaceId = monitorJson["activeWorkspace"]["id"];
this->monitors.insert({monitor.id, monitor});
}
}
int numWorkspaces = 6;
int numMonitors = 2;
for (int i = 0; i < numWorkspaces * numMonitors; i++)
{
WorkspaceState tempState;
tempState.active = false;
tempState.focused = false;
tempState.urgent = false;
tempState.id = i;
this->monitors[i / numWorkspaces].workspaceStates.insert({i % numWorkspaces, tempState});
}
std::string hyprctlWorkspacesOutput = SystemHelper::get_command_output("hyprctl workspaces -j");
auto workspacesJson = nlohmann::json::parse(hyprctlWorkspacesOutput);
if (workspacesJson.is_array())
{
for (auto &workspaceJson : workspacesJson)
{
int currentId = workspaceJson["id"];
int monitorId = workspaceJson["monitorID"];
WorkspaceState &workspaceState = this->monitors[monitorId].workspaceStates.at((currentId - 1) % numWorkspaces);
int focusedWorkspaceId = this->monitors[monitorId].focusedWorkspaceId;
workspaceState.focused = currentId == focusedWorkspaceId;
workspaceState.active = true;
}
}
} }
bool HyprlandService::on_socket_read(Glib::IOCondition condition) bool HyprlandService::on_socket_read(Glib::IOCondition condition)