#include "modules/niri/window.hpp" #include #include #include #include "util/rewrite_string.hpp" #include "util/sanitize_str.hpp" namespace waybar::modules::niri { Window::Window(const std::string &id, const Bar &bar, const Json::Value &config) : AAppIconLabel(config, "window", id, "{title}", 0, true), bar_(bar) { if (!gIPC) gIPC = std::make_unique(); gIPC->registerForIPC("WindowsChanged", this); gIPC->registerForIPC("WindowOpenedOrChanged", this); gIPC->registerForIPC("WindowClosed", this); gIPC->registerForIPC("WindowFocusChanged", this); dp.emit(); } Window::~Window() { gIPC->unregisterForIPC(this); } void Window::onEvent(const Json::Value &ev) { dp.emit(); } void Window::doUpdate() { auto ipcLock = gIPC->lockData(); const auto &windows = gIPC->windows(); const auto &workspaces = gIPC->workspaces(); const auto separateOutputs = config_["separate-outputs"].asBool(); const auto ws_it = std::find_if(workspaces.cbegin(), workspaces.cend(), [&](const auto &ws) { if (separateOutputs) { return ws["is_active"].asBool() && ws["output"].asString() == bar_.output->name; } return ws["is_focused"].asBool(); }); std::vector::const_iterator it; if (ws_it == workspaces.cend() || (*ws_it)["active_window_id"].isNull()) { it = windows.cend(); } else { const auto id = (*ws_it)["active_window_id"].asUInt64(); it = std::find_if(windows.cbegin(), windows.cend(), [id](const auto &win) { return win["id"].asUInt64() == id; }); } setClass("empty", ws_it == workspaces.cend() || (*ws_it)["active_window_id"].isNull()); if (it != windows.cend()) { const auto &window = *it; const auto title = window["title"].asString(); const auto appId = window["app_id"].asString(); const auto sanitizedTitle = waybar::util::sanitize_string(title); const auto sanitizedAppId = waybar::util::sanitize_string(appId); label_.show(); label_.set_markup(waybar::util::rewriteString( fmt::format(fmt::runtime(format_), fmt::arg("title", sanitizedTitle), fmt::arg("app_id", sanitizedAppId)), config_["rewrite"])); updateAppIconName(appId, ""); if (tooltipEnabled()) label_.set_tooltip_text(title); const auto id = window["id"].asUInt64(); const auto workspaceId = window["workspace_id"].asUInt64(); const auto isSolo = std::none_of(windows.cbegin(), windows.cend(), [&](const auto &win) { return win["id"].asUInt64() != id && win["workspace_id"].asUInt64() == workspaceId; }); setClass("solo", isSolo); if (!appId.empty()) setClass(appId, isSolo); if (oldAppId_ != appId) { if (!oldAppId_.empty()) setClass(oldAppId_, false); oldAppId_ = appId; } } else { label_.hide(); updateAppIconName("", ""); setClass("solo", false); if (!oldAppId_.empty()) setClass(oldAppId_, false); oldAppId_.clear(); } } void Window::update() { doUpdate(); AAppIconLabel::update(); } void Window::setClass(const std::string &className, bool enable) { auto styleContext = bar_.window.get_style_context(); if (enable) { if (!styleContext->has_class(className)) { styleContext->add_class(className); } } else { styleContext->remove_class(className); } } } // namespace waybar::modules::niri