diff --git a/.clang-format b/.clang-format index 5ba963f..39f9642 100644 --- a/.clang-format +++ b/.clang-format @@ -1,22 +1 @@ -BasedOnStyle: LLVM IndentWidth: 4 -AlignConsecutiveAssignments: true -AlignEscapedNewlines: Left -AlignTrailingComments: Always -BreakBeforeBraces: Allman -ColumnLimit: 0 -MaxEmptyLinesToKeep: 1 -InsertNewlineAtEOF: true -BreakBeforeBinaryOperators: NonAssignment -BinPackArguments: false -PenaltyBreakBeforeFirstCallParameter: 1000 -ContinuationIndentWidth: 4 # Adjust the indent width for continuation lines - -IncludeCategories: - - Regex: '^(<.+>)$' - Priority: 1 - - Regex: '^"(.+\.hpp)"$' - Priority: 2 - - Regex: '.*' - Priority: 3 -IncludeBlocks: Regroup \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d8edd3..564e844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,8 @@ link_directories(${GTKMM_LIBRARY_DIRS} ${LAYERSHELL_LIBRARY_DIRS}) add_library(bar_lib) target_sources(bar_lib PUBLIC - src/bar.cpp + src/app.cpp + src/bar/bar.cpp src/widgets/clock.cpp src/services/hyprland.cpp ) diff --git a/include/app.hpp b/include/app.hpp new file mode 100644 index 0000000..7ebe347 --- /dev/null +++ b/include/app.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "bar/bar.hpp" +#include "glibmm/refptr.h" +#include "gtkmm/application.h" +#include "services/hyprland.hpp" + +class App { +public: + App(); + + int run(); +private: + Glib::RefPtr app; + std::vector bars; + HyprlandService hyprlandService; + + void setupServices(); +}; \ No newline at end of file diff --git a/include/bar.hpp b/include/bar/bar.hpp similarity index 80% rename from include/bar.hpp rename to include/bar/bar.hpp index 88cb8cb..31c6d8f 100644 --- a/include/bar.hpp +++ b/include/bar/bar.hpp @@ -9,11 +9,10 @@ class Bar : public Gtk::Window { public: - Bar(); + Bar(GdkMonitor* monitor, HyprlandService::Monitor* hyprlandMonitor); protected: Clock clock; - HyprlandService hyprland; Gtk::CenterBox main_box{}; void setup_ui(); diff --git a/include/services/hyprland.hpp b/include/services/hyprland.hpp index 90978c0..3b3fb03 100644 --- a/include/services/hyprland.hpp +++ b/include/services/hyprland.hpp @@ -1,23 +1,22 @@ #pragma once #include +#include +#include #include #include -#include -#include -class HyprlandService -{ - typedef struct WorkspaceState - { +class HyprlandService { + + public: + typedef struct WorkspaceState { int id; bool active; bool focused; bool urgent; } WorkspaceState; - typedef struct Monitor - { + typedef struct Monitor { std::map workspaceStates; std::string name; int x; @@ -26,7 +25,6 @@ class HyprlandService int focusedWorkspaceId; } Monitor; - public: HyprlandService(); ~HyprlandService(); @@ -36,17 +34,17 @@ class HyprlandService 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 (const auto& pair : mon.workspaceStates) { + for (const auto &pair : mon.workspaceStates) { const WorkspaceState ws = pair.second; std::cout << " - [ID: " << ws.id << "] " - << "Active: " << (ws.active ? "Yes" : "No") << " | " - << "Focused: " << (ws.focused ? "Yes" : "No") << " | " - << "Urgent: " << (ws.urgent ? "Yes" : "No") << "\n"; + << "Active: " << (ws.active ? "Yes" : "No") << " | " + << "Focused: " << (ws.focused ? "Yes" : "No") << " | " + << "Urgent: " << (ws.urgent ? "Yes" : "No") << "\n"; } } std::cout << "====================\n"; @@ -57,10 +55,12 @@ class HyprlandService void start(); void on_hyprland_event(std::string event, std::string data); + Monitor* getMonitorById(const int &name); + private: int m_fd = -1; std::string m_buffer; - std::map monitors; + std::map monitors; bool on_socket_read(Glib::IOCondition condition); void parse_message(const std::string &line); diff --git a/main.cpp b/main.cpp index c388e52..78f6555 100644 --- a/main.cpp +++ b/main.cpp @@ -1,8 +1,8 @@ -#include "bar.hpp" +#include "app.hpp" int main(int argc, char *argv[]) { - auto app = Gtk::Application::create("org.example.mybar"); + App app; - return app->make_window_and_run(argc, argv); + return app.run(); } diff --git a/src/app.cpp b/src/app.cpp new file mode 100644 index 0000000..a4dc765 --- /dev/null +++ b/src/app.cpp @@ -0,0 +1,47 @@ +#include "app.hpp" + +#include + +App::App() { + this->setupServices(); + + this->app = Gtk::Application::create("org.example.mybar"); + + app->signal_activate().connect([&]() { + auto display = Gdk::Display::get_default(); + auto monitors = display->get_monitors(); + + for (guint i = 0; i < monitors->get_n_items(); ++i) { + auto monitor = std::dynamic_pointer_cast( + monitors->get_object(i)); + if (monitor) { + auto hyprlanMonitor = this->hyprlandService.getMonitorById(i); + + auto bar = new Bar(monitor->gobj(), hyprlanMonitor); + this->hyprlandService.printMonitor(*hyprlanMonitor); // Debugging output + + bar->set_application(app); + bar->show(); + bars.push_back(bar); + } + } + }); + + app->signal_shutdown().connect([&]() { + for (auto bar : bars) { + delete bar; + } + bars.clear(); + }); +} + +void App::setupServices() { + this->hyprlandService.socketEventSignal.connect(sigc::mem_fun( + this->hyprlandService, &HyprlandService::on_hyprland_event)); + + this->hyprlandService.start(); +} + +int App::run() { + return this->app->run(); +} diff --git a/src/bar.cpp b/src/bar/bar.cpp similarity index 90% rename from src/bar.cpp rename to src/bar/bar.cpp index 17ed53a..cf71e93 100644 --- a/src/bar.cpp +++ b/src/bar/bar.cpp @@ -1,4 +1,4 @@ -#include "bar.hpp" +#include "bar/bar.hpp" #include #include @@ -9,10 +9,14 @@ #include "glibmm/main.h" #include "sigc++/functors/mem_fun.h" -Bar::Bar() +Bar::Bar(GdkMonitor* monitor, HyprlandService::Monitor* hyprlandMonitor) { gtk_layer_init_for_window(this->gobj()); + if (monitor) { + gtk_layer_set_monitor(this->gobj(), monitor); + } + gtk_layer_set_anchor(this->gobj(), GTK_LAYER_SHELL_EDGE_TOP, true); gtk_layer_set_anchor(this->gobj(), GTK_LAYER_SHELL_EDGE_LEFT, true); gtk_layer_set_anchor(this->gobj(), GTK_LAYER_SHELL_EDGE_RIGHT, true); @@ -31,11 +35,6 @@ Bar::Bar() this->clock, &Clock::onUpdate), 1000); - - hyprland.socketEventSignal.connect( - sigc::mem_fun(this->hyprland, &HyprlandService::on_hyprland_event)); - - hyprland.start(); } void Bar::setup_ui() diff --git a/src/services/hyprland.cpp b/src/services/hyprland.cpp index b4f86d6..3bda581 100644 --- a/src/services/hyprland.cpp +++ b/src/services/hyprland.cpp @@ -24,7 +24,6 @@ HyprlandService::~HyprlandService() void HyprlandService::on_hyprland_event(std::string event, std::string data) { - if (event == "workspacev2") { std::cout << event << " " << data << std::endl; @@ -75,15 +74,15 @@ void HyprlandService::start() { for (auto &monitorJson : monitorsJson) { - Monitor monitor; + Monitor* monitor = new Monitor(); - monitor.id = monitorJson["id"]; - monitor.name = monitorJson["name"]; - monitor.x = monitorJson["x"]; - monitor.y = monitorJson["y"]; - monitor.focusedWorkspaceId = monitorJson["activeWorkspace"]["id"]; + 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}); + this->monitors.insert({monitor->id, monitor}); } } @@ -99,7 +98,7 @@ void HyprlandService::start() tempState.urgent = false; tempState.id = i; - this->monitors[i / numWorkspaces].workspaceStates.insert({i % numWorkspaces, tempState}); + this->monitors[i / numWorkspaces]->workspaceStates.insert({i % numWorkspaces, tempState}); } std::string hyprctlWorkspacesOutput = SystemHelper::get_command_output("hyprctl workspaces -j"); @@ -111,9 +110,10 @@ void HyprlandService::start() { int currentId = workspaceJson["id"]; int monitorId = workspaceJson["monitorID"]; - WorkspaceState &workspaceState = this->monitors[monitorId].workspaceStates.at((currentId - 1) % numWorkspaces); + Monitor* monitor = this->monitors[monitorId]; + WorkspaceState &workspaceState = monitor->workspaceStates.at((currentId - 1) % numWorkspaces); - int focusedWorkspaceId = this->monitors[monitorId].focusedWorkspaceId; + int focusedWorkspaceId = monitor[monitorId].focusedWorkspaceId; workspaceState.focused = currentId == focusedWorkspaceId; workspaceState.active = true; } @@ -178,3 +178,16 @@ std::string HyprlandService::get_socket_path() return std::string(runtime) + "/hypr/" + sig + "/.socket2.sock"; } + + +HyprlandService::Monitor* HyprlandService::getMonitorById(const int &id) +{ + if (this->monitors.find(id) != this->monitors.end()) + { + return this->monitors.at(id); + } + else + { + throw std::runtime_error("Monitor with ID " + std::to_string(id) + " not found."); + } +} \ No newline at end of file