deine cousine
This commit is contained in:
@@ -21,17 +21,25 @@ HyprlandService::~HyprlandService() {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
// free allocated workspace pointers
|
||||
for (auto &p : this->workspaces) {
|
||||
delete p.second;
|
||||
}
|
||||
this->workspaces.clear();
|
||||
this->monitors.clear();
|
||||
}
|
||||
|
||||
void HyprlandService::on_hyprland_event(std::string event, std::string data) {
|
||||
if (event == "monitoradded" || event == "monitorremoved") {
|
||||
refresh_monitors();
|
||||
}
|
||||
|
||||
|
||||
if (event == "urgent") {
|
||||
onUrgentEvent(data);
|
||||
}
|
||||
|
||||
if (event == "activewindowv2") {
|
||||
onActiveWindowEvent(data);
|
||||
}
|
||||
|
||||
if (event == "workspace" || event == "movewindow") {
|
||||
refresh_workspaces();
|
||||
}
|
||||
@@ -39,8 +47,8 @@ void HyprlandService::on_hyprland_event(std::string event, std::string data) {
|
||||
// use for
|
||||
// event == "focusedmon"
|
||||
|
||||
if (event == "activewindowv2") {
|
||||
onActiveWindowEvent(data);
|
||||
if (event == "monitoradded" || event == "monitorremoved") {
|
||||
refresh_monitors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,31 +89,38 @@ void HyprlandService::start() {
|
||||
}
|
||||
|
||||
bool HyprlandService::on_socket_read(Glib::IOCondition condition) {
|
||||
const auto error_mask =
|
||||
Glib::IOCondition::IO_HUP | Glib::IOCondition::IO_ERR;
|
||||
const auto error_mask = Glib::IOCondition::IO_HUP | Glib::IOCondition::IO_ERR;
|
||||
|
||||
if (static_cast<int>(condition & error_mask) != 0) {
|
||||
std::cerr << "[Hyprland] Socket disconnected." << std::endl;
|
||||
close(fd);
|
||||
fd = -1;
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
char temp_buffer[4096];
|
||||
const ssize_t bytes_read = read(fd, temp_buffer, sizeof(temp_buffer) - 1);
|
||||
const ssize_t bytes_read = read(fd, temp_buffer, sizeof(temp_buffer));
|
||||
|
||||
if (bytes_read > 0) {
|
||||
temp_buffer[bytes_read] = '\0';
|
||||
buffer.append(temp_buffer);
|
||||
|
||||
size_t pos = 0;
|
||||
|
||||
while ((pos = buffer.find('\n')) != std::string::npos) {
|
||||
const std::string line = buffer.substr(0, pos);
|
||||
parse_message(line);
|
||||
buffer.erase(0, pos + 1);
|
||||
if (bytes_read <= 0) {
|
||||
// peer closed or error
|
||||
std::cerr << "[Hyprland] Socket read returned " << bytes_read << std::endl;
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// append exactly bytes_read bytes (may contain embedded nulls)
|
||||
this->socket_buffer.append(temp_buffer, static_cast<size_t>(bytes_read));
|
||||
|
||||
size_t pos = 0;
|
||||
while ((pos = this->socket_buffer.find('\n')) != std::string::npos) {
|
||||
const std::string line = this->socket_buffer.substr(0, pos);
|
||||
parse_message(line);
|
||||
this->socket_buffer.erase(0, pos + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -134,8 +149,12 @@ std::string HyprlandService::get_socket_path() {
|
||||
}
|
||||
|
||||
void HyprlandService::refresh_monitors() {
|
||||
this->monitors.clear();
|
||||
// free any previously allocated WorkspaceState objects before rebuilding
|
||||
for (auto &p : this->workspaces) {
|
||||
delete p.second;
|
||||
}
|
||||
this->workspaces.clear();
|
||||
this->monitors.clear();
|
||||
|
||||
std::string output = SystemHelper::get_command_output(kMonitorCommand);
|
||||
auto monitorsJson = nlohmann::json::parse(output, nullptr, false);
|
||||
@@ -160,10 +179,12 @@ void HyprlandService::refresh_monitors() {
|
||||
wsState.label = std::to_string(slot);
|
||||
wsState.monitorId = monitor.id;
|
||||
|
||||
int id = slot + monitor.id * HyprlandService::kWorkspaceSlotCount;
|
||||
wsState.hyprId = id;
|
||||
this->workspaces[id] = new WorkspaceState(wsState);
|
||||
this->monitors[monitor.id].workspaceStates[slot] = this->workspaces[id];
|
||||
int id = slot + monitor.id * HyprlandService::kWorkspaceSlotCount;
|
||||
wsState.hyprId = id;
|
||||
this->workspaces[id] = new WorkspaceState(wsState);
|
||||
if (monitor.id >= 0) {
|
||||
this->monitors[monitor.id].workspaceStates[slot] = this->workspaces[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,17 +212,28 @@ void HyprlandService::refresh_workspaces() {
|
||||
const int monitorId = monitorJson.value("id", -1);
|
||||
const int focusedWorkspaceId = monitorJson["activeWorkspace"].value("id", -1);
|
||||
|
||||
auto monitor = this->monitors[monitorId];
|
||||
monitor.focusedWorkspaceId = focusedWorkspaceId;
|
||||
// write into the stored monitor (use reference)
|
||||
auto it = this->monitors.find(monitorId);
|
||||
if (it != this->monitors.end()) {
|
||||
it->second.focusedWorkspaceId = focusedWorkspaceId;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &workspaceJson : workspacesJson) {
|
||||
const int workspaceId = workspaceJson.value("id", -1);
|
||||
std::map<int, WorkspaceState *>::iterator workspaceStateIt = this->workspaces.find(workspaceId);
|
||||
WorkspaceState *workspaceState = workspaceStateIt->second;
|
||||
auto workspaceStateIt = this->workspaces.find(workspaceId);
|
||||
if (workspaceStateIt == this->workspaces.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
workspaceState->focused = monitors[workspaceState->monitorId].focusedWorkspaceId == workspaceId;
|
||||
workspaceState->active = true;
|
||||
WorkspaceState *workspaceState = workspaceStateIt->second;
|
||||
auto mit = this->monitors.find(workspaceState->monitorId);
|
||||
if (mit != this->monitors.end()) {
|
||||
workspaceState->focused = mit->second.focusedWorkspaceId == workspaceId;
|
||||
} else {
|
||||
workspaceState->focused = false;
|
||||
}
|
||||
workspaceState->active = true;
|
||||
}
|
||||
|
||||
workspaceStateChanged.emit();
|
||||
@@ -229,12 +261,16 @@ void HyprlandService::onUrgentEvent(std::string windowAddress) {
|
||||
if (addr == "0x" + windowAddress) {
|
||||
int workspaceId = clientJson["workspace"].value("id", -1);
|
||||
|
||||
WorkspaceState *ws = this->workspaces[workspaceId];
|
||||
auto it = this->workspaces.find(workspaceId);
|
||||
if (it != this->workspaces.end() && it->second) {
|
||||
|
||||
if (std::find(it->second->urgentWindows.begin(),
|
||||
it->second->urgentWindows.end(), windowAddress) ==
|
||||
it->second->urgentWindows.end()) {
|
||||
it->second->urgentWindows.push_back(windowAddress);
|
||||
workspaceStateChanged.emit();
|
||||
}
|
||||
|
||||
// todo: maybee better method of access
|
||||
if (ws) {
|
||||
ws->urgentWindows.push_back(windowAddress);
|
||||
workspaceStateChanged.emit();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -250,13 +286,13 @@ void HyprlandService::onActiveWindowEvent(std::string windowAddress) {
|
||||
const std::string addr = clientJson.value("address", "");
|
||||
|
||||
if (addr == "0x" + windowAddress) {
|
||||
int workspaceId = clientJson["workspace"]["id"];
|
||||
WorkspaceState *ws = this->workspaces[workspaceId];
|
||||
|
||||
if (ws) {
|
||||
auto it = std::find(ws->urgentWindows.begin(), ws->urgentWindows.end(), windowAddress);
|
||||
if (it != ws->urgentWindows.end()) {
|
||||
ws->urgentWindows.erase(it);
|
||||
int workspaceId = clientJson["workspace"]["id"];
|
||||
auto it = this->workspaces.find(workspaceId);
|
||||
if (it != this->workspaces.end() && it->second) {
|
||||
WorkspaceState *ws = it->second;
|
||||
auto uit = std::find(ws->urgentWindows.begin(), ws->urgentWindows.end(), windowAddress);
|
||||
if (uit != ws->urgentWindows.end()) {
|
||||
ws->urgentWindows.erase(uit);
|
||||
workspaceStateChanged.emit();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user