Waybar/src/modules/workspaces.cpp

105 lines
3.2 KiB
C++
Raw Normal View History

2018-08-08 21:54:58 +00:00
#include "modules/workspaces.hpp"
#include "ipc/client.hpp"
2018-08-09 10:05:48 +00:00
waybar::modules::Workspaces::Workspaces(Bar &bar)
2018-08-10 21:21:21 +00:00
: _bar(bar)
2018-08-08 21:54:58 +00:00
{
2018-08-10 21:21:21 +00:00
_box.get_style_context()->add_class("workspaces");
2018-08-13 12:05:13 +00:00
std::string socketPath = get_socketpath();
2018-08-13 19:23:43 +00:00
_ipcfd = ipc_open_socket(socketPath);
_ipcEventfd = ipc_open_socket(socketPath);
const char *subscribe = "[ \"workspace\" ]";
2018-08-13 12:05:13 +00:00
uint32_t len = strlen(subscribe);
2018-08-13 19:23:43 +00:00
ipc_single_command(_ipcEventfd, IPC_SUBSCRIBE, subscribe, &len);
2018-08-10 21:21:21 +00:00
_thread = [this] {
2018-08-13 19:23:43 +00:00
try {
if (_bar.outputName.empty()) {
// Wait for the name of the output
while (_bar.outputName.empty())
_thread.sleep_for(chrono::milliseconds(150));
} else
ipc_recv_response(_ipcEventfd);
uint32_t len = 0;
std::lock_guard<std::mutex> lock(_mutex);
auto str = ipc_single_command(_ipcfd, IPC_GET_WORKSPACES, nullptr, &len);
2018-08-13 19:23:43 +00:00
_workspaces = _getWorkspaces(str);
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Workspaces::update));
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
2018-08-09 18:22:01 +00:00
};
2018-08-08 21:54:58 +00:00
}
2018-08-09 10:05:48 +00:00
auto waybar::modules::Workspaces::update() -> void
2018-08-08 21:54:58 +00:00
{
2018-08-13 19:23:43 +00:00
std::lock_guard<std::mutex> lock(_mutex);
2018-08-10 16:02:12 +00:00
bool needReorder = false;
2018-08-08 21:54:58 +00:00
for (auto it = _buttons.begin(); it != _buttons.end(); ++it) {
2018-08-13 19:23:43 +00:00
auto ws = std::find_if(_workspaces.begin(), _workspaces.end(),
2018-08-08 21:54:58 +00:00
[it](auto node) -> bool { return node["num"].asInt() == it->first; });
2018-08-13 19:23:43 +00:00
if (ws == _workspaces.end()) {
2018-08-10 21:21:21 +00:00
it = _buttons.erase(it);
2018-08-10 16:02:12 +00:00
needReorder = true;
2018-08-08 21:54:58 +00:00
}
}
2018-08-13 19:23:43 +00:00
for (auto node : _workspaces) {
if (_bar.outputName != node["output"].asString())
continue;
2018-08-08 21:54:58 +00:00
auto it = _buttons.find(node["num"].asInt());
2018-08-13 19:23:43 +00:00
if (it == _buttons.end()) {
2018-08-08 21:54:58 +00:00
_addWorkspace(node);
2018-08-10 16:02:12 +00:00
needReorder = true;
2018-08-08 21:54:58 +00:00
} else {
2018-08-13 19:23:43 +00:00
auto &button = it->second;
2018-08-08 21:54:58 +00:00
bool isCurrent = node["focused"].asBool();
if (!isCurrent) {
2018-08-13 19:23:43 +00:00
button.get_style_context()->remove_class("current");
} else if (isCurrent) {
2018-08-13 19:23:43 +00:00
button.get_style_context()->add_class("current");
2018-08-08 21:54:58 +00:00
}
2018-08-10 16:02:12 +00:00
if (needReorder)
2018-08-13 19:23:43 +00:00
_box.reorder_child(button, node["num"].asInt() - 1);
button.show();
2018-08-08 21:54:58 +00:00
}
}
}
2018-08-09 10:05:48 +00:00
void waybar::modules::Workspaces::_addWorkspace(Json::Value node)
2018-08-08 21:54:58 +00:00
{
auto pair = _buttons.emplace(node["num"].asInt(), node["name"].asString());
auto &button = pair.first->second;
2018-08-10 21:21:21 +00:00
_box.pack_start(button, false, false, 0);
2018-08-08 21:54:58 +00:00
button.set_relief(Gtk::RELIEF_NONE);
button.signal_clicked().connect([this, pair] {
2018-08-11 00:09:39 +00:00
try {
std::lock_guard<std::mutex> lock(_mutex);
2018-08-11 00:09:39 +00:00
auto value = fmt::format("workspace \"{}\"", pair.first->first);
uint32_t size = value.size();
2018-08-13 19:23:43 +00:00
ipc_single_command(_ipcfd, IPC_COMMAND, value.c_str(), &size);
2018-08-11 00:09:39 +00:00
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
2018-08-08 21:54:58 +00:00
});
2018-08-10 21:21:21 +00:00
_box.reorder_child(button, node["num"].asInt() - 1);
2018-08-08 21:54:58 +00:00
if (node["focused"].asBool()) {
button.get_style_context()->add_class("current");
}
button.show();
}
2018-08-13 19:23:43 +00:00
Json::Value waybar::modules::Workspaces::_getWorkspaces(const std::string data)
2018-08-08 21:54:58 +00:00
{
2018-08-13 19:23:43 +00:00
Json::Value res;
2018-08-11 00:09:39 +00:00
try {
std::string err;
2018-08-13 19:23:43 +00:00
res = _parser.parse(data);
2018-08-11 00:09:39 +00:00
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
2018-08-08 21:54:58 +00:00
}
2018-08-13 19:23:43 +00:00
return res;
2018-08-08 21:54:58 +00:00
}
2018-08-09 10:05:48 +00:00
waybar::modules::Workspaces::operator Gtk::Widget &() {
2018-08-10 21:21:21 +00:00
return _box;
2018-08-08 21:54:58 +00:00
}