no compile errors, fully functional workspace indicators
This commit is contained in:
@@ -13,34 +13,38 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "helpers/hypr.hpp"
|
||||
#include "helpers/socket.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/button.h"
|
||||
|
||||
HyprlandService::HyprlandService() {
|
||||
auto monitorDataJson = HyprctlHelper::getMonitorData();
|
||||
init();
|
||||
bindSocket();
|
||||
}
|
||||
|
||||
void HyprlandService::init() {
|
||||
auto monitorDataJson = HyprctlHelper::getMonitorData();
|
||||
auto onClick = sigc::mem_fun(*this, &HyprlandService::switchToWorkspace);
|
||||
|
||||
for (const auto &item : monitorDataJson) {
|
||||
auto monitorPtr = std::make_shared<Monitor>();
|
||||
|
||||
int monitorId = item["id"].get<int>();
|
||||
std::string monitorName = item["name"].get<std::string>();
|
||||
int monitorId = item["id"].get<int>();
|
||||
|
||||
monitorPtr->id = monitorId;
|
||||
monitorPtr->name = item["name"].get<std::string>();
|
||||
this->monitors[monitorPtr->id] = monitorPtr;
|
||||
monitorPtr->name = monitorName;
|
||||
monitorPtr->activeWorkspaceId = item["activeWorkspace"]["id"].get<int>();
|
||||
monitorPtr->focused = item["focused"].get<bool>();
|
||||
this->monitors[monitorPtr->name] = monitorPtr;
|
||||
|
||||
// Create inidcators for hyprsplit
|
||||
for (int i = 1; i <= NUM_WORKSPACES; i++) {
|
||||
WorkspaceState state;
|
||||
int workspaceId = i + (NUM_WORKSPACES * monitorId);
|
||||
|
||||
state.id = workspaceId;
|
||||
state.monitorId = monitorId;
|
||||
|
||||
auto view = std::make_shared<WorkspaceIndicator>(std::to_string(i));
|
||||
std::shared_ptr<WorkspaceData> state = std::make_shared<WorkspaceData>();
|
||||
int workspaceId = i + (NUM_WORKSPACES * monitorId);
|
||||
|
||||
state->id = workspaceId;
|
||||
state->monitorName = monitorName;
|
||||
auto view = std::make_shared<WorkspaceIndicator>(workspaceId, std::to_string(i), onClick);
|
||||
auto workSpace = std::make_shared<Workspace>();
|
||||
workSpace->state = state;
|
||||
workSpace->view = view;
|
||||
@@ -50,30 +54,38 @@ HyprlandService::HyprlandService() {
|
||||
}
|
||||
}
|
||||
|
||||
auto clientsDataJson = HyprctlHelper::getClientData();
|
||||
|
||||
for (const auto &client : clientsDataJson) {
|
||||
auto clientPtr = std::make_shared<Client>();
|
||||
clientPtr->address = client["address"].get<std::string>();
|
||||
clientPtr->workspaceId = client["workspace"]["id"].get<int>();
|
||||
clientPtr->title = client["title"].get<std::string>();
|
||||
this->clients[clientPtr->address] = clientPtr;
|
||||
|
||||
auto workspacePtr = workspaces[clientPtr->workspaceId];
|
||||
workspacePtr->state->clients[clientPtr->address] = clientPtr;
|
||||
|
||||
if (client.contains("urgent") && client["urgent"].get<bool>()) {
|
||||
workspacePtr->state->urgentClients.insert(clientPtr->address);
|
||||
}
|
||||
}
|
||||
|
||||
auto workspaceDataJson = HyprctlHelper::getWorkspaceData();
|
||||
|
||||
for (const auto &workspace : workspaceDataJson) {
|
||||
auto workspacePtr = std::make_shared<Workspace>();
|
||||
workspacePtr->state.id = workspace["id"].get<int>();
|
||||
workspacePtr->state.monitorId = workspace["monitorID"].get<int>();
|
||||
workspaces[workspacePtr->state.id] = workspacePtr;
|
||||
auto workspacePtr = workspaces[workspace["id"].get<int>()];
|
||||
auto state = workspacePtr->state;
|
||||
|
||||
state->id = workspace["id"].get<int>();
|
||||
state->monitorName = workspace["monitor"].get<std::string>();
|
||||
|
||||
refreshIndicator(workspacePtr);
|
||||
}
|
||||
|
||||
bindSocket();
|
||||
}
|
||||
|
||||
void HyprlandService::init() {
|
||||
}
|
||||
|
||||
std::string HyprlandService::getSocketPath() {
|
||||
auto sig = std::string(std::getenv("HYPRLAND_INSTANCE_SIGNATURE"));
|
||||
auto runtime = std::string(std::getenv("XDG_RUNTIME_DIR"));
|
||||
|
||||
return std::string(runtime) + "/hypr/" + sig + "/.socket2.sock";
|
||||
}
|
||||
|
||||
void HyprlandService::bindSocket() {
|
||||
std::string socketPath = getSocketPath();
|
||||
std::string socketPath = HyprSocketHelper::getHyprlandSocketPath();
|
||||
|
||||
socketFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (socketFd == -1) {
|
||||
@@ -96,29 +108,220 @@ void HyprlandService::bindSocket() {
|
||||
|
||||
GSource *source = g_unix_fd_source_new(socketFd, static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR));
|
||||
|
||||
auto onSocketEvent = [](gint fd, GIOCondition condition, gpointer user_data) -> gboolean {
|
||||
auto onSocketEvent = [](gint fd, GIOCondition , gpointer user_data) -> gboolean {
|
||||
HyprlandService *self = static_cast<HyprlandService *>(user_data);
|
||||
auto messages = SocketHelper::parseSocketMessage(fd, ">>");
|
||||
|
||||
for (const auto &message : messages) {
|
||||
self->handleSocketMessage(message);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
};
|
||||
|
||||
g_source_set_callback(source, (GSourceFunc)(+onSocketEvent), this, nullptr);
|
||||
g_source_set_callback(source, reinterpret_cast<GSourceFunc>(reinterpret_cast<void*>(+onSocketEvent)), this, nullptr);
|
||||
g_source_attach(source, g_main_context_default());
|
||||
g_source_unref(source);
|
||||
}
|
||||
|
||||
std::shared_ptr<Gtk::Box> HyprlandService::getWorkspaceIndicatorsForMonitor(int monitorId) {
|
||||
auto box = std::make_shared<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
|
||||
void HyprlandService::onWorkspaceChanged(int workspaceId) {
|
||||
auto newActive = workspaces[workspaceId];
|
||||
auto state = newActive->state;
|
||||
auto monitorPtr = monitors[state->monitorName];
|
||||
|
||||
auto monitor = monitors[monitorId];
|
||||
int oldActiveWorkspaceId = monitorPtr->activeWorkspaceId;
|
||||
auto oldActive = workspaces[oldActiveWorkspaceId];
|
||||
|
||||
int i = 0;
|
||||
for (const auto &[wsId, wsPair] : monitor->monitorWorkspaces) {
|
||||
box->append((Gtk::Box &)*wsPair->view);
|
||||
i++;
|
||||
monitorPtr->activeWorkspaceId = workspaceId;
|
||||
|
||||
refreshIndicator(newActive);
|
||||
refreshIndicator(oldActive);
|
||||
}
|
||||
|
||||
void HyprlandService::onFocusedMonitorChanged(std::string monitorData) {
|
||||
std::string monitorName = StringHelper::split(monitorData, ',')[0];
|
||||
|
||||
for (const auto &[_, monitorPtr] : monitors) {
|
||||
std::string itMonitorName = monitorPtr->name;
|
||||
|
||||
if (itMonitorName == monitorName) {
|
||||
monitorPtr->focused = true;
|
||||
|
||||
int activeWorkspaceId = monitorPtr->activeWorkspaceId;
|
||||
auto activeWorkspace = workspaces[activeWorkspaceId];
|
||||
refreshIndicator(activeWorkspace);
|
||||
} else {
|
||||
monitorPtr->focused = false;
|
||||
|
||||
int activeWorkspaceId = monitorPtr->activeWorkspaceId;
|
||||
auto activeWorkspace = workspaces[activeWorkspaceId];
|
||||
refreshIndicator(activeWorkspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HyprlandService::onMonitorRemoved(std::string monitorName) {
|
||||
auto monitorPtr = this->monitors[monitorName];
|
||||
|
||||
for (const auto &[wsId, wsPtr] : monitorPtr->monitorWorkspaces) {
|
||||
this->workspaces.erase(wsId);
|
||||
}
|
||||
|
||||
monitorPtr->monitorWorkspaces.clear();
|
||||
monitorPtr->bar->close();
|
||||
|
||||
this->monitors.erase(monitorName);
|
||||
}
|
||||
|
||||
// void HyprlandService::onMonitorAdded(std::string monitorName) {
|
||||
// // this->signalMonitorAdded.emit();
|
||||
// }
|
||||
|
||||
|
||||
void HyprlandService::onOpenWindow(std::string windowData) {
|
||||
auto parts = StringHelper::split(windowData, ',');
|
||||
std::string addr = "0x" + parts[0];
|
||||
int workspaceId = std::stoi(parts[1]);
|
||||
std::string title = parts[2];
|
||||
|
||||
auto clientPtr = std::make_shared<Client>();
|
||||
clientPtr->address = addr;
|
||||
clientPtr->workspaceId = workspaceId;
|
||||
clientPtr->title = title;
|
||||
this->clients[clientPtr->address] = clientPtr;
|
||||
auto workspacePtr = workspaces[clientPtr->workspaceId];
|
||||
workspacePtr->state->clients[clientPtr->address] = clientPtr;
|
||||
|
||||
refreshIndicator(workspacePtr);
|
||||
}
|
||||
|
||||
void HyprlandService::onCloseWindow(std::string windowData) {
|
||||
auto parts = StringHelper::split(windowData, ',');
|
||||
std::string addr = "0x" + parts[0];
|
||||
|
||||
if (this->clients.find(addr) == this->clients.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clientPtr = this->clients[addr];
|
||||
int workspaceId = clientPtr->workspaceId;
|
||||
|
||||
auto workspacePtr = workspaces[workspaceId];
|
||||
workspacePtr->state->clients.erase(addr);
|
||||
this->clients.erase(addr);
|
||||
|
||||
refreshIndicator(workspacePtr);
|
||||
}
|
||||
|
||||
void HyprlandService::handleSocketMessage(SocketHelper::SocketMessage message) {
|
||||
if (socketEventTypeMap.find(message.eventType) == socketEventTypeMap.end()) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SocketEventType eventType = socketEventTypeMap[message.eventType];
|
||||
std::string eventData = message.eventData;
|
||||
|
||||
switch (eventType) {
|
||||
case FOCUSED_MONITOR: {
|
||||
onFocusedMonitorChanged(eventData);
|
||||
break;
|
||||
}
|
||||
case WORKSPACE_CHANGED: {
|
||||
this->onWorkspaceChanged(std::stoi(eventData));
|
||||
break;
|
||||
}
|
||||
case OPEN_WINDOW: {
|
||||
this->onOpenWindow(eventData);
|
||||
break;
|
||||
}
|
||||
case CLOSE_WINDOW: {
|
||||
this->onCloseWindow(eventData);
|
||||
break;
|
||||
}
|
||||
case URGENT: {
|
||||
this->onUrgent(eventData);
|
||||
break;
|
||||
}
|
||||
case ACTIVE_WINDOW: {
|
||||
this->onActiveWindowChanged(eventData);
|
||||
break;
|
||||
}
|
||||
case MONITOR_REMOVED: {
|
||||
this->onMonitorRemoved(eventData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void HyprlandService::onUrgent(std::string windowAddress) {
|
||||
std::string addr = "0x" + windowAddress;
|
||||
if (this->clients.find(addr) == this->clients.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clientPtr = this->clients[addr];
|
||||
int workspaceId = clientPtr->workspaceId;
|
||||
|
||||
auto workspacePtr = workspaces[workspaceId];
|
||||
workspacePtr->state->urgentClients.insert(addr);
|
||||
|
||||
refreshIndicator(workspacePtr);
|
||||
}
|
||||
|
||||
void HyprlandService::onActiveWindowChanged(std::string windowAddress) {
|
||||
std::string addr = "0x" + windowAddress;
|
||||
if (this->clients.find(addr) == this->clients.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clientPtr = this->clients[addr];
|
||||
int workspaceId = clientPtr->workspaceId;
|
||||
|
||||
auto workspacePtr = workspaces[workspaceId];
|
||||
workspacePtr->state->urgentClients.erase(addr);
|
||||
|
||||
refreshIndicator(workspacePtr);
|
||||
}
|
||||
|
||||
std::shared_ptr<Gtk::Box> HyprlandService::getWorkspaceIndicatorsForMonitor(std::string monitorName) {
|
||||
auto box = std::make_shared<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
|
||||
auto monitor = monitors[monitorName];
|
||||
|
||||
for (const auto &[wsId, wsPair] : monitor->monitorWorkspaces) {
|
||||
box->append((Gtk::Box &)*wsPair->view);
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
void HyprlandService::switchToWorkspace(int workspaceId) {
|
||||
HyprctlHelper::dispatchWorkspace(workspaceId);
|
||||
}
|
||||
|
||||
void HyprlandService::refreshIndicator(std::shared_ptr<Workspace> workspace) {
|
||||
auto view = workspace->view;
|
||||
|
||||
auto state = workspace->state;
|
||||
auto monitorsPtr = monitors[state->monitorName];
|
||||
|
||||
bool isUrgent = !state->urgentClients.empty();
|
||||
bool isEmpty = state->clients.empty();
|
||||
bool isPreseneting = state->id == monitorsPtr->activeWorkspaceId;
|
||||
bool isFocused = monitorsPtr->focused && isPreseneting;
|
||||
|
||||
if (isUrgent) {
|
||||
view->setIndicatorState(WorkspaceIndicator::URGENT);
|
||||
} else if (isFocused) {
|
||||
view->setIndicatorState(WorkspaceIndicator::FOCUSED);
|
||||
} else if (isPreseneting) {
|
||||
view->setIndicatorState(WorkspaceIndicator::PRESENTING);
|
||||
} else if (!isEmpty) {
|
||||
view->setIndicatorState(WorkspaceIndicator::ALIVE);
|
||||
} else {
|
||||
view->setIndicatorState(WorkspaceIndicator::EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
void HyprlandService::addBar(std::shared_ptr<Bar> bar, std::string monitorName) {
|
||||
this->monitors[monitorName]->bar = bar;
|
||||
}
|
||||
Reference in New Issue
Block a user