commit b0d173873c9a532c539a47ac5055f2f692a45b9d Author: Miskolczi Richárd Date: Tue Jun 10 14:09:56 2025 +0200 Adding files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc95448 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.cache/ +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b6dbe79 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.10.0) +project(hyprland-toggle-tiling VERSION 0.1.0 LANGUAGES C CXX) + +include(FetchContent) +FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz) +FetchContent_MakeAvailable(json) + +add_executable(htt main.cpp HyprlandService.cpp Workspace.cpp Client.cpp) +target_link_libraries(htt PRIVATE nlohmann_json::nlohmann_json) +target_include_directories(htt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Client.cpp b/Client.cpp new file mode 100644 index 0000000..50d8838 --- /dev/null +++ b/Client.cpp @@ -0,0 +1,31 @@ +#include "Client.h" + +void from_json(const json& j, WorkspaceSignature& ws) { + j.at("id").get_to(ws.id); + j.at("name").get_to(ws.name); +} + +void from_json(const json& j, Client& client) { + j.at("address").get_to(client.address); + j.at("mapped").get_to(client.mapped); + j.at("hidden").get_to(client.hidden); + j.at("size").get_to(client.size); + j.at("workspace").get_to(client.workspace); + j.at("floating").get_to(client.floating); + j.at("pseudo").get_to(client.pseudo); + j.at("monitor").get_to(client.monitor); + j.at("class").get_to(client.className); // Maps "class" JSON field to className + j.at("title").get_to(client.title); + j.at("initialClass").get_to(client.initialClass); + j.at("initialTitle").get_to(client.initialTitle); + j.at("pid").get_to(client.pid); + j.at("xwayland").get_to(client.xwayland); + j.at("pinned").get_to(client.pinned); + j.at("fullscreen").get_to(client.fullscreen); + j.at("fullscreenClient").get_to(client.fullscreenClient); + j.at("swallowing").get_to(client.swallowing); + j.at("focusHistoryID").get_to(client.focusHistory); + j.at("inhibitingIdle").get_to(client.inhibitingIdle); + j.at("xdgTag").get_to(client.xdgTag); + j.at("xdgDescription").get_to(client.xdgDescription); +} diff --git a/Client.h b/Client.h new file mode 100644 index 0000000..ba6fb0d --- /dev/null +++ b/Client.h @@ -0,0 +1,46 @@ +#ifndef CLIENT_H +#define CLIENT_H + +#include +#include +#include + +using json = nlohmann::json; + +struct WorkspaceSignature { + public: + int id; + std::string name; + + friend void from_json(const json& j, WorkspaceSignature& ws); +}; + +class Client { + public: + std::string address; + bool mapped; + bool hidden; + std::array size; + WorkspaceSignature workspace; + bool floating; + bool pseudo; + int monitor; + std::string className; + std::string title; + std::string initialClass; + std::string initialTitle; + int pid; + bool xwayland; + bool pinned; + int fullscreen; + int fullscreenClient; + std::string swallowing; + int focusHistory; + bool inhibitingIdle; + std::string xdgTag; + std::string xdgDescription; + + friend void from_json(const json& j, Client& client); +}; + +#endif diff --git a/HyprlandService.cpp b/HyprlandService.cpp new file mode 100644 index 0000000..822a697 --- /dev/null +++ b/HyprlandService.cpp @@ -0,0 +1,34 @@ +#include "HyprlandService.h" + +using json = nlohmann::json; + +std::string HyprlandService::exec(const std::string& command) { + char buffer[128]; + std::string result = ""; + + FILE* pipe = popen(command.c_str(), "r"); + if (!pipe) { + return "popen failed"; + } + + while (fgets(buffer, sizeof(buffer), pipe) != NULL) { + result += buffer; + } + + int status = pclose(pipe); + if (status == -1) { + return "Error closing pipe"; + } + + return result; +}; + +Workspace HyprlandService::getCurrentWorkspace() { + json j = json::parse(exec("/usr/bin/hyprctl activeworkspace -j")); + return j.get(); +}; + +std::list HyprlandService::getClients() { + json j = json::parse(exec("/usr/bin/hyprctl clients -j")); + return j.get>(); +}; diff --git a/HyprlandService.h b/HyprlandService.h new file mode 100644 index 0000000..fd7c1b9 --- /dev/null +++ b/HyprlandService.h @@ -0,0 +1,16 @@ +#ifndef HYPRLAND_SERVICE_H +#define HYPRLAND_SERVICE_H + +#include +#include +#include "Workspace.h" +#include "Client.h" +#include + +class HyprlandService { + public: + static Workspace getCurrentWorkspace(); + static std::list getClients(); + static std::string exec(const std::string& command); +}; +#endif diff --git a/Workspace.cpp b/Workspace.cpp new file mode 100644 index 0000000..828d399 --- /dev/null +++ b/Workspace.cpp @@ -0,0 +1,13 @@ +#include "Workspace.h" + +void from_json(const nlohmann::json &j, Workspace &w) { + j.at("id").get_to(w.id); + j.at("name").get_to(w.name); + j.at("monitor").get_to(w.monitor); + j.at("monitorID").get_to(w.monitorID); + j.at("windows").get_to(w.windows); + j.at("hasfullscreen").get_to(w.hasfullscreen); + j.at("lastwindow").get_to(w.lastwindow); + j.at("lastwindowtitle").get_to(w.lastwindowtitle); + j.at("ispersistent").get_to(w.ispersistent); +} diff --git a/Workspace.h b/Workspace.h new file mode 100644 index 0000000..4f5273f --- /dev/null +++ b/Workspace.h @@ -0,0 +1,23 @@ +#ifndef WORKSPACE_H +#define WORKSPACE_H +#include +#include + +using json = nlohmann::json; + +class Workspace { +public: + int id; + std::string name; + std::string monitor; + int monitorID; + int windows; + bool hasfullscreen; + std::string lastwindow; + std::string lastwindowtitle; + bool ispersistent; + + friend void from_json(const json& j, Workspace& workspace); +}; + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..94d524e --- /dev/null +++ b/main.cpp @@ -0,0 +1,44 @@ +#include +#include "HyprlandService.h" + +int main(int, char**){ + Workspace w = HyprlandService::getCurrentWorkspace(); + std::cout << w.id << std::endl; + std::cout << w.name << std::endl; + std::cout << w.monitor << std::endl; + std::cout << w.monitorID << std::endl; + std::cout << w.windows << std::endl; + std::cout << w.hasfullscreen << std::endl; + std::cout << w.lastwindow << std::endl; + std::cout << w.lastwindowtitle << std::endl; + std::cout << w.ispersistent; + + std::list clients = HyprlandService::getClients(); + for (const auto& c : clients) { + std::cout << "Client:" << std::endl; + std::cout << " address: " << c.address << std::endl; + std::cout << " mapped: " << c.mapped << std::endl; + std::cout << " hidden: " << c.hidden << std::endl; + std::cout << " size: [" << c.size[0] << ", " << c.size[1] << "]" << std::endl; + std::cout << " workspace.id: " << c.workspace.id << std::endl; + std::cout << " workspace.name: " << c.workspace.name << std::endl; + std::cout << " floating: " << c.floating << std::endl; + std::cout << " pseudo: " << c.pseudo << std::endl; + std::cout << " monitor: " << c.monitor << std::endl; + std::cout << " className: " << c.className << std::endl; + std::cout << " title: " << c.title << std::endl; + std::cout << " initialClass: " << c.initialClass << std::endl; + std::cout << " initialTitle: " << c.initialTitle << std::endl; + std::cout << " pid: " << c.pid << std::endl; + std::cout << " xwayland: " << c.xwayland << std::endl; + std::cout << " pinned: " << c.pinned << std::endl; + std::cout << " fullscreen: " << c.fullscreen << std::endl; + std::cout << " fullscreenClient: " << c.fullscreenClient << std::endl; + std::cout << " swallowing: " << c.swallowing << std::endl; + std::cout << " focusHistory: " << c.focusHistory << std::endl; + std::cout << " inhibitingIdle: " << c.inhibitingIdle << std::endl; + std::cout << " xdgTag: " << c.xdgTag << std::endl; + std::cout << " xdgDescription: " << c.xdgDescription << std::endl; + std::cout << std::endl; + } +}