diff --git a/include/helpers/systemHelper.hpp b/include/helpers/systemHelper.hpp new file mode 100644 index 0000000..0900846 --- /dev/null +++ b/include/helpers/systemHelper.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +class SystemHelper +{ + public: + static std::string get_command_output(const char *cmd) + { + std::array buffer; + std::string result; + std::unique_ptr 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; + } +}; diff --git a/include/services/hyprland.hpp b/include/services/hyprland.hpp index ff7f0e6..274778a 100644 --- a/include/services/hyprland.hpp +++ b/include/services/hyprland.hpp @@ -1,11 +1,30 @@ #pragma once #include +#include #include #include class HyprlandService { + typedef struct WorkspaceState + { + int id; + bool active; + bool focused; + bool urgent; + } WorkspaceState; + + typedef struct Monitor + { + std::map workspaceStates; + std::string name; + int x; + int y; + int id; + int focusedWorkspaceId; + } Monitor; + public: HyprlandService(); ~HyprlandService(); @@ -18,6 +37,7 @@ class HyprlandService private: int m_fd = -1; std::string m_buffer; + std::map monitors; bool on_socket_read(Glib::IOCondition condition); void parse_message(const std::string &line); diff --git a/src/services/hyprland.cpp b/src/services/hyprland.cpp index 6e3a0fc..b112213 100644 --- a/src/services/hyprland.cpp +++ b/src/services/hyprland.cpp @@ -3,10 +3,15 @@ #include #include #include +#include +#include +#include #include #include #include +#include "helpers/systemHelper.hpp" + HyprlandService::HyprlandService() {} HyprlandService::~HyprlandService() @@ -19,21 +24,13 @@ HyprlandService::~HyprlandService() void HyprlandService::on_hyprland_event(std::string event, std::string data) { - if (event == "workspace") - { - 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; - } + + // std::cout << event << " " << data << std::endl; } void HyprlandService::start() { + // setup socket std::string socket_path = get_socket_path(); if (socket_path.empty()) { @@ -66,6 +63,58 @@ void HyprlandService::start() sigc::mem_fun(*this, &HyprlandService::on_socket_read), m_fd, 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) @@ -89,7 +138,7 @@ bool HyprlandService::on_socket_read(Glib::IOCondition condition) m_buffer.append(buffer); size_t pos = 0; - + while ((pos = m_buffer.find('\n')) != std::string::npos) { std::string line = m_buffer.substr(0, pos);