fix(workspaces): avoid mutex block
This commit is contained in:
parent
171ecd53aa
commit
e77c155ede
|
@ -26,9 +26,11 @@ class Workspaces : public IModule {
|
||||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||||
std::string getIcon(const std::string&, const Json::Value&);
|
std::string getIcon(const std::string&, const Json::Value&);
|
||||||
bool handleScroll(GdkEventScroll*);
|
bool handleScroll(GdkEventScroll*);
|
||||||
const std::string getCycleWorkspace(uint8_t current, bool prev) const;
|
const std::string getCycleWorkspace(const Json::Value& workspaces, uint8_t current,
|
||||||
uint16_t getWorkspaceIndex(const std::string& name) const;
|
bool prev) const;
|
||||||
|
uint16_t getWorkspaceIndex(const Json::Value& workspaces, const std::string& name) const;
|
||||||
std::string trimWorkspaceName(std::string);
|
std::string trimWorkspaceName(std::string);
|
||||||
|
const Json::Value getWorkspaces();
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
const Json::Value& config_;
|
const Json::Value& config_;
|
||||||
|
|
|
@ -77,11 +77,11 @@ struct Ipc::ipc_response Ipc::recv(int fd) const {
|
||||||
|
|
||||||
while (total < ipc_header_size_) {
|
while (total < ipc_header_size_) {
|
||||||
auto res = ::recv(fd, header.data() + total, ipc_header_size_ - total, 0);
|
auto res = ::recv(fd, header.data() + total, ipc_header_size_ - total, 0);
|
||||||
if (res <= 0) {
|
if (fd_event_ == -1 || fd_ == -1) {
|
||||||
if (res <= 0 && (fd_event_ == -1 || fd_ == -1)) {
|
|
||||||
// IPC is closed so just return an empty response
|
// IPC is closed so just return an empty response
|
||||||
return {0, 0, ""};
|
return {0, 0, ""};
|
||||||
}
|
}
|
||||||
|
if (res <= 0) {
|
||||||
throw std::runtime_error("Unable to receive IPC header");
|
throw std::runtime_error("Unable to receive IPC header");
|
||||||
}
|
}
|
||||||
total += res;
|
total += res;
|
||||||
|
|
|
@ -25,10 +25,15 @@ void Workspaces::onCmd(const struct Ipc::ipc_response res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Json::Value Workspaces::getWorkspaces() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return workspaces_;
|
||||||
|
}
|
||||||
|
|
||||||
void Workspaces::worker() {
|
void Workspaces::worker() {
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
try {
|
try {
|
||||||
if (!workspaces_.empty()) {
|
if (!getWorkspaces().empty()) {
|
||||||
ipc_.handleEvent();
|
ipc_.handleEvent();
|
||||||
}
|
}
|
||||||
if (thread_.isRunning()) {
|
if (thread_.isRunning()) {
|
||||||
|
@ -42,12 +47,12 @@ void Workspaces::worker() {
|
||||||
|
|
||||||
auto Workspaces::update() -> void {
|
auto Workspaces::update() -> void {
|
||||||
bool needReorder = false;
|
bool needReorder = false;
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
auto workspaces = getWorkspaces();
|
||||||
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
||||||
auto ws = std::find_if(workspaces_.begin(), workspaces_.end(), [it](auto node) -> bool {
|
auto ws = std::find_if(workspaces.begin(), workspaces.end(), [it](auto node) -> bool {
|
||||||
return node["name"].asString() == it->first;
|
return node["name"].asString() == it->first;
|
||||||
});
|
});
|
||||||
if (ws == workspaces_.end() ||
|
if (ws == workspaces.end() ||
|
||||||
(!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output->name)) {
|
(!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output->name)) {
|
||||||
it = buttons_.erase(it);
|
it = buttons_.erase(it);
|
||||||
needReorder = true;
|
needReorder = true;
|
||||||
|
@ -55,7 +60,7 @@ auto Workspaces::update() -> void {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto const &node : workspaces_) {
|
for (auto const &node : workspaces) {
|
||||||
if (!config_["all-outputs"].asBool() && bar_.output->name != node["output"].asString()) {
|
if (!config_["all-outputs"].asBool() && bar_.output->name != node["output"].asString()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +86,7 @@ auto Workspaces::update() -> void {
|
||||||
button.get_style_context()->remove_class("urgent");
|
button.get_style_context()->remove_class("urgent");
|
||||||
}
|
}
|
||||||
if (needReorder) {
|
if (needReorder) {
|
||||||
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
box_.reorder_child(button, getWorkspaceIndex(workspaces, node["name"].asString()));
|
||||||
}
|
}
|
||||||
auto icon = getIcon(node["name"].asString(), node);
|
auto icon = getIcon(node["name"].asString(), node);
|
||||||
std::string output = icon;
|
std::string output = icon;
|
||||||
|
@ -132,7 +137,8 @@ void Workspaces::addWorkspace(const Json::Value &node) {
|
||||||
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||||
button.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
button.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||||
}
|
}
|
||||||
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
auto workspaces = getWorkspaces();
|
||||||
|
box_.reorder_child(button, getWorkspaceIndex(workspaces, node["name"].asString()));
|
||||||
if (node["focused"].asBool()) {
|
if (node["focused"].asBool()) {
|
||||||
button.get_style_context()->add_class("focused");
|
button.get_style_context()->add_class("focused");
|
||||||
}
|
}
|
||||||
|
@ -165,35 +171,35 @@ bool Workspaces::handleScroll(GdkEventScroll *e) {
|
||||||
if (scrolling_) {
|
if (scrolling_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
auto workspaces = getWorkspaces();
|
||||||
uint8_t idx;
|
uint8_t idx;
|
||||||
scrolling_ = true;
|
scrolling_ = true;
|
||||||
for (idx = 0; idx < workspaces_.size(); idx += 1) {
|
for (idx = 0; idx < workspaces.size(); idx += 1) {
|
||||||
if (workspaces_[idx]["focused"].asBool()) {
|
if (workspaces[idx]["focused"].asBool()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (idx == workspaces_.size()) {
|
if (idx == workspaces.size()) {
|
||||||
scrolling_ = false;
|
scrolling_ = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string name;
|
std::string name;
|
||||||
if (e->direction == GDK_SCROLL_UP) {
|
if (e->direction == GDK_SCROLL_UP) {
|
||||||
name = getCycleWorkspace(idx, true);
|
name = getCycleWorkspace(workspaces, idx, true);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_DOWN) {
|
if (e->direction == GDK_SCROLL_DOWN) {
|
||||||
name = getCycleWorkspace(idx, false);
|
name = getCycleWorkspace(workspaces, idx, false);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_SMOOTH) {
|
if (e->direction == GDK_SCROLL_SMOOTH) {
|
||||||
gdouble delta_x, delta_y;
|
gdouble delta_x, delta_y;
|
||||||
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, &delta_y);
|
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, &delta_y);
|
||||||
if (delta_y < 0) {
|
if (delta_y < 0) {
|
||||||
name = getCycleWorkspace(idx, true);
|
name = getCycleWorkspace(workspaces, idx, true);
|
||||||
} else if (delta_y > 0) {
|
} else if (delta_y > 0) {
|
||||||
name = getCycleWorkspace(idx, false);
|
name = getCycleWorkspace(workspaces, idx, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name.empty() || name == workspaces_[idx]["name"].asString()) {
|
if (name.empty() || name == workspaces[idx]["name"].asString()) {
|
||||||
scrolling_ = false;
|
scrolling_ = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -202,24 +208,25 @@ bool Workspaces::handleScroll(GdkEventScroll *e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string Workspaces::getCycleWorkspace(uint8_t focused_workspace, bool prev) const {
|
const std::string Workspaces::getCycleWorkspace(const Json::Value &workspaces,
|
||||||
|
uint8_t focused_workspace, bool prev) const {
|
||||||
auto inc = prev ? -1 : 1;
|
auto inc = prev ? -1 : 1;
|
||||||
int size = workspaces_.size();
|
int size = workspaces.size();
|
||||||
uint8_t idx = 0;
|
uint8_t idx = 0;
|
||||||
for (int i = focused_workspace; i < size && i >= 0; i += inc) {
|
for (int i = focused_workspace; i < size && i >= 0; i += inc) {
|
||||||
bool same_output = (workspaces_[i]["output"].asString() == bar_.output->name &&
|
bool same_output = (workspaces[i]["output"].asString() == bar_.output->name &&
|
||||||
!config_["all-outputs"].asBool()) ||
|
!config_["all-outputs"].asBool()) ||
|
||||||
config_["all-outputs"].asBool();
|
config_["all-outputs"].asBool();
|
||||||
bool same_name =
|
bool same_name =
|
||||||
workspaces_[i]["name"].asString() == workspaces_[focused_workspace]["name"].asString();
|
workspaces[i]["name"].asString() == workspaces[focused_workspace]["name"].asString();
|
||||||
if (same_output && !same_name) {
|
if (same_output && !same_name) {
|
||||||
return workspaces_[i]["name"].asString();
|
return workspaces[i]["name"].asString();
|
||||||
}
|
}
|
||||||
if (prev && i - 1 < 0) {
|
if (prev && i - 1 < 0) {
|
||||||
i = size;
|
i = size;
|
||||||
} else if (!prev && i + 1 >= size) {
|
} else if (!prev && i + 1 >= size) {
|
||||||
i = -1;
|
i = -1;
|
||||||
} else if (idx >= workspaces_.size()) {
|
} else if (idx >= workspaces.size()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
idx += 1;
|
idx += 1;
|
||||||
|
@ -227,9 +234,10 @@ const std::string Workspaces::getCycleWorkspace(uint8_t focused_workspace, bool
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Workspaces::getWorkspaceIndex(const std::string &name) const {
|
uint16_t Workspaces::getWorkspaceIndex(const Json::Value &workspaces,
|
||||||
|
const std::string &name) const {
|
||||||
uint16_t idx = 0;
|
uint16_t idx = 0;
|
||||||
for (const auto &workspace : workspaces_) {
|
for (const auto &workspace : workspaces) {
|
||||||
if (workspace["name"].asString() == name) {
|
if (workspace["name"].asString() == name) {
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +246,7 @@ uint16_t Workspaces::getWorkspaceIndex(const std::string &name) const {
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return workspaces_.size();
|
return workspaces.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Workspaces::trimWorkspaceName(std::string name) {
|
std::string Workspaces::trimWorkspaceName(std::string name) {
|
||||||
|
|
Loading…
Reference in New Issue