#include "widgets/workspaceIndicator.hpp" #include #include #include #include #include #include #include "services/hyprland.hpp" #include "gtkmm/box.h" #include "gtkmm/label.h" WorkspaceIndicator::WorkspaceIndicator(int monitorId) : Gtk::Box(Gtk::Orientation::HORIZONTAL), monitorId(monitorId) { set_margin_top(2); set_margin_bottom(2); workspaceConnection = service->workspaceStateChanged.connect( sigc::mem_fun(*this, &WorkspaceIndicator::on_workspace_update)); monitorConnection = service->monitorStateChanged.connect( sigc::mem_fun(*this, &WorkspaceIndicator::on_monitor_update)); for (int i = 1; i <= HyprlandService::kWorkspaceSlotCount; ++i) { auto overlay = Gtk::make_managed(); auto numLabel = Gtk::make_managed(std::to_string(i)); auto pillContainer = Gtk::make_managed(Gtk::Orientation::HORIZONTAL); auto gesture = Gtk::GestureClick::create(); gesture->set_button(GDK_BUTTON_PRIMARY); gesture->signal_released().connect([this, i](int, double, double) { this->service->switchToWorkspace( i + this->monitorId * HyprlandService::kWorkspaceSlotCount); }); workspaceGestures[i] = gesture; workspaceIndicators[i] = overlay; overlay->add_controller(gesture); overlay->add_css_class("workspace-pill"); if (i == 6 || i == 7) { auto indicator = Gtk::make_managed(i == 6 ? "🫱🏻" : "🫲🏻"); indicator->add_css_class(i == 6 ? "workspace-pill-six" : "workspace-pill-seven"); indicator->set_valign(Gtk::Align::END); overlay->set_child(*indicator); overlay->add_overlay(*numLabel); pillContainer->append(*overlay); } else { overlay->set_child(*numLabel); pillContainer->append(*overlay); } append(*pillContainer); } rebuild(); } WorkspaceIndicator::~WorkspaceIndicator() { if (workspaceConnection.connected()) { workspaceConnection.disconnect(); } if (monitorConnection.connected()) { monitorConnection.disconnect(); } } void WorkspaceIndicator::on_workspace_update() { rebuild(); } void WorkspaceIndicator::on_monitor_update() { rebuild(); } void WorkspaceIndicator::refreshLabel(Gtk::Overlay *overlay, const HyprlandService::WorkspaceState &state) { overlay->remove_css_class("workspace-pill-active"); overlay->remove_css_class("workspace-pill-focused"); overlay->remove_css_class("workspace-pill-urgent"); // controller created once in constructor and reused if (state.urgentWindows.size() > 0) { overlay->add_css_class("workspace-pill-urgent"); } else { if (state.focused) { overlay->add_css_class("workspace-pill-focused"); } else if (state.active) { overlay->add_css_class("workspace-pill-active"); } } } void WorkspaceIndicator::rebuild() { HyprlandService::Monitor *mon = service->getMonitorById(this->monitorId); for (auto [id, workspaceState] : mon->workspaceStates) { Gtk::Overlay *overlay = workspaceIndicators[id]; this->refreshLabel(overlay, *workspaceState); } }