fix workspace interactivity

This commit is contained in:
2025-12-17 22:45:30 +01:00
parent a912cb9687
commit 11ccd55a52
5 changed files with 125 additions and 176 deletions

View File

@@ -1,5 +1,7 @@
#include "widgets/workspaceIndicator.hpp"
#include "services/hyprland.hpp"
#include <cassert>
#include <gdk/gdk.h>
#include <gtkmm/gestureclick.h>
#include <gtkmm/widget.h>
@@ -16,6 +18,23 @@ WorkspaceIndicator::WorkspaceIndicator(HyprlandService &service, int monitorId)
monitorConnection = service.monitorStateChanged.connect(
sigc::mem_fun(*this, &WorkspaceIndicator::on_monitor_update));
for (int i = 1; i <= HyprlandService::kWorkspaceSlotCount; ++i) {
auto label = Gtk::make_managed<Gtk::Label>(std::to_string(i));
label->add_css_class("workspace-pill");
auto gesture = Gtk::GestureClick::create();
gesture->set_button(GDK_BUTTON_PRIMARY);
gesture->signal_released().connect(
[this, i, &service](int, double, double) {
service.switchToWorkspace(
i + this->monitorId * HyprlandService::kWorkspaceSlotCount);
});
label->add_controller(gesture);
workspaceLabels[i] = label;
append(*label);
}
rebuild();
}
@@ -29,53 +48,42 @@ WorkspaceIndicator::~WorkspaceIndicator() {
}
}
void WorkspaceIndicator::on_workspace_update(int monitorId) {
if (this->monitorId != monitorId && monitorId != -1) {
return;
}
void WorkspaceIndicator::on_workspace_update() {
rebuild();
}
void WorkspaceIndicator::on_monitor_update() { rebuild(); }
void WorkspaceIndicator::refreshLabel(Gtk::Label *label, HyprlandService::WorkspaceState state) {
label->remove_css_class("workspace-pill-active");
label->remove_css_class("workspace-pill-focused");
label->remove_css_class("workspace-pill-urgent");
auto gesture = Gtk::GestureClick::create();
gesture->set_button(GDK_BUTTON_PRIMARY);
gesture->signal_released().connect(
[this, state](int, double, double) {
service.switchToWorkspace(state.hyprId);
});
label->add_controller(gesture);
if (state.urgentWindows.size() > 0) {
label->add_css_class("workspace-pill-urgent");
} else {
if (state.focused) {
label->add_css_class("workspace-pill-focused");
} else if (state.active) {
label->add_css_class("workspace-pill-active");
}
}
}
void WorkspaceIndicator::rebuild() {
HyprlandService hypr = this->service;
int i = 0;
for (auto &[id, workspaceState] : hypr.getAllWorkspaces()) {
if (workspaceState.monitorId != this->monitorId) {
continue;
}
HyprlandService::Monitor *mon = service.getMonitorById(this->monitorId);
auto label = Gtk::make_managed<Gtk::Label>(workspaceState.label);
label->add_css_class("workspace-pill");
auto gesture = Gtk::GestureClick::create();
gesture->set_button(GDK_BUTTON_PRIMARY);
gesture->signal_released().connect(
[this, id](int, double, double) { service.switchToWorkspace(id); });
label->add_controller(gesture);
if (workspaceState.urgentWindows.empty()) {
if (workspaceState.focused) {
label->add_css_class("workspace-pill-focused");
} else if (workspaceState.active) {
label->add_css_class("workspace-pill-active");
}
} else {
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;
for (auto [id, workspaceState] : mon->workspaceStates) {
assert(id > 0);
Gtk::Label *label = workspaceLabels[id];
this->refreshLabel(label, *workspaceState);
}
}