Skip to content

Commit

Permalink
Merge pull request #2278 from Anakael/pr/anakael/hyprland-workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexays committed Jul 4, 2023
2 parents c91c8bb + f26a125 commit bb61461
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 20 deletions.
8 changes: 7 additions & 1 deletion include/modules/hyprland/workspaces.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <gtkmm/button.h>
#include <gtkmm/label.h>

#include <memory>

#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
Expand Down Expand Up @@ -44,12 +46,16 @@ class Workspaces : public AModule, public EventHandler {
private:
void onEvent(const std::string&) override;
void sort_workspaces();
void create_workspace(int id);
void remove_workspace(int id);

std::string format_;
std::map<std::string, std::string> icons_map_;
bool with_icon_;
int active_workspace_id;
std::vector<Workspace> workspaces_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
std::vector<int> workspaces_to_create_;
std::vector<int> workspaces_to_remove_;
std::mutex mutex_;
const Bar& bar_;
Gtk::Box box_;
Expand Down
2 changes: 1 addition & 1 deletion src/AModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
bool reverse_mouse = config_["reverse-mouse-scrolling"].asBool();

// ignore reverse-scrolling if event comes from a mouse wheel
GdkDevice* device = gdk_event_get_source_device((GdkEvent *)e);
GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e);
if (device != NULL && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
reverse = reverse_mouse;
}
Expand Down
66 changes: 48 additions & 18 deletions src/modules/hyprland/workspaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <algorithm>
#include <charconv>
#include <memory>
#include <string>

namespace waybar::modules::hyprland {
Expand Down Expand Up @@ -45,56 +46,83 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
}

auto Workspaces::update() -> void {
std::lock_guard<std::mutex> lock(mutex_);
for (Workspace &workspace : workspaces_) {
workspace.set_active(workspace.id() == active_workspace_id);
for (int &workspace_to_remove : workspaces_to_remove_) {
remove_workspace(workspace_to_remove);
}

workspaces_to_remove_.clear();

for (int &workspace_to_create : workspaces_to_create_) {
create_workspace(workspace_to_create);
}

workspaces_to_create_.clear();

for (std::unique_ptr<Workspace> &workspace : workspaces_) {
workspace->set_active(workspace->id() == active_workspace_id);

std::string &workspace_icon = icons_map_[""];
if (with_icon_) {
workspace_icon = workspace.select_icon(icons_map_);
workspace_icon = workspace->select_icon(icons_map_);
}

workspace.update(format_, workspace_icon);
workspace->update(format_, workspace_icon);
}

AModule::update();
}

void Workspaces::onEvent(const std::string &ev) {
std::lock_guard<std::mutex> lock(mutex_);
std::string eventName(begin(ev), begin(ev) + ev.find_first_of('>'));
std::string payload = ev.substr(eventName.size() + 2);
if (eventName == "workspace") {
std::from_chars(payload.data(), payload.data() + payload.size(), active_workspace_id);
} else if (eventName == "destroyworkspace") {
int deleted_workspace_id;
std::from_chars(payload.data(), payload.data() + payload.size(), deleted_workspace_id);
auto workspace = std::find_if(workspaces_.begin(), workspaces_.end(),
[&](Workspace &x) { return x.id() == deleted_workspace_id; });
box_.remove(workspace->button());
workspaces_.erase(workspace);
workspaces_to_remove_.push_back(deleted_workspace_id);
} else if (eventName == "createworkspace") {
int new_workspace_id;
std::from_chars(payload.data(), payload.data() + payload.size(), new_workspace_id);
workspaces_.push_back(new_workspace_id);
Gtk::Button &new_workspace_button = workspaces_.back().button();
box_.pack_end(new_workspace_button, false, false);
sort_workspaces();
new_workspace_button.show_all();
workspaces_to_create_.push_back(new_workspace_id);
}

dp.emit();
}

void Workspaces::create_workspace(int id) {
workspaces_.push_back(std::make_unique<Workspace>(id));
Gtk::Button &new_workspace_button = workspaces_.back()->button();
box_.pack_start(new_workspace_button, false, false);
sort_workspaces();
new_workspace_button.show_all();
}

void Workspaces::remove_workspace(int id) {
auto workspace = std::find_if(workspaces_.begin(), workspaces_.end(),
[&](std::unique_ptr<Workspace> &x) { return x->id() == id; });

if (workspace == workspaces_.end()) {
spdlog::warn("Can't find workspace with id {}", workspace->get()->id());
return;
}

box_.remove(workspace->get()->button());
workspaces_.erase(workspace);
}

void Workspaces::init() {
const auto activeWorkspace = WorkspaceDto::parse(gIPC->getSocket1JsonReply("activeworkspace"));
active_workspace_id = activeWorkspace.id;
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
for (const Json::Value &workspace_json : workspaces_json) {
workspaces_.push_back(Workspace(WorkspaceDto::parse(workspace_json)));
workspaces_.push_back(
std::make_unique<Workspace>(Workspace(WorkspaceDto::parse(workspace_json))));
}

for (auto &workspace : workspaces_) {
box_.pack_start(workspace.button(), false, false);
box_.pack_start(workspace->button(), false, false);
}

sort_workspaces();
Expand Down Expand Up @@ -139,10 +167,12 @@ void Workspace::update(const std::string &format, const std::string &icon) {

void Workspaces::sort_workspaces() {
std::sort(workspaces_.begin(), workspaces_.end(),
[](Workspace &lhs, Workspace &rhs) { return lhs.id() < rhs.id(); });
[](std::unique_ptr<Workspace> &lhs, std::unique_ptr<Workspace> &rhs) {
return lhs->id() < rhs->id();
});

for (size_t i = 0; i < workspaces_.size(); ++i) {
box_.reorder_child(workspaces_[i].button(), i);
box_.reorder_child(workspaces_[i]->button(), i);
}
}

Expand Down

0 comments on commit bb61461

Please sign in to comment.