add workspace indicators

This commit is contained in:
2025-12-09 22:53:29 +01:00
parent 25c73f67a7
commit d53dfa27f1
8 changed files with 501 additions and 132 deletions

View File

@@ -0,0 +1,114 @@
#include "widgets/workspaceIndicator.hpp"
#include <exception>
#include <gtkmm/widget.h>
#include <sigc++/functors/mem_fun.h>
WorkspaceIndicator::WorkspaceIndicator(HyprlandService &service, int monitorId)
: Gtk::Box(Gtk::Orientation::HORIZONTAL), m_service(service), m_monitorId(monitorId)
{
set_spacing(6);
set_margin_top(2);
set_margin_bottom(2);
m_workspaceConnection = m_service.workspaceStateChanged.connect(
sigc::mem_fun(*this, &WorkspaceIndicator::on_workspace_update));
m_monitorConnection = m_service.monitorStateChanged.connect(
sigc::mem_fun(*this, &WorkspaceIndicator::on_monitor_update));
rebuild();
}
WorkspaceIndicator::~WorkspaceIndicator()
{
if (m_workspaceConnection.connected())
{
m_workspaceConnection.disconnect();
}
if (m_monitorConnection.connected())
{
m_monitorConnection.disconnect();
}
}
void WorkspaceIndicator::on_workspace_update(int monitorId)
{
if (monitorId != m_monitorId && monitorId != -1)
{
return;
}
rebuild();
}
void WorkspaceIndicator::on_monitor_update()
{
rebuild();
}
void WorkspaceIndicator::rebuild()
{
clear_children();
HyprlandService::Monitor *monitor = nullptr;
try
{
monitor = m_service.getMonitorById(m_monitorId);
}
catch (const std::exception &)
{
return;
}
if (monitor == nullptr)
{
return;
}
for (int workspaceId = 1; workspaceId <= HyprlandService::kWorkspaceSlotCount; ++workspaceId)
{
const HyprlandService::WorkspaceState *state = nullptr;
auto it = monitor->workspaceStates.find(workspaceId);
if (it != monitor->workspaceStates.end())
{
state = &it->second;
}
const std::string display = (state && !state->label.empty()) ? state->label : std::to_string(workspaceId);
auto label = Gtk::make_managed<Gtk::Label>(display);
label->add_css_class("workspace-pill");
if (state != nullptr)
{
if (state->focused)
{
label->add_css_class("workspace-pill-focused");
}
else if (state->active)
{
label->add_css_class("workspace-pill-active");
}
if (state->urgent)
{
label->add_css_class("workspace-pill-urgent");
}
}
append(*label);
}
}
void WorkspaceIndicator::clear_children()
{
Gtk::Widget *child = get_first_child();
while (child != nullptr)
{
Gtk::Widget *next = child->get_next_sibling();
remove(*child);
child = next;
}
}