Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved hyprland/window by fixing icon search and implementing configurable spacing #2973

Merged
1 change: 1 addition & 0 deletions include/modules/hyprland/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
bool allFloating_;
bool swallowing_;
bool fullscreen_;
bool focused_;
};

} // namespace waybar::modules::hyprland
64 changes: 50 additions & 14 deletions src/AAppIconLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,61 @@ AAppIconLabel::AAppIconLabel(const Json::Value& config, const std::string& name,
image_.set_pixel_size(app_icon_size_);
}

std::string toLowerCase(const std::string& input) {
std::string result = input;
std::transform(result.begin(), result.end(), result.begin(),
[](unsigned char c) { return std::tolower(c); });
return result;
}

std::optional<std::string> getFileBySuffix(const std::string& dir, const std::string& suffix,
bool check_lower_case) {
if (!std::filesystem::exists(dir)) {
return {};
}
for (const auto& entry : std::filesystem::recursive_directory_iterator(dir)) {
if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string();
if (filename.size() < suffix.size()) {
continue;
}
if ((filename.compare(filename.size() - suffix.size(), suffix.size(), suffix) == 0) ||
(check_lower_case && filename.compare(filename.size() - suffix.size(), suffix.size(),
toLowerCase(suffix)) == 0)) {
return entry.path().string();
}
}
}

return {};
}

std::optional<std::string> getFileBySuffix(const std::string& dir, const std::string& suffix) {
return getFileBySuffix(dir, suffix, false);
}

std::optional<std::string> getDesktopFilePath(const std::string& app_identifier,
const std::string& alternative_app_identifier) {
if (app_identifier.empty()) {
return {};
}

const auto data_dirs = Glib::get_system_data_dirs();
for (const auto& data_dir : data_dirs) {
const auto data_app_dir = data_dir + "applications/";
auto desktop_file_path = data_app_dir + app_identifier + ".desktop";
if (std::filesystem::exists(desktop_file_path)) {
const auto data_app_dir = data_dir + "/applications/";
auto desktop_file_suffix = app_identifier + ".desktop";
// searching for file by suffix catches cases like terminal emulator "foot" where class is
// "footclient" and desktop file is named "org.codeberg.dnkl.footclient.desktop"
auto desktop_file_path = getFileBySuffix(data_app_dir, desktop_file_suffix, true);
// "true" argument allows checking for lowercase - this catches cases where class name is
// "LibreWolf" and desktop file is named "librewolf.desktop"
if (desktop_file_path.has_value()) {
return desktop_file_path;
}
if (!alternative_app_identifier.empty()) {
desktop_file_path = data_app_dir + alternative_app_identifier + ".desktop";
if (std::filesystem::exists(desktop_file_path)) {
desktop_file_suffix = alternative_app_identifier + ".desktop";
desktop_file_path = getFileBySuffix(data_app_dir, desktop_file_suffix, true);
if (desktop_file_path.has_value()) {
return desktop_file_path;
}
}
Expand All @@ -58,24 +101,17 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
return app_identifier_desktop;
}

const auto to_lower = [](const std::string& str) {
auto str_cpy = str;
std::transform(str_cpy.begin(), str_cpy.end(), str_cpy.begin(),
[](unsigned char c) { return std::tolower(c); });
return str;
};

const auto first_space = app_identifier.find_first_of(' ');
if (first_space != std::string::npos) {
const auto first_word = to_lower(app_identifier.substr(0, first_space));
const auto first_word = toLowerCase(app_identifier.substr(0, first_space));
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
return first_word;
}
}

const auto first_dash = app_identifier.find_first_of('-');
if (first_dash != std::string::npos) {
const auto first_word = to_lower(app_identifier.substr(0, first_dash));
const auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
return first_word;
}
Expand Down
15 changes: 14 additions & 1 deletion src/AIconLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ AIconLabel::AIconLabel(const Json::Value &config, const std::string &name, const
bool enable_click, bool enable_scroll)
: ALabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) {
event_box_.remove();
label_.unset_name();
label_.get_style_context()->remove_class(MODULE_CLASS);
box_.get_style_context()->add_class(MODULE_CLASS);
if (!id.empty()) {
label_.get_style_context()->remove_class(id);
box_.get_style_context()->add_class(id);
}

box_.set_orientation(Gtk::Orientation::ORIENTATION_HORIZONTAL);
box_.set_spacing(8);
box_.set_name(name);

int spacing = config_["icon-spacing"].isInt() ? config_["icon-spacing"].asInt() : 8;
box_.set_spacing(spacing);

box_.add(image_);
box_.add(label_);

event_box_.add(box_);
}

Expand Down
10 changes: 10 additions & 0 deletions src/modules/hyprland/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ auto Window::update() -> void {
label_.hide();
}

if (focused_) {
image_.show();
} else {
image_.hide();
}

setClass("empty", workspace_.windows == 0);
setClass("solo", solo_);
setClass("floating", allFloating_);
Expand Down Expand Up @@ -137,13 +143,16 @@ void Window::queryActiveWorkspace() {
workspace_ = getActiveWorkspace();
}

focused_ = true;
if (workspace_.windows > 0) {
const auto clients = gIPC->getSocket1JsonReply("clients");
assert(clients.isArray());
auto activeWindow = std::find_if(clients.begin(), clients.end(), [&](Json::Value window) {
return window["address"] == workspace_.last_window;
});

if (activeWindow == std::end(clients)) {
focused_ = false;
return;
}

Expand Down Expand Up @@ -185,6 +194,7 @@ void Window::queryActiveWorkspace() {
soloClass_ = "";
}
} else {
focused_ = false;
windowData_ = WindowData{};
allFloating_ = false;
swallowing_ = false;
Expand Down