Merge pull request #2408 from zjeffer/hyprland/workspaces_active-only
Implement 'active_only' option and 'visible' class in hyprland/workspaces
This commit is contained in:
commit
80de22a159
|
@ -14,9 +14,11 @@
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
|
class Workspaces;
|
||||||
|
|
||||||
class Workspace {
|
class Workspace {
|
||||||
public:
|
public:
|
||||||
explicit Workspace(const Json::Value& workspace_data);
|
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager);
|
||||||
std::string& select_icon(std::map<std::string, std::string>& icons_map);
|
std::string& select_icon(std::map<std::string, std::string>& icons_map);
|
||||||
Gtk::Button& button() { return button_; };
|
Gtk::Button& button() { return button_; };
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ class Workspace {
|
||||||
bool active() const { return active_; };
|
bool active() const { return active_; };
|
||||||
bool is_special() const { return is_special_; };
|
bool is_special() const { return is_special_; };
|
||||||
bool is_persistent() const { return is_persistent_; };
|
bool is_persistent() const { return is_persistent_; };
|
||||||
|
bool is_visible() const { return is_visible_; };
|
||||||
bool is_empty() const { return windows_ == 0; };
|
bool is_empty() const { return windows_ == 0; };
|
||||||
bool is_urgent() const { return is_urgent_; };
|
bool is_urgent() const { return is_urgent_; };
|
||||||
|
|
||||||
|
@ -33,12 +36,15 @@ class Workspace {
|
||||||
void set_active(bool value = true) { active_ = value; };
|
void set_active(bool value = true) { active_ = value; };
|
||||||
void set_persistent(bool value = true) { is_persistent_ = value; };
|
void set_persistent(bool value = true) { is_persistent_ = value; };
|
||||||
void set_urgent(bool value = true) { is_urgent_ = value; };
|
void set_urgent(bool value = true) { is_urgent_ = value; };
|
||||||
|
void set_visible(bool value = true) { is_visible_ = value; };
|
||||||
void set_windows(uint value) { windows_ = value; };
|
void set_windows(uint value) { windows_ = value; };
|
||||||
void set_name(std::string value) { name_ = value; };
|
void set_name(std::string value) { name_ = value; };
|
||||||
|
|
||||||
void update(const std::string& format, const std::string& icon);
|
void update(const std::string& format, const std::string& icon);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Workspaces& workspace_manager_;
|
||||||
|
|
||||||
int id_;
|
int id_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string output_;
|
std::string output_;
|
||||||
|
@ -47,6 +53,7 @@ class Workspace {
|
||||||
bool is_special_ = false;
|
bool is_special_ = false;
|
||||||
bool is_persistent_ = false;
|
bool is_persistent_ = false;
|
||||||
bool is_urgent_ = false;
|
bool is_urgent_ = false;
|
||||||
|
bool is_visible_ = false;
|
||||||
|
|
||||||
Gtk::Button button_;
|
Gtk::Button button_;
|
||||||
Gtk::Box content_;
|
Gtk::Box content_;
|
||||||
|
@ -62,6 +69,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||||
|
|
||||||
auto all_outputs() const -> bool { return all_outputs_; }
|
auto all_outputs() const -> bool { return all_outputs_; }
|
||||||
auto show_special() const -> bool { return show_special_; }
|
auto show_special() const -> bool { return show_special_; }
|
||||||
|
auto active_only() const -> bool { return active_only_; }
|
||||||
|
|
||||||
auto get_bar_output() const -> std::string { return bar_.output->name; }
|
auto get_bar_output() const -> std::string { return bar_.output->name; }
|
||||||
|
|
||||||
|
@ -75,6 +83,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||||
|
|
||||||
bool all_outputs_ = false;
|
bool all_outputs_ = false;
|
||||||
bool show_special_ = false;
|
bool show_special_ = false;
|
||||||
|
bool active_only_ = false;
|
||||||
|
|
||||||
void fill_persistent_workspaces();
|
void fill_persistent_workspaces();
|
||||||
void create_persistent_workspaces();
|
void create_persistent_workspaces();
|
||||||
|
|
|
@ -24,13 +24,18 @@ Addressed by *hyprland/workspaces*
|
||||||
*show-special*: ++
|
*show-special*: ++
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
default: false ++
|
default: false ++
|
||||||
If set to true special workspaces will be shown.
|
If set to true, special workspaces will be shown.
|
||||||
|
|
||||||
*all-outputs*: ++
|
*all-outputs*: ++
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
default: false ++
|
default: false ++
|
||||||
If set to false workspaces group will be shown only in assigned output. Otherwise all workspace groups are shown.
|
If set to false workspaces group will be shown only in assigned output. Otherwise all workspace groups are shown.
|
||||||
|
|
||||||
|
*active-only*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: false ++
|
||||||
|
If set to true, only the active workspace will be shown.
|
||||||
|
|
||||||
# FORMAT REPLACEMENTS
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
*{id}*: id of workspace assigned by compositor
|
*{id}*: id of workspace assigned by compositor
|
||||||
|
@ -43,10 +48,11 @@ Addressed by *hyprland/workspaces*
|
||||||
|
|
||||||
Additional to workspace name matching, the following *format-icons* can be set.
|
Additional to workspace name matching, the following *format-icons* can be set.
|
||||||
|
|
||||||
- *default*: Will be shown, when no string match is found.
|
- *default*: Will be shown, when no string match is found and none of the below conditions have defined icons.
|
||||||
- *active*: Will be shown, when workspace is active
|
- *active*: Will be shown, when workspace is active
|
||||||
- *special*: Will be shown on non-active special workspaces
|
- *special*: Will be shown on non-active special workspaces
|
||||||
- *empty*: Will be shown on empty persistent workspaces
|
- *empty*: Will be shown on non-active, non-special empty persistent workspaces
|
||||||
|
- *visible*: Will be shown on workspaces that are visible but not active. For example: this is useful if you want your visible workspaces on other monitors to have the same look as active.
|
||||||
- *persistent*: Will be shown on non-empty persistent workspaces
|
- *persistent*: Will be shown on non-empty persistent workspaces
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
@ -95,6 +101,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
||||||
- *#workspaces button*
|
- *#workspaces button*
|
||||||
- *#workspaces button.active*
|
- *#workspaces button.active*
|
||||||
- *#workspaces button.empty*
|
- *#workspaces button.empty*
|
||||||
|
- *#workspaces button.visible*
|
||||||
- *#workspaces button.persistent*
|
- *#workspaces button.persistent*
|
||||||
- *#workspaces button.special*
|
- *#workspaces button.special*
|
||||||
- *#workspaces button.urgent*
|
- *#workspaces button.urgent*
|
||||||
|
|
|
@ -38,6 +38,11 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
|
||||||
show_special_ = config_show_special.asBool();
|
show_special_ = config_show_special.asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto config_active_only = config_["active-only"];
|
||||||
|
if (config_active_only.isBool()) {
|
||||||
|
active_only_ = config_active_only.asBool();
|
||||||
|
}
|
||||||
|
|
||||||
box_.set_name("workspaces");
|
box_.set_name("workspaces");
|
||||||
if (!id.empty()) {
|
if (!id.empty()) {
|
||||||
box_.get_style_context()->add_class(id);
|
box_.get_style_context()->add_class(id);
|
||||||
|
@ -75,11 +80,29 @@ auto Workspaces::update() -> void {
|
||||||
|
|
||||||
workspaces_to_create_.clear();
|
workspaces_to_create_.clear();
|
||||||
|
|
||||||
|
// get all active workspaces
|
||||||
|
auto monitors = gIPC->getSocket1JsonReply("monitors");
|
||||||
|
std::vector<std::string> visible_workspaces;
|
||||||
|
for (Json::Value &monitor : monitors) {
|
||||||
|
auto ws = monitor["activeWorkspace"];
|
||||||
|
if (ws.isObject() && (ws["name"].isString())) {
|
||||||
|
visible_workspaces.push_back(ws["name"].asString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &workspace : workspaces_) {
|
for (auto &workspace : workspaces_) {
|
||||||
|
// active
|
||||||
workspace->set_active(workspace->name() == active_workspace_name_);
|
workspace->set_active(workspace->name() == active_workspace_name_);
|
||||||
if (workspace->name() == active_workspace_name_ && workspace.get()->is_urgent()) {
|
// disable urgency if workspace is active
|
||||||
|
if (workspace->name() == active_workspace_name_ && workspace->is_urgent()) {
|
||||||
workspace->set_urgent(false);
|
workspace->set_urgent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// visible
|
||||||
|
workspace->set_visible(std::find(visible_workspaces.begin(), visible_workspaces.end(),
|
||||||
|
workspace->name()) != visible_workspaces.end());
|
||||||
|
|
||||||
|
// set workspace icon
|
||||||
std::string &workspace_icon = icons_map_[""];
|
std::string &workspace_icon = icons_map_[""];
|
||||||
if (with_icon_) {
|
if (with_icon_) {
|
||||||
workspace_icon = workspace->select_icon(icons_map_);
|
workspace_icon = workspace->select_icon(icons_map_);
|
||||||
|
@ -103,9 +126,10 @@ void Workspaces::onEvent(const std::string &ev) {
|
||||||
} else if (eventName == "createworkspace") {
|
} else if (eventName == "createworkspace") {
|
||||||
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
||||||
for (Json::Value workspace_json : workspaces_json) {
|
for (Json::Value workspace_json : workspaces_json) {
|
||||||
if (workspace_json["name"].asString() == payload &&
|
std::string name = workspace_json["name"].asString();
|
||||||
|
if (name == payload &&
|
||||||
(all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
|
(all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
|
||||||
(show_special() || !workspace_json["name"].asString().starts_with("special"))) {
|
(show_special() || !name.starts_with("special"))) {
|
||||||
workspaces_to_create_.push_back(workspace_json);
|
workspaces_to_create_.push_back(workspace_json);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -120,8 +144,8 @@ void Workspaces::onEvent(const std::string &ev) {
|
||||||
if (bar_.output->name == new_output) { // TODO: implement this better
|
if (bar_.output->name == new_output) { // TODO: implement this better
|
||||||
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
||||||
for (Json::Value workspace_json : workspaces_json) {
|
for (Json::Value workspace_json : workspaces_json) {
|
||||||
if (workspace_json["name"].asString() == workspace &&
|
std::string name = workspace_json["name"].asString();
|
||||||
bar_.output->name == workspace_json["monitor"].asString()) {
|
if (name == workspace && bar_.output->name == workspace_json["monitor"].asString()) {
|
||||||
workspaces_to_create_.push_back(workspace_json);
|
workspaces_to_create_.push_back(workspace_json);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -154,15 +178,15 @@ void Workspaces::update_window_count() {
|
||||||
auto workspace_json = std::find_if(
|
auto workspace_json = std::find_if(
|
||||||
workspaces_json.begin(), workspaces_json.end(),
|
workspaces_json.begin(), workspaces_json.end(),
|
||||||
[&](Json::Value const &x) { return x["name"].asString() == workspace->name(); });
|
[&](Json::Value const &x) { return x["name"].asString() == workspace->name(); });
|
||||||
|
uint32_t count = 0;
|
||||||
if (workspace_json != workspaces_json.end()) {
|
if (workspace_json != workspaces_json.end()) {
|
||||||
try {
|
try {
|
||||||
workspace->set_windows((*workspace_json)["windows"].asUInt());
|
count = (*workspace_json)["windows"].asUInt();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
spdlog::error("Failed to update window count: {}", e.what());
|
spdlog::error("Failed to update window count: {}", e.what());
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
workspace->set_windows(0);
|
|
||||||
}
|
}
|
||||||
|
workspace->set_windows(count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +205,7 @@ void Workspaces::create_workspace(Json::Value &value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new workspace
|
// create new workspace
|
||||||
workspaces_.emplace_back(std::make_unique<Workspace>(value));
|
workspaces_.emplace_back(std::make_unique<Workspace>(value, *this));
|
||||||
Gtk::Button &new_workspace_button = workspaces_.back()->button();
|
Gtk::Button &new_workspace_button = workspaces_.back()->button();
|
||||||
box_.pack_start(new_workspace_button, false, false);
|
box_.pack_start(new_workspace_button, false, false);
|
||||||
sort_workspaces();
|
sort_workspaces();
|
||||||
|
@ -207,7 +231,7 @@ void Workspaces::remove_workspace(std::string name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::fill_persistent_workspaces() {
|
void Workspaces::fill_persistent_workspaces() {
|
||||||
if (config_["persistent_workspaces"].isObject() && !all_outputs()) {
|
if (config_["persistent_workspaces"].isObject()) {
|
||||||
const Json::Value persistent_workspaces = config_["persistent_workspaces"];
|
const Json::Value persistent_workspaces = config_["persistent_workspaces"];
|
||||||
const std::vector<std::string> keys = persistent_workspaces.getMemberNames();
|
const std::vector<std::string> keys = persistent_workspaces.getMemberNames();
|
||||||
|
|
||||||
|
@ -297,9 +321,10 @@ void Workspaces::init() {
|
||||||
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
||||||
for (Json::Value workspace_json : workspaces_json) {
|
for (Json::Value workspace_json : workspaces_json) {
|
||||||
if ((all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
|
if ((all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
|
||||||
(!workspace_json["name"].asString().starts_with("special") || show_special()))
|
(!workspace_json["name"].asString().starts_with("special") || show_special())) {
|
||||||
create_workspace(workspace_json);
|
create_workspace(workspace_json);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
update_window_count();
|
update_window_count();
|
||||||
|
|
||||||
|
@ -314,8 +339,9 @@ Workspaces::~Workspaces() {
|
||||||
std::lock_guard<std::mutex> lg(mutex_);
|
std::lock_guard<std::mutex> lg(mutex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Workspace::Workspace(const Json::Value &workspace_data)
|
Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_manager)
|
||||||
: id_(workspace_data["id"].asInt()),
|
: workspace_manager_(workspace_manager),
|
||||||
|
id_(workspace_data["id"].asInt()),
|
||||||
name_(workspace_data["name"].asString()),
|
name_(workspace_data["name"].asString()),
|
||||||
output_(workspace_data["monitor"].asString()), // TODO:allow using monitor desc
|
output_(workspace_data["monitor"].asString()), // TODO:allow using monitor desc
|
||||||
windows_(workspace_data["windows"].asInt()),
|
windows_(workspace_data["windows"].asInt()),
|
||||||
|
@ -350,12 +376,26 @@ void add_or_remove_class(const Glib::RefPtr<Gtk::StyleContext> &context, bool co
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspace::update(const std::string &format, const std::string &icon) {
|
void Workspace::update(const std::string &format, const std::string &icon) {
|
||||||
|
// clang-format off
|
||||||
|
if (this->workspace_manager_.active_only() && \
|
||||||
|
!this->active() && \
|
||||||
|
!this->is_persistent() && \
|
||||||
|
!this->is_visible() && \
|
||||||
|
!this->is_special()) {
|
||||||
|
// clang-format on
|
||||||
|
// if active_only is true, hide if not active, persistent, visible or special
|
||||||
|
button_.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button_.show();
|
||||||
|
|
||||||
auto style_context = button_.get_style_context();
|
auto style_context = button_.get_style_context();
|
||||||
add_or_remove_class(style_context, active(), "active");
|
add_or_remove_class(style_context, active(), "active");
|
||||||
add_or_remove_class(style_context, is_special(), "special");
|
add_or_remove_class(style_context, is_special(), "special");
|
||||||
add_or_remove_class(style_context, is_empty(), "empty");
|
add_or_remove_class(style_context, is_empty(), "empty");
|
||||||
add_or_remove_class(style_context, is_persistent(), "persistent");
|
add_or_remove_class(style_context, is_persistent(), "persistent");
|
||||||
add_or_remove_class(style_context, is_urgent(), "urgent");
|
add_or_remove_class(style_context, is_urgent(), "urgent");
|
||||||
|
add_or_remove_class(style_context, is_visible(), "visible");
|
||||||
|
|
||||||
label_.set_markup(fmt::format(fmt::runtime(format), fmt::arg("id", id()),
|
label_.set_markup(fmt::format(fmt::runtime(format), fmt::arg("id", id()),
|
||||||
fmt::arg("name", name()), fmt::arg("icon", icon)));
|
fmt::arg("name", name()), fmt::arg("icon", icon)));
|
||||||
|
@ -420,6 +460,13 @@ std::string &Workspace::select_icon(std::map<std::string, std::string> &icons_ma
|
||||||
return named_icon_it->second;
|
return named_icon_it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_visible()) {
|
||||||
|
auto visible_icon_it = icons_map.find("visible");
|
||||||
|
if (visible_icon_it != icons_map.end()) {
|
||||||
|
return visible_icon_it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_empty()) {
|
if (is_empty()) {
|
||||||
auto empty_icon_it = icons_map.find("empty");
|
auto empty_icon_it = icons_map.find("empty");
|
||||||
if (empty_icon_it != icons_map.end()) {
|
if (empty_icon_it != icons_map.end()) {
|
||||||
|
|
Loading…
Reference in New Issue