#pragma once #include #include #include #include #include #include class HyprlandService { public: static constexpr int kWorkspaceSlotCount = 5; struct WorkspaceState { int id = -1; int hyprId = -1; bool active = false; bool focused = false; bool urgent = false; std::string label; }; struct Monitor { std::map workspaceStates; std::string name; int x = 0; int y = 0; int id = -1; int focusedWorkspaceId = -1; }; HyprlandService(); ~HyprlandService(); void start(); void on_hyprland_event(std::string event, std::string data); void printMonitor(const Monitor &mon) const; sigc::signal socketEventSignal; sigc::signal workspaceStateChanged; sigc::signal monitorStateChanged; Monitor *getMonitorById(int id); const Monitor *getMonitorById(int id) const; Monitor *getMonitorByIndex(std::size_t index); const Monitor *getMonitorByIndex(std::size_t index) const; // Switch to a workspace slot on a given monitor. If the workspace has an // associated Hyprland workspace id (hyprId >= 0) that id will be used. // Otherwise the slot and monitor name will be used to request creation // / activation via `hyprctl`. void switchToWorkspace(int workspaceId); private: int fd = -1; std::string buffer; std::map monitors; bool on_socket_read(Glib::IOCondition condition); void parse_message(const std::string &line); std::string get_socket_path(); void refresh_monitors(); void refresh_workspaces(); void handle_urgent_window(std::string windowAddress); }; inline void HyprlandService::printMonitor(const Monitor &mon) const { std::cout << "=== Monitor Info ===\n"; std::cout << "Name: " << mon.name << " (ID: " << mon.id << ")\n"; std::cout << "Position: (" << mon.x << ", " << mon.y << ")\n"; std::cout << "Focused Workspace ID: " << mon.focusedWorkspaceId << "\n"; std::cout << "Workspaces:\n"; if (mon.workspaceStates.empty()) { std::cout << " (None)\n"; } else { for (int slot = 1; slot <= HyprlandService::kWorkspaceSlotCount; ++slot) { const auto it = mon.workspaceStates.find(slot); if (it == mon.workspaceStates.end()) { std::cout << " - [Slot: " << slot << " | HyprID: n/a]" << " Label: | Active: No | Focused: No | " "Urgent: No\n"; continue; } const WorkspaceState &ws = it->second; std::cout << " - [Slot: " << ws.id << " | HyprID: " << (ws.hyprId >= 0 ? std::to_string(ws.hyprId) : std::string("n/a")) << "] " << "Label: " << (ws.label.empty() ? "" : ws.label) << " | " << "Active: " << (ws.active ? "Yes" : "No") << " | " << "Focused: " << (ws.focused ? "Yes" : "No") << " | " << "Urgent: " << (ws.urgent ? "Yes" : "No") << "\n"; } } std::cout << "====================\n"; }